389 Directory Server のアクセス制御では、誰がどの属性を読めるのか、誰が書き込めるのかを明確にします。LDAP に接続するアプリケーションをすべて cn=Directory Manager で接続させるのではなく、読み取り用 BIND、書き込み用 BIND、管理者 DN を分けます。
この記事は、Ubuntu 22.04 の既存環境で 389 Directory Server の BIND ユーザーとアクセス制御を読み直すための記事です。新規構築では Ubuntu 26.04 側の記事を優先しつつ、22.04 環境の設定確認や古い構築記録の読み替えに使ってください。
- 匿名 BIND を許可するかどうか
- 読み取り用 BIND と書き込み用 BIND の分離
- BIND ユーザー用 LDIF の作成
- ACI の考え方
ldapsearchで権限差を確認する方法
書籍
LDAP – 設定・管理・プログラミング
LDAP の基礎、ディレクトリ設計、検索、認証連携を体系的に確認したい場合の参考書籍です。価格や在庫はリンク先で確認してください。
Amazon で見るこのリンクは Amazon アソシエイトリンクです。
匿名 BIND の扱い
内部 LDAP でも、匿名 BIND を許可するかどうかは明確に決めます。認証基盤として使う場合は、匿名 BIND を無効化し、参照用 BIND ユーザーを作る方が扱いやすいです。
sudo dsconf ldap01 config replace nsslapd-allow-anonymous-access=off
sudo dsctl ldap01 restart匿名 BIND を止めた場合、SSSD、Samba、Postfix、アプリケーションなどは、用途に応じた BIND ユーザーで検索する設計にします。
BIND ユーザーを分ける
読み取り専用の cn=ro と、書き込み用の cn=rw を分けます。参照だけのサービスに書き込み権限を与えないことが目的です。
| BIND DN | 用途 |
|---|---|
cn=ro,ou=service,... | SSSD、Postfix、Web アプリケーションなどの参照用 |
cn=rw,ou=service,... | 管理ツールや登録処理などの書き込み用 |
cn=Directory Manager | 389 DS 管理者。通常のアプリ連携には使わない |
BIND ユーザーを登録する
サービスアカウント用の OU に、読み取り用と書き込み用の BIND ユーザーを登録します。
cat <<'EOF' > /tmp/bind-users.ldif
dn: cn=ro,ou=service,dc=example,dc=local
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: ro
userPassword: change-me-ro
dn: cn=rw,ou=service,dc=example,dc=local
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: rw
userPassword: change-me-rw
EOF
ldapadd -x \
-H ldaps://ldap.example.local \
-D 'cn=Directory Manager' \
-W \
-f /tmp/bind-users.ldifパスワードは例の値を使わず、運用環境の管理方法に合わせます。読み取り用と書き込み用で同じパスワードを使い回さないようにします。
ACI の考え方
ACI は、LDAP ツリーに対するアクセス制御です。どの DN に、どの属性への、どの操作を許可するかを定義します。ここでは考え方として、読み取り用 BIND には検索と読み取り、書き込み用 BIND には必要な範囲の変更を許可します。
ldapmodify -x -H ldaps://ldap.example.local -D 'cn=Directory Manager' -W <<'EOF'
dn: dc=example,dc=local
changetype: modify
add: aci
aci: (target="ldap:///dc=example,dc=local")(targetattr="*")(version 3.0; acl "read access for ro"; allow (read,search,compare) userdn="ldap:///cn=ro,ou=service,dc=example,dc=local";)
aci: (target="ldap:///dc=example,dc=local")(targetattr="*")(version 3.0; acl "write access for rw"; allow (all) userdn="ldap:///cn=rw,ou=service,dc=example,dc=local";)
EOF実運用では、targetattr="*" や allow (all) をそのまま広く使うのではなく、必要な属性と操作に絞ります。まずは参照系と更新系を分ける設計から始めます。
権限差を確認する
読み取り用 BIND で検索できること、匿名 BIND では検索できないことを確認します。
ldapsearch -x \
-H ldaps://ldap.example.local \
-D 'cn=ro,ou=service,dc=example,dc=local' \
-W \
-b dc=example,dc=local \
dn
ldapsearch -x \
-H ldaps://ldap.example.local \
-b dc=example,dc=local \
dn匿名 BIND 側で検索できてしまう場合は、匿名アクセスの設定や ACI を確認します。読み取り用 BIND で見えない場合は、base DN、ACI、BIND DN、パスワードを分けて確認します。
BIND ユーザーを分ける理由
LDAP に接続するアプリケーションをすべて管理者 DN で接続させると、読み取り専用でよい用途にも過剰な権限を与えることになります。BIND ユーザーは、アプリケーションが LDAP を検索するための専用アカウントとして作り、必要な属性だけを読めるようにします。
SSSD、Samba、メール、Web アプリケーションなどで参照範囲が異なる場合は、BIND ユーザーを分けると障害時の切り分けや権限見直しがしやすくなります。
まとめ
LDAP のアクセス制御は、匿名 BIND、読み取り専用 BIND、書き込み BIND、管理者 DN を分けて考えると確認しやすくなります。Samba や Postfix から参照する場合も、必要最小限の権限を持つ BIND ユーザーを使います。
22.04 の既存環境を見直すときは、匿名 BIND が許可されていないか、アプリケーションが管理者 DN で接続していないか、ACI が広すぎないかを分けて確認します。

