LDAP over SSL(LDAPS)での接続方法


LDAPSでの通信にははまりましたが、20時間の闘いにて、通信の確立に成功しましたので、手順を書いておきます。

CA証明局の構築とCA証明書の作成

LDAPS通信ごときに、公的機関の証明は不要だと思います。
暗号化さえされればいいですからね。
と言う訳で、まずはCentOS6でのCA構築手順です。
言うまでもなく、OpenSSLが事前にインストールされている必要があります。
また、CA局は、LDAPサーバでなくても構いません。
後で説明するLDAPサーバ側で作成したサーバ証明書に対して署名(CA局が認めた証明書だよってサインする事)を行う為に必要なサーバとなります。

/etc/pki/tls/mics/CA -newca
Generating a 2048 bit RSA private key
........+++
......................................................+++
writing new private key to 'private/cakey.pem'
Enter PEM pass phrase:<任意のパスワードを設定>
Verifying - Enter PEM pass phrase:<パスワードをもう一回入力>
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:<JPとかを入力>
State or Province Name (full name) [Berkshire]:<都道府県名を入力>
Locality Name (eg, city) [Newbury]:<市町村名を入力>
Organization Name (eg, company) [My Company Ltd]:<組織名を入力>
Organizational Unit Name (eg, section) []:<部署名を入力>
Common Name (eg, your name or your server's hostname) []:<重要!!サーバのFQDN>
Email Address []:<管理者のメールアドレス>
この後はEnterとパスワード入力を求められます。

これで、”/etc/pki/CA”以下に、証明局の各ファイルやディレクトリが作成されたと思います。
CAディレクトリ直下にある、”cacert.pem”が、CA証明書となりますので、これを後でLDAPサーバにコピーします。
再度やり直したい場合は、CAディレクトリ以下を丸ごと削除すればOKです。

念のため、パーミッションを変更しておきます。

chmod 600 /etc/pki/CA/private/cacert.key
chmod 700 

これでCA局とCA証明書の準備が整いました。

LDAPサーバ用のサーバ証明書と鍵の作成

次にLDAPサーバ上で、サーバ証明書と鍵を作成します。

openssl req -new -keyout server.key -out server.csr

次はOpenLDAPの起動時にパスワードを聞かれなくてもいい様に、鍵にかけられたパスワードの解除を行います。

mv server.key server.key.org
openssl rsa -in server.key.org -out server.key

これでサーバ証明書と鍵が作成できたので、CA局のサーバに、サーバ証明書をコピーします。

scp server.csr <CA局サーバのユーザ名>@<CA局サーバのアドレス>:<宛先のディレクトリ>

鍵のサイン(サーバ証明書の作成)

CA局のサーバで、LDAPサーバからコピーした鍵から、CA局がサインした証明書を作成します。

openssl ca -out server.crt -infiles server.csr

作成された証明書(サーバー証明書)とCA局の証明書を、LDAPサーバにコピーします。
以下の例では、OpenLDAPでデフォルトで用意されている証明書設置用のディレクトリを宛先としています。

scp server.crt <LDAPサーバのユーザ名>@<LDAPサーバのアドレス>:/etc/openldap/cacerts/
scp cacert.pem <LDAPサーバのユーザ名>@<LDAPサーバのアドレス>:/etc/openldap/cacerts/

LDAPサーバの設定

まず、先程作成したサーバの鍵を、鍵設置用のディレクトリにコピーします。
CA局の証明書と、サーバ証明書は先の手順ですでに設置されていると思いますので手順は割愛します。

cp server.key /etc/openldap/cacerts/

次にOpenLDAPの設定です。
OpenLDAP2.4では動的データベースによる設定手順が標準となっていますので、これを前提にした手順を示します。
まず、slapd.confに、証明書を指定する箇所がコメントアウトされていますので、以下の様に書き換えます。

vi /etc/openldap/slapd.conf
#TLSCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
#TLSCertificateFile /etc/pki/tls/certs/slapd.pem
#TLSCertificateKeyFile /etc/pki/tls/certs/slapd.pem
TLSCACertificateFile    /etc/openldap/cacerts/cacert.pem
TLSCertificateFile      /etc/openldap/cacerts/server.crt
TLSCertificateKeyFile   /etc/openldap/cacerts/server.key

すでにOpenLDAPを起動してしまっている場合、slapd.confの設定だけでは反映されませんので、以下の手順を実行してOpenLDAPで読み込めるようにします。
(ldapmodifyでの操作に慣れている方は、もちろんldapmodifyによる変更でも構いません)

rm -rf etc/openldap/slapd.d/*
slapd -f etc/openldap/slapd.conf -F etc/openldap/slapd.d/
chown -R ldap:ldap etc/openldap/slapd.d/*

これで証明書を読み込ませる事が出来ました。
しかし、OpenLDAP2.4では、この手順だけではLDAPSのポート636での待ち受けは出来ない様です。多分バグです。2.4はバグだらけですが、うまくつきあえばちゃんと動きます。

vim /etc/sysconfig/ldap
#SLAPD_LDAPS=no
SLAPD_LDAPS=yes

これでLDAPサーバ側の設定完了です。
なお、CA局とサーバ証明書の作成時にホスト名をFQDNで指定するのですが、ここを適当な値にしてしまうと通信が出来ないので要注意です。
LDAPに問い合わせを行うサーバからFQDNで問い合わせをする必要があり、LDAPのサーバ証明書の作成の際に入力したFQDNと一致しなければ、エラーで跳ねられてしまいます。

LDAP Clientの設定

LDAP Clientでコマンドラインで接続する場合は、LDAPのクライアントのサーバにある、ldap.confを設定します。
(open-ldapclientsも必要になりますので事前にインストールしておいて下さい。)

vim /etc/openldap/ldap.conf
TLS_CACERTDIR /etc/openldap/cacerts
TLS_REQCERT     never

この2行を書き加えて下さい。
それから、CA証明書を、ldap.confに指定したパスに、CA局からコピーして設置しておく事も忘れないで下さい。

接続テスト

LDAPクライアントのサーバから、ldapsearchを叩いてテストします。

ldapsearch -x -H "ldaps://<LDAPサーバのFQDN>" -D "<バインドユーザ>" -b "<検索対象>" -w

LDAPサーバの接続先は、サーバ証明書の作成時に入力したFQDNを使う必要があります。

OpenLDAP2.4の”bdb_db_open: db_open(/var/db/openldap-data/id2entry.bdb) failed: No such file or directory (2)”と言うエラーについて


CentOS6.2に対してyumでopneldapをインストールすると2.4がインストールされます。
これがなかなかの曲者で、動的データベースと呼ばれるbdbに対して設定ファイルを書き込む仕様が標準となりました。
なお、動的データベースは、2.3から搭載されている機能で、設定を変更した場合に即座に反映されるものですが、取り扱いが非常に厄介な物でもあります。

OpenLDAP2.4の初期構築時に、slapd.confに設定した内容を動的データベースに書き込むには、以下のコマンドを実行します。

slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
chomd -R ldap:ldap /etc/openldap/slapd.d/*

しかしここで起動をしようとしても、失敗する事が有ります。
そこでslpatestコマンドで設定ファイルを確認すると、

bdb_db_open: db_open(/var/db/openldap-data/id2entry.bdb) failed: No such file or directory (2)

というエラーが出ていませんか?
実際に/var/db/openldap-data/の中を見ても、id2entry.dbと言うファイルが存在しない事に気づきます。
しかしどうやっても出来ず色々調べていたところ、適当に*.ldifをslapaddで追加すると、このファイルが出来上がる事がわかりました。
こんな感じです。

slapadd -l /etc/openldap/schema/core.ldif
chown -R ldap:ldap /var/lib/ldap/*

これで起動できるようになりました。
バグなんでしょうかね。でも少なくとも4年前からこの仕様が続いている様です。

OpenLDAP2.4の設定変更について


OpenLDAP2.4で、slapd.conf内の設定、特にドメインやManagerのパスワードを変更した場合は、以下の作業が必要になります。

アカウントのデータが削除されるので注意!!

1. /etc/openldap/slapd.d/と、/var/lib/ldap/以下を削除

rm -rf /etc/openldap/slapd.d/*
rm -rf /var/lib/ldap/*

2. DB_CONFIGをコピーしてパーミッションを変更

cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
chown -R ldap:ldap /var/lib/ldap/DB_CONFIG 

3. slapd.d以下のファイルを作成し、パーミッションを変更

slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d/
chown -R ldap:ldap /etc/openldap/slapd.d

4. slapd.confを編集し、OpenLDAPを再起動

以上で設定変更が反映されます。
間違っていたらご指摘下さい。

OpenLDAP2.4の Invalid credentials (49)について

OpenLDAP2.4以降に採用された、設定関係も丸ごとDBに突っ込む仕様ですが、全く以て使い辛く情報も少ないですよね。
期待のマルチマスター構成も、こんなんじゃ使い物になる以前の問題です。

このDBに構成情報を持たせる事が元で、 Invalid credentials (49)のエラーにはまっている方多いんじゃないでしょうか。
パスワードも絶対間違ってないのに的な。。。
そうゆう時は以下の様にして、ディレクトリを丸ごと吹き飛ばしてサービス再起動したりするといきなり直ったりするかもしれません。

rm -rf /etc/openldap/slap.d

そもそも、今まで通りにslap.confで運用したい場合は、slapd.confの中で、以下の部分をコメントアウトすると、今までの様に使いやすいOpenLDAPを使用できます。

# enable on-the-fly configuration (cn=config)
#database config
#access to *
#       by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
#       by * none

# enable server status monitoring (cn=monitor)
#database monitor
#access to *
#       by dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
#       by dn.exact="cn=Manager,dc=my-domain,dc=com" read
#       by * none

CentOS6.xになってから、OpenLDAP2.4が標準になり、FreeRadiusも2系になり、色々と変わっていますね。
しかもいい方向にはあまり変わっていないようで、どうしちゃったんだろって感じですね。