そろそろLDAPにしてみないか?

第11回 OpenLDAPとSSL

この記事を読むのに必要な時間:およそ 7.5 分

slapd.confの設定

slapd.confの設定は非常にシンプルで,Apacheやその他サーバソフトウェアを設定するときと同じ概念となります。もちろんこれ以外に細かいパラメータは存在するのですが,SSL対応サーバを構築する場合,⁠サーバ鍵」⁠証明書」の2つを設定することで暗号化を実現することができます。

リスト3 slapd.confの一部

# CAバンドルが必要な場合には指定
#TLSCACertificateFile /etc/openldap/ca-bundle.crt 
TLSCertificateFile /etc/openldap/server.crt 
TLSCertificateKeyFile /etc/openldap/server.key 

最後にslapdプロセスを再起動して準備は完了です。このように証明書情報を適切にセットしておくと,通常の389/tcpだけではなくSSL専用の636/tcpが使用されるようになります。

クライアントからの接続確認

接続確認をするために,接続がldaps(LDAP+SSL)であることを-Hオプションを使用して明示します。

図4 クライアントからの接続

ldapsearch -x -H "ldaps://10.0.100.10/" -b "dc=example,dc=com" 
ldap_bind: Can't contact LDAP server (-1) 
	additional info: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed 

あれれ,エラーが表示されてしまいました。

冒頭で軽く触れたように,SSLの本来の目的とは暗号化だけではありません。たとえ通信が暗号化されていたとしても,フィッシングサイトと暗号化通信してしまってはセキュリティの意味も無いためです。自己証明書を使用した場合,暗号化を実現することができますが,クライアントは接続先を正当なサイトと判断することができないためこのエラーが表示されているわけです(いわゆるオレオレ証明書と呼ばれているものです⁠⁠。

そこで,ldapsearchコマンドが参照する設定ファイルを編集し,接続先の妥当性を確認しないようにしておきます。

リスト4 /etc/openldap/ldap.confの追加

TLS_REQCERT     never

もしOpenLDAPをソースからコンパイルした場合には,/usr/local/etc/openldap/ldap.confとなっている場合が多いでしょう。同ファイル名の/etc/ldap.confとは用途が異なるため注意してください。

正しく設定した場合は,エントリを検索できるようになっているはずです。

図5

% ldapsearch -x -H "ldaps://10.0.100.10/" -b "dc=example,dc=com" 
-- 省略 --
# hogeuser, People, example.com 
dn: uid=hogeuser,ou=People,dc=example,dc=com 
objectClass: account 
objectClass: posixAccount 
objectClass: ldapPublicKey 
uid: hogeuser 
cn: hogeuser 
loginShell: /bin/bash 
uidNumber: 2000 
gidNumber: 2000 
homeDirectory: /home/hogeuser 
sshPublicKey: ssh-dss AAAAB3NzaC1kc3MAAACBAJ5sBOzM/PCkETefX7yzrs+oEVOp3hwuBSpL 
 96pbkfoyQ5jvMABT6aGzXqQUTZu00Gke+G+CJeOg3rw9K7+ghrNuB4Rv33l1LdILjTTMFqDsvMo02 
 Un6DKv/EvAW++rarKDDU5DMJOEPqkOWTsPb683WP77fHcBxKsALVtVAFTMzAAAAFQDVPmzJd39IYv 
 KMWQsJQvzPefUX8wAAAIEAliBMDP2SFtPoAZMAbCtAwWtQmXh7C/+CJwrQEJMDYb1Pp+7jaOk+7Ag 
 sGMTA2abtSsPDvvhlrNXOyqx+EMYxibwnX4dnGS7NQAsQhqUmvqzzKfySD/UvJ6GQYtB9FMpju0L/ 
 qH5B5jtdfwggXTaGRXuadnzAZ7rrOOMvosqyhc8AAACBAInNQo10pbrnkp9grL+Db2/Rp1JXVajN0 
 2isPzfpS7uX9rohAlyTVLAjlwLwTGrp6CFwG4/t9e7jxlIo4Wm2r7LXgLr9u7+dg+oMENJpYkt/0N 
 tLBq40dICE8yhha58cQau5z98Ajc6dO9yvB2Bp6C3oDIiumPq/e2IMGjYYrtcP nomo@rx8 

実際にtcpdumpなどで636/tcpに流れるデータを確認してみてください。

StartTLS

こちらもOpenLDAPに限った話ではなく,SMTPやPOP3などでは比較的多く使われている技術ですが,OpenLDAPはStartTLSをサポートしています。StartTLSとは,接続の確立時には平文によるデータ通信を行い,STARTTLSコマンドをクライアントが発行することにより,以降の通信を全て暗号化してしまう技術です。

この接続はldapsearchコマンド-Zオプションを渡すだけで実現できます。それぞれのコマンドを実行中に389/tcpをtsharkコマンドでキャプチャしてみました。

リスト5 通常のldapsearch(389/tcpを使用)

496.959580   10.0.100.1 -> 10.0.100.10  TCP 51450 > ldap [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=63349770 TSER=0 WS=7 
496.960331  10.0.100.10 -> 10.0.100.1   TCP ldap > 51450 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=424013 TSER=63349770 WS=2 
496.960368   10.0.100.1 -> 10.0.100.10  TCP 51450 > ldap [ACK] Seq=1 Ack=1 Win=5888 Len=0 TSV=63349771 TSER=424013 
496.966756   10.0.100.1 -> 10.0.100.10  LDAP bindRequest(1) "" simple 
496.966934  10.0.100.10 -> 10.0.100.1   TCP ldap > 51450 [ACK] Seq=1 Ack=15 Win=5792 Len=0 TSV=424019 TSER=63349772 
496.967765  10.0.100.10 -> 10.0.100.1   LDAP bindResponse(1) success 
496.967786   10.0.100.1 -> 10.0.100.10  TCP 51450 > ldap [ACK] Seq=15 Ack=15 Win=5888 Len=0 TSV=63349772 TSER=424021 
496.968298   10.0.100.1 -> 10.0.100.10  LDAP searchRequest(2) "dc=example,dc=com" wholeSubtree 
496.971835  10.0.100.10 -> 10.0.100.1   LDAP searchResEntry(2) "dc=example,dc=com" 
496.973767  10.0.100.10 -> 10.0.100.1   LDAP searchResEntry(2) "ou=People,dc=example,dc=com" 
496.973854   10.0.100.1 -> 10.0.100.10  TCP 51450 > ldap [ACK] Seq=71 Ack=208 Win=5888 Len=0 TSV=63349774 TSER=424022 
496.974530  10.0.100.10 -> 10.0.100.1   LDAP searchResEntry(2) "ou=Group,dc=example,dc=com" 
496.975029  10.0.100.10 -> 10.0.100.1   LDAP searchResEntry(2) "cn=sshuser,ou=Group,dc=example,dc=com" 
496.975088   10.0.100.1 -> 10.0.100.10  TCP 51450 > ldap [ACK] Seq=71 Ack=417 Win=5888 Len=0 TSV=63349774 TSER=424025 
496.975724  10.0.100.10 -> 10.0.100.1   LDAP searchResEntry(2) "cn=hogeuser,ou=Group,dc=example,dc=com" 
496.976129  10.0.100.10 -> 10.0.100.1   LDAP searchResEntry(2) "uid=sshuser,ou=People,dc=example,dc=com" 
496.976146   10.0.100.1 -> 10.0.100.10  TCP 51450 > ldap [ACK] Seq=71 Ack=1411 Win=7680 Len=0 TSV=63349775 TSER=424027 
496.977116  10.0.100.10 -> 10.0.100.1   LDAP searchResEntry(2) "uid=hogeuser,ou=People,dc=example,dc=com" 
496.977590  10.0.100.10 -> 10.0.100.1   LDAP searchResDone(2) success 
496.977607   10.0.100.1 -> 10.0.100.10  TCP 51450 > ldap [ACK] Seq=71 Ack=2301 Win=9344 Len=0 TSV=63349775 TSER=424028 
496.977764   10.0.100.1 -> 10.0.100.10  LDAP unbindRequest(3) 
496.977975   10.0.100.1 -> 10.0.100.10  TCP 51450 > ldap [FIN, ACK] Seq=78 Ack=2301 Win=9344 Len=0 TSV=63349775 TSER=424028 
496.979528  10.0.100.10 -> 10.0.100.1   TCP ldap > 51450 [FIN, ACK] Seq=2301 Ack=79 Win=5792 Len=0 TSV=424031 TSER=63349775 
496.979562   10.0.100.1 -> 10.0.100.10  TCP 51450 > ldap [ACK] Seq=79 Ack=2302 Win=9344 Len=0 TSV=63349775 TSER=424031 

リスト6 StartTLS時のldapsearch(389/tcpを使用)

513.712634   10.0.100.1 -> 10.0.100.10  TCP 51451 > ldap [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=63353959 TSER=0 WS=7 
513.712858  10.0.100.10 -> 10.0.100.1   TCP ldap > 51451 [SYN, ACK] Seq=0 Ack=1 Win=5792 Len=0 MSS=1460 TSV=426214 TSER=63353959 WS=2 
513.712890   10.0.100.1 -> 10.0.100.10  TCP 51451 > ldap [ACK] Seq=1 Ack=1 Win=5888 Len=0 TSV=63353959 TSER=426214 
513.713697   10.0.100.1 -> 10.0.100.10  LDAP extendedReq(1) LDAP_START_TLS_OID 
513.713825  10.0.100.10 -> 10.0.100.1   TCP ldap > 51451 [ACK] Seq=1 Ack=32 Win=5792 Len=0 TSV=426216 TSER=63353959 
513.714085  10.0.100.10 -> 10.0.100.1   LDAP extendedResp(1) [LDAP_START_TLS_OID responseName missing] 
513.714101   10.0.100.1 -> 10.0.100.10  TCP 51451 > ldap [ACK] Seq=32 Ack=15 Win=5888 Len=0 TSV=63353959 TSER=426217 
513.717707   10.0.100.1 -> 10.0.100.10  SSLv2 Client Hello 
513.721392  10.0.100.10 -> 10.0.100.1   TLSv1 Server Hello, Certificate, Server Hello Done 
513.722359   10.0.100.1 -> 10.0.100.10  TLSv1 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message 
513.726489  10.0.100.10 -> 10.0.100.1   TLSv1 Change Cipher Spec, Encrypted Handshake Message 
513.727464   10.0.100.1 -> 10.0.100.10  TLSv1 Application Data, Application Data 
513.727822  10.0.100.10 -> 10.0.100.1   TLSv1 Application Data, Application Data 
513.728385   10.0.100.1 -> 10.0.100.10  TLSv1 Application Data, Application Data 
513.728864  10.0.100.10 -> 10.0.100.1   TLSv1 Application Data, Application Data 
513.729058  10.0.100.10 -> 10.0.100.1   TLSv1 Application Data, Application Data 
513.729175  10.0.100.10 -> 10.0.100.1   TLSv1 Application Data, Application Data 
513.729871   10.0.100.1 -> 10.0.100.10  TCP 51451 > ldap [ACK] Seq=584 Ack=1533 Win=13056 Len=0 TSV=63353963 TSER=426228 
513.730069  10.0.100.10 -> 10.0.100.1   TLSv1 Application Data, Application Data, Application Data, Application Data, Application Data, Application Data, Application Data, 
513.730250  10.0.100.10 -> 10.0.100.1   TLSv1 Application Data 
513.730266   10.0.100.1 -> 10.0.100.10  TCP 51451 > ldap [ACK] Seq=584 Ack=3887 Win=18816 Len=0 TSV=63353963 TSER=426231 
513.731168   10.0.100.1 -> 10.0.100.10  TLSv1 Application Data, Application Data 
513.731567  10.0.100.10 -> 10.0.100.1   TLSv1 Encrypted Alert 
513.731691  10.0.100.10 -> 10.0.100.1   TCP ldap > 51451 [FIN, ACK] Seq=3924 Ack=658 Win=6864 Len=0 TSV=426233 TSER=63353963 
513.731914   10.0.100.1 -> 10.0.100.10  TLSv1 Encrypted Alert 
513.748263  10.0.100.10 -> 10.0.100.1   TCP ldap > 51451 [RST] Seq=3925 Win=0 Len=0 
513.748373   10.0.100.1 -> 10.0.100.10  TCP 51451 > ldap [RST, ACK] Seq=695 Ack=3925 Win=18816 Len=0 TSV=63353968 TSER=426232 

このように,同じ389/tcpを使用しているにもかかわらず,StartTLSを使用した場合には通信内容が暗号化されています。

最後に

今回はSSL/TLSによる通信経路の暗号化についてお話ししてきました。

暗号化は効果的なセキュリティ対策ですが,複雑な暗号化,復号化はCPU負荷を生み出すことを考慮しておかなければなりません。たとえば,メールサーバのルックアップデータベース用にLDAPを使用していた場合,メールの流量によってはLDAP検索速度にボトルネックが発生し,メール配送のスループットが落ちてしまうことがあります。⁠セキュリティ上必要だから」という漠然とした理由でメールサーバ,LDAPサーバ間の接続をSSLにしていては,さらにボトルネックが大きくなってしまう可能性もあります。

本当にそのネットワーク上にSSLが必要なのか検討した上で,さらに可能であれば事前にパフォーマンステストを行ってからSSLを導入するようにしてください。

著者プロフィール

中満英生(なかみつひでお)

大学時代に出会ったSolarisがきっかけでUNIXの世界へ。その後ホスティングプロバイダ,データセンターで実務経験を積む傍ら,雑誌記事の執筆や技術セミナーの講師を務める。サーバ設定の他,セキュリティに関する著作や技術者エッセイも執筆経験あり。