michihide's blog

技術メモおよび雑感

TLS Support for openldap-2.4.x / php on CentOS7

やっと動いたので簡単にメモしておく。

前提

  • LDAP Consumer として動作中のホストに対して TLS Support を追加する。
  • 証明書は例によってオレオレ。
    • Webサーバ用のワイルドカード証明書も取得済みだが、通信路の暗号化だけなら証明書の有効期限到達時の切り替えなどを考慮しなくていいのでオレオレが楽。

オレオレ証明書の作成

  • openssl パッケージに含まれる make-dummy-cert コマンドを使うのが簡単
/etc/pki/tls/certs/make-dummy-cert /tmp/self-cert
sed -n '/BEGIN PRIVATE KEY/,/END PRIVATE KEY/'p /tmp/self-cert > /etc/openldap/certs/localhost.key
sed -n '/BEGIN CERTIFICATE/,/END ERTIFICATE/'p /tmp/self-cert  > /etc/openldap/certs/localhost.crt

LDAP サーバへの設定追加

$ cat tls.ldif
dn: cn=config
changetype: modify
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/openldap/certs/localhost.crt
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/openldap/certs/localhost.key
$ /usr/bin/ldapmodify -x -D cn=config -w (内緒) -H ldap://localhost:389 -f tls.ldif

動作確認(別ホストからでも可)

$ cat /etc/openldap/ldap.conf
....
TLS_REQCERT never ←この行がなければ追加
  • 従来の非暗号化でアクセスできることを確認
$ ldapsearch -x -LLL -h example.com -b ou=Users,dc=example,dc=com '(uid=test1)' dn
dn: uid=test1,ou=Users,dc=example,dc=com
  • TLS 接続 ( -Z オプション)でアクセスできることを確認
$ ldapsearch -Z -x -LLL -h example.com -b ou=Users,dc=example.com '(uid=test1)' dn
dn: uid=test1,ou=Users,dc=example,dc=com
  • 出力は全く同じだが、これで TLS 通信できている。
  • 利用する通信ポートは、デフォルトでは平文の場合と同じ(389)。
    • なので、ファイアーウォールの設定等はそのままでよい。
  • -d 1 (デバッグオプション)を付けると、TLS で通信できていることが確認できる。
  • パケットを拾ってみると、クエリー自体が暗号化されていることが確認できる。

20150615171852

PHPからの認証動作確認

  • 実際にはPHPで書かれたアプリからの認証で使いたいので、以下のようなサンプルプログラムを書いて検証
$ cat ldap_tls.php
#!/usr/bin/php
<?php
define('LDAP_SERVER', 'ldap://example.com:389');
define('ACCOUNT', 'test1');
define('PASSWD', 'ok-pass');
$ds = ldap_connect(LDAP_SERVER)                    or die("ldap_connect()\n");
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3) or die("LDAP_OPT_PROTOCOL_VERSION\n");
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0)        or die("LDAP_OPT_REFERRALS\n");
ldap_start_tls($ds)                                or die("ldap_start_tls()\n");
$dn = sprintf("uid=%s,ou=Users,dc=example.com", ACCOUNT);
if (ldap_bind($ds, $dn, PASSWD))    {
    echo "Authentication succeeded.\n";
} else  {
    echo "Authentication failure.\n";
}
  • パスワードが正しければ Authentication succeeded が表示され、
  • わざと間違えたら Authentication failure が表示されることを確認。

ということで、めでたしめでたし。