今回のテーマは暗号化です。SMTPやPOP3プロトコルでは平文パスワードがネットワーク上を流れることが知られていますが、LDAPでも同じことが言え、tcpdumpなどでキャプチャしてみると、パスワード文字列を簡単に取得することができてしまいます。
たとえば、UNIXアカウントをOpenLDAPで管理する場合、実際のパスワード情報はLDAPサーバ上のuserPassword属性中に暗号化された状態で格納されていますが、ネットワーク上のトラフィックをキャプチャしてみると、平文のパスワードを取得することができてしまいます。
信頼されたネットワーク内のみで運用するのであれば話は別ですが、盗聴の危険性を考慮した場合、ネットワーク経路の暗号化を是非検討してみてください。
暗号化の種類
データを暗号化させるためには、いくつかの方法が考えられますが、これはSMTP/POP3/IMAPなどの基本的なプロトコルにおける考え方と同様です。
ひとつ目の方法はSSL/TLSにより、トラフィック全体を暗号化させることです。この場合SSLを使用しますので、LDAPサーバ上にサーバ鍵、証明書、CA情報などを設置しておく必要があります。トラフィックをSSLでカプセリングすることで、パスワード情報だけではなく接続の最初から最後までの全情報を暗号化させることができることが最大のメリットです。また、暗号化だけではなく信頼された接続先に安全に接続できる、という意味も持ちます。
もうひとつの方法は、LDAPバインド時の認証情報のみを暗号化させることです。この場合、バインド時の情報だけが暗号化されていますので、エントリを取得する際の情報は平文の状態となります。SMTP Authの設定を経験されたことのある読者はご存じかと思いますが、CRAM-MD5方式などの暗号化メソッドがそれに該当します。データの一部しか暗号化されないのであれば、「最初からSSL/TLSにしていたほうが良いのでは?」と考える読者の方もいらっしゃるかもしれませんが、全てを暗号化するわけではないため、SSLよりもパフォーマンス的に優れる、というのがメリットです。
今回は前者のSSLによる設定を紹介します。
OpenLDAPとSSL/TLS設定
SSL設定を行うためにはサーバ鍵、証明書などの情報が必須です。通常であればVeriSignのような認証局にCSRを提出し、証明書を取得する手順となりますが、今回は皆さん予想されているとおり、自己証明書を使った構築方法を説明します。
ちなみに、証明書を作成するためのOpenSSLには証明書を手軽に作成するための、CA.shやCA.plというスクリプトが含まれていることが多いのですが、お使いのディストリビューションによっては、opensslコマンドは存在するが、CA.shが存在しない、という場合もありますので、今回はCA.shを使わない方法を説明します。
サーバ鍵の作成
opensslコマンドを使ってサーバ鍵を作成しますが、例のごとく鍵にパスフレーズが含まれていると、安全ではあるのですが運用上不便なところも多いため、パスフレーズ無しの鍵を作成しておきます。
次に自分自身でサインする証明書を作成します。今回の目的は先に述べたよう、暗号化のみであるため、公の認証局は使用しません。また、後々の運用を楽にするため、有効期限をかなり長めに設定します。
整理しておきますと、サーバ鍵と証明書の内容は次のようなフォーマットになります。
では、これらのファイルを便宜上/etc/openldapディレクトリ中にコピーしてください。安全のためサーバ鍵のパーミッションは管理者のみが参照できるように設定しておきます。
また、公の認証局を使用する場合には、必要に応じてその認証局のCA情報を同ディレクトリに保存しておいてください。
slapd.confの設定
slapd.confの設定は非常にシンプルで、Apacheやその他サーバソフトウェアを設定するときと同じ概念となります。もちろんこれ以外に細かいパラメータは存在するのですが、SSL対応サーバを構築する場合、「サーバ鍵」「証明書」の2つを設定することで暗号化を実現することができます。
最後にslapdプロセスを再起動して準備は完了です。このように証明書情報を適切にセットしておくと、通常の389/tcpだけではなくSSL専用の636/tcpが使用されるようになります。
クライアントからの接続確認
接続確認をするために、接続がldaps(LDAP+SSL)であることを-Hオプションを使用して明示します。
あれれ、エラーが表示されてしまいました。
冒頭で軽く触れたように、SSLの本来の目的とは暗号化だけではありません。たとえ通信が暗号化されていたとしても、フィッシングサイトと暗号化通信してしまってはセキュリティの意味も無いためです。自己証明書を使用した場合、暗号化を実現することができますが、クライアントは接続先を正当なサイトと判断することができないためこのエラーが表示されているわけです(いわゆるオレオレ証明書と呼ばれているものです)。
そこで、ldapsearchコマンドが参照する設定ファイルを編集し、接続先の妥当性を確認しないようにしておきます。
もしOpenLDAPをソースからコンパイルした場合には、/usr/local/etc/openldap/ldap.confとなっている場合が多いでしょう。同ファイル名の/etc/ldap.confとは用途が異なるため注意してください。
正しく設定した場合は、エントリを検索できるようになっているはずです。
実際にtcpdumpなどで636/tcpに流れるデータを確認してみてください。
StartTLS
こちらもOpenLDAPに限った話ではなく、SMTPやPOP3などでは比較的多く使われている技術ですが、OpenLDAPはStartTLSをサポートしています。StartTLSとは、接続の確立時には平文によるデータ通信を行い、STARTTLSコマンドをクライアントが発行することにより、以降の通信を全て暗号化してしまう技術です。
この接続はldapsearchコマンドに-Zオプションを渡すだけで実現できます。それぞれのコマンドを実行中に389/tcpをtsharkコマンドでキャプチャしてみました。
このように、同じ389/tcpを使用しているにもかかわらず、StartTLSを使用した場合には通信内容が暗号化されています。
最後に
今回はSSL/TLSによる通信経路の暗号化についてお話ししてきました。
暗号化は効果的なセキュリティ対策ですが、複雑な暗号化、復号化はCPU負荷を生み出すことを考慮しておかなければなりません。たとえば、メールサーバのルックアップデータベース用にLDAPを使用していた場合、メールの流量によってはLDAP検索速度にボトルネックが発生し、メール配送のスループットが落ちてしまうことがあります。「セキュリティ上必要だから」という漠然とした理由でメールサーバ、LDAPサーバ間の接続をSSLにしていては、さらにボトルネックが大きくなってしまう可能性もあります。
本当にそのネットワーク上にSSLが必要なのか検討した上で、さらに可能であれば事前にパフォーマンステストを行ってからSSLを導入するようにしてください。