最初に
前回 までのFDS記事でSASLという言葉が出てきましたが、そういえばこれまでSASLについてあまり触れることがありませんでしたので、今回はOpenLDAPとSASLの関係についてお話ししておきます。
SASLとはS imple A uthentication and S ecurity L ayerの略であり、簡単に言ってしまうと認証のためのフレームワークのようなものです。SASLを使用することにより、開発者は既存のライブラリや仕組みを再利用することができ、利用者にはチャレンジ・レスポンス認証などの安全な認証方式を提供することができます。
また、認証方式についてですが、SASLの中にはいくつかのメカニズムが用意されており、Kerberos、GSSAPI、DIGEST-MD5などいくつかの方式を利用することができるのですが、今回は検証環境の関係上、KerberosなどではなくDIGEST-MD5やCRAM-MD5を用いて安全な認証を実現します。
OpenLDAPとSASLの関係
たとえば、今まで通り-xオプションを使ったシンプル認証で
% ldapsearch -x -D “uid=nomo,ou=People,dc=example,dc=com" -w abc123 -b “dc=example,dc=com" "objectClass=*"
という検索を行う場合、クライアントからサーバに次のようなデータが送信されます。abc123という文字列が暗号化されていないことがわかるでしょうか(図1 ) 。
図1 Wiresharkでパケットをキャプチャした様子
SASLを有効にすることで、前回の記事のAPOP同様、ネットワーク上に流れるパスワードを暗号化することができます。
それではさっそくSASLの設定です。/etc/openldap/slapd.confに以下を追記してslapdを再起動してください。
リスト1 slapd.confに追記する内容
sasl-regexp
uid=([^,]+),.*,cn=auth
uid=$1,ou=People,dc=example,dc=com
password-hash {CLEARTEXT}
クライアント側からSASL認証が要求されると、LDAPサーバは認証時に与えられたユーザ名を用いて、
uid=ユーザ名,cn=,cn=digest-md5,cn=auth
(レルムが省略された場合はuid=ユーザ名,cn=digest-md5,cn=auth)
といったDNを生成します。ただし、実際にはこのようなエントリは存在しませんので、実際のDNにマッピングする設定が必要となります。そのための設定が
sasl-regexp 変換前DN 変換後DN
です。また、チャレンジ・レスポンス方式を使用する場合にはサーバ側に平文パスワード、または中間値が必要となりますので、エントリ中のuserPassword属性を常に平文で保存しておくため、
password-hash {CLEARTEXT}
を設定しています。この設定を行うことで
% ldappasswd -U nomo -w abc123 -Y digest-md5 -s hoge
のようにパスワードを変更しても、それがデフォルトのSSHA形式でなく常に平文状態で格納されるようになります。
エントリの登録
今回は
sasl-regexp uid=([^,]+),.*,cn=auth uid=$1,ou=People,dc=example,dc=com
という設定を行っているため、登録するエントリもuid=$1,ou=People,dc=example,dc=com に属している必要があります。
リスト2 サンプルエントリ
dn: dc=example,dc=c、om
objectClass: dcObject
objectClass: organization
dc: example
o: example
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People
dn: uid=nomo,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
sn: nomo
cn: nomo
uid: nomo
userPassword: abc123
エントリを登録できたら、後は次のように-Uオプションと-Yオプションを使用した検索が可能となります。
% ldapsearch -U proxy -Y digest-md5 -b "dc=example,dc=com" "objectclass=*"
Wiresharkで確認してみても、平文パスワードは確認できず、サーバから発行されたチャレンジに基づきクライアントが毎回異なったレスポンスを返していることがわかります(図2) 。
図2 パケットをキャプチャした様子
Postfix SMTP AuthとSASL
OpenLDAP側でSASL設定を行っておくことにより、Cyrus-SASLのldapdbプラグインを利用することができるようになります。このプラグインは以前にも紹介したよう、FDSでは対応していないSASLプロキシ設定を行っておかなければなりません。
この概念としては、PostfixからロードされるSASLライブラリがプロキシアカウントであるproxyuserでLDAPサーバに接続し、そのproxyuserが代理で実際のユーザを検索しパスワードを照合する、といったイメージになります。そのため、次のようにプロキシ用のアカウントをLDAP上に登録しておきます。
今までとの違いは、saslAuthzTo属性です。この設定によって、proxyuserがuid=.*,ou=People,dc=example,dc=com以下から照合を行うことができるようになります。
リスト3 proxyuserアカウントの登録
dn: uid=proxyuser,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
sn: proxyuser
cn: proxyuser
uid: proxyuser
userPassword: proxy_passwd
saslAuthzTo: dn.regex: uid=.*,ou=People,dc=example,dc=com
また、saslAuthzTo属性を有効にするため、slapd.confには
sasl-authz-policy To
を加えるとともに、proxyuserアカウントが実ユーザのパスワードを検索できるよう、
access to *
by self write
by dn="uid=proxyuser,ou=People,dc=example,dc=com" write
by * read
といったACLを設定しておきます。あとはSMTP Auth用にsmtpd.confを作成します。
リスト4 /usr/lib/sasl2/smtpd.conf
pwcheck_method: auxprop
auxprop_plugin: ldapdb
ldapdb_uri: ldap://localhost
ldapdb_id: proxyuser
ldapdb_pw: proxy_passwd
ldapdb_mech: DIGEST-MD5
mech_list: LOGIN PLAIN CRAM-MD5 DIGEST-MD5
駆け足になりましたが、これでsaslauthdを使わずLDAP認証が可能となりましたので、telnetコマンドなどで動作を確認してみてください。
最後に
OpenLDAPには以前紹介したSSLや今回紹介したようなSASLのように、さまざまな暗号化手法が用意されています。どのような手法を選択するかはユーザ次第となりますが、SSLを有効にした上でSASL認証を行ってもあまり意味が無さそうですし、LDAPのメリットである「高速な検索」が暗号化、復号化処理の負荷により失われてしまうかもしれません。
また、LDAPサーバ、クライアントはデータセンターなどの閉鎖的なネットワークに存在することも多く、このような場合にも通信経路を暗号化させる意味はそれほど無いでしょう。そのため、SSLやSASLを有効にする場合には、サーバとクライアントの経路、登録されているデータの機密性など考慮した上で適切な設定を行ってください。
たとえばインターネット越しにLDAP検索を行う場合でも、すでに経路がVPNなどで暗号化されていれば、通常SSLの必要もありません。ただし、検索速度を犠牲にしてでも二重、三重の暗号化を検討したいのであれば、それもまた自由です。
2008年最後の記事となってしまいましたが、来年もよろしくおつきあいください。