読者です 読者をやめる 読者になる 読者になる

たごもりすメモ

コードとかその他の話とか。

OpenLDAPサーバを介してActiveDirectoryに接続する際の注意点ふたつメモ

Windows ServerのActive DirectoryLDAPサーバとして使用している人は多いと思うが、様々な事情によりWindows Serverに直接繋ぐのはアレなのでOpenLDAPサーバ(slapd)を立てて ldap backend を使用して中継サーバとしている人はそれなりにいると思う。いるよね。いるかなあ。

そのような構成にした場合、以下の2点に注意する必要がある。のでまとめてみた。
また 前のエントリ で書いた perl backend を使用した構成をとる場合にも影響する。

AD特有の属性値の扱いについて

ActiveDirectory上のデータではアカウント名が sAMAccountName フルネームが displayName という属性に入っていることが多い*1。したがってこれらの属性が使えないといろいろと不便だ。
しかしOpenLDAPに含まれているスキーマ定義にこれらの属性は存在しない。

slapdが外部のバックエンドと通信を行う際、以下の点に注意する必要がある。

  • フィルタはslapdが把握しているスキーマに適合するか検査される
    • スキーマに存在しない属性フィルタは以下のようにマークされて渡される(ようだ)
 (sAMAccountName=tagomoris)
 ↓
 (?sAMAccountName=tagomoris)  # 当然バックエンド側では存在しない属性としてエラーになる
  • レスポンスのLDAP Entityはslapdが把握しているスキーマに適合されるか検査される
    • つまり知らない属性値などは無視され、クエリ発行元には返らない
    • これは perl backend 特有の動作かも? ldap backend の場合はバックエンドから返ってきたEntityがスキーマにかかわらずそのまま返ってくる

これらの問題により、OpenLDAPサーバが間にいると sAMAccountName でフィルタができなくなるし、perl backend から sAMAccountName の値が返せない。これだと残念すぎるので、どうしても扱いたい値については、自力で slapd.conf で定義してやろう。*2
必要な情報はMSDNからかきあつめてきた。

またLDAPの知識が全然足りなかったところ、こちらのページが大変参考になった。多謝!
OpenLDAP 2.0 ´ÉÍý¼Ô¥¬¥¤¥É: ¥¹¥­¡¼¥Þ»ØÄê

ということで sAMAccountName と displayName だけでもとりあえず扱えるようにするには、slapd.conf に以下のように加える。各database指定より前に書く。

attributeType ( 1.2.840.113556.1.4.221 NAME 'sAMAccountName'
                EQUALITY caseIgnoreMatch
                SUBSTR caseIgnoreSubstringsMatch
                SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )

attributeType ( 1.2.840.113556.1.2.13 NAME 'displayName'
                EQUALITY caseIgnoreMatch
                SUBSTR caseIgnoreSubstringsMatch
                SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )

これで sAMAccountName でフィルタがかけられるようになるし、perl backendを使っているときクエリ結果に sAMAccountName や displayName が含まれるようになるはず。

コネクション数の制御について

OpenLDAPldap backend 経由で接続する背後のサーバとの間のコネクション数がどんどん増えて溢れてしまう、という問題に直面した。
手元で Apache2 mod_ldap + mod_authnz_ldapOpenLDAP 2.4.26 ldap backend を組み合わせて起きた事態。もしかしたらこの組合せに特有かもしれない。そこまで見てない。

プロキシサーバ(Apache2 mod_proxy)の認証に mod_authnz_ldap を使用していたら、Apacheとslapdの間のTCP Establishedは80くらいなのにslapdとその背後のLDAPサーバの間のTCPコネクション数がうなぎのぼりに上昇し、ついには溢れて全く通信ができなくなるという事態になってしまった。
詳細に状況を見てみると、厳密に毎回ではないものの、認証が行われるたびに張りっぱなしのコネクションがひとつ増えてる。原因が何かを調べてみたんだけどいまいちよく分からない。あれこれ試してみて、以下の設定でとりあえず症状が収まった。

database        ldap
suffix          "dc=tagomor,dc=is"
uri             ldap://ldapserver.local/
lastmod         off
binddn          "cn=Manager,dn=tagomor,dn=is"
bindpw          xxxxxx

chase-referrals no
conn-ttl        15
idle-timeout    5
single-conn     yes

多分 "single-conn yes" がキモ。
mod_ldap からの接続が search と bind を繰り返す際、裏側の ldap backend が張るコネクションがリークするんじゃないかと思う。 single-conn yes を設定*3したところ、認証のたびにコネクション数が増える症状は収まってマトモな状況になった。

大量の search&bind を繰り返すような使いかたでないと出ない症状だと思うけど、気にしておいて損はないと思う。

*1:ような気がする……少なくとも自分の知ってる例は全部そうだった

*2:本当はADが扱うスキーマをそのまま用意して読み込んでやりたいんだけど、どうしても見付からなかった。誰か知ってたら教えて……。

*3:デフォルトはNO