【OpenLDAP基本講座 第5回】アクセス制御 (ACL)。olcAcessの読み方・書き方と「鉄壁の守り」

あなたのLDAPサーバー、丸見えになっていませんか?

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、LDIFを使ったデータの登録・更新・削除(CRUD操作)について学びました。
これでディレクトリにデータが入りましたが、実は今の状態はセキュリティ的に非常に危険です。

OpenLDAPのデフォルト設定(または簡易的な設定)では、「ネットワークに繋がる人なら誰でも、全ユーザーの全情報を閲覧可能」になっていることが多いのです。
社員の自宅住所や電話番号、最悪の場合はパスワードハッシュまでもが、ldapsearch 一発で抜き取られてしまうリスクがあります。

コウ君

先生、ギクリとしました……。
「動けばいいや」と思って、ACLの設定は後回しにしてました。
というか、to attrs=userPassword by self write by anonymous auth... みたいな呪文が難しすぎて、見なかったことにしていたんです。
あれって、上から順番に書かないと動かないって本当ですか?

リナックス先生

コウ君、それはファイアウォールと同じよ。
「First Match Wins(最初にマッチしたルールが適用される)」という大原則を知らないと、いくら設定を書いても穴だらけになるわ。
今回は、OpenLDAPの守護神である ACL (Access Control List) の仕組みを、図解と実例で完全にマスターしましょう!

ウィンドウズ先生

はい、ウィンドウズ先生です。
Active DirectoryではGUIでポチポチ権限設定できますが、裏側ではACLが動いています。
OpenLDAPのACL(olcAccess)は非常に柔軟で強力ですが、書き方を間違えると「誰もログインできない(締め出し)」という事故も起こります。
私が現場で使っている「鉄板の設定テンプレート」を紹介しますので、まずはこれをベースに理解を深めてください。

本記事では、ACLの基本構文、評価順序のルール、実務で必須となる「パスワード保護」や「セルフサービス(自己変更)」の設定、そして特定のグループに管理権限を委譲する方法までを徹底解説します。

🐬 OpenLDAP 基本講座 カリキュラム


第1章:ACLの解剖学。olcAccessの構造を理解する

OpenLDAP (cn=config) において、アクセス制御は olcAccess という属性で定義されます。
この属性は1つのデータベース(olcDatabase={2}mdb,cn=config)に対して複数設定でき、それぞれが1つのルールを表します。

基本構文

ACLは以下の3要素で構成されています。

to <対象> by <誰に> <権限> [by <誰に> <権限> ...]
  1. to <対象>: 制御したいデータはどこか?(DN、属性、フィルタなど)
  2. by <誰に>: アクセスしてきているのは誰か?(DN、自分自身、匿名、認証済みユーザーなど)
  3. <権限>: 何を許可するのか?(読み取り、書き込み、認証など)

権限レベル (Access Level)

権限は強さに応じてレベル分けされています。
強い権限を与えると、それより弱い権限も自動的に付与されます。

権限 意味 包含される権限
manage 管理(全権限)。ACL変更などはできないが、データ操作は自由。 write, read, search, compare, auth
write 書き込み(変更、追加、削除)。 read, search, compare, auth
read 読み取り(値の参照)。 search, compare, auth
search 検索(フィルタにマッチするか)。値は見えない。 compare, auth
compare 比較(値が一致するか)。パスワード確認などに使用。 auth
auth 認証(Bind)。パスワード照合のために必要。 none
none 拒否(何もできない)。存在すら分からない。

重要: read 権限がないと、検索でヒットしても結果の中身(値)を見ることができません。


第2章:評価順序の罠。「First Match Wins」とは?

ACLを理解する上で最も重要なルール、それは「評価順序」です。
OpenLDAPは、設定されたACLを上から順番に評価し、条件にマッチした行が見つかった時点で評価を終了します。

失敗例:順序の間違い

# ルール1:全員に読み取り許可
to * by * read

# ルール2:パスワードは自分以外見ちゃダメ
to attrs=userPassword by self write by anonymous auth by * none

この設定の場合、パスワード情報へのアクセスはどうなるでしょうか?
答えは「全員が見れてしまう」です。

なぜなら、パスワード属性へのアクセス要求が来たとき、まず「ルール1(to *)」にマッチしてしまいます。
そこで「全員read OK」と判定され、処理が終了するため、下の「ルール2」は無視されるのです。

鉄則:具体的ルールを上に、汎用ルールを下に

正しい順序はこうです。

# ルール1:パスワード(具体的)の設定
to attrs=userPassword by self write by anonymous auth by * none

# ルール2:それ以外(汎用的)の設定
to * by * read

例外的な細かいルールを先に書き、最後に「その他すべて」に対するルールを書くのが鉄則です。


第3章:実践ACL(1) パスワードを鉄壁に守る

それでは、具体的な設定パターンを見ていきましょう。
まずは最優先事項、userPassword 属性の保護です。

要件

  • 自分自身 (self) は、パスワードを変更 (write) できる。
  • ログイン認証のために、匿名ユーザー (anonymous) はパスワード照合 (auth) ができる。
  • それ以外のユーザー(他人)は、パスワードを見ること (read) も比較すること (compare) もできない。

ACL設定

to attrs=userPassword
  by self write
  by anonymous auth
  by * none

解説:

  • by anonymous auth: これがないと、ユーザーがログイン(Bind)する際に「パスワードが合っているか」のチェックができず、ログインに失敗します。
    ※OpenLDAPの仕様上、Bind処理の初期段階は匿名状態で行われるためです。
  • by * none: これにより、管理者が ldapsearch してもパスワードハッシュは見えなくなります(セキュリティ上好ましい)。

💡 プロのノウハウ:shadowLastChange
Linuxユーザーの場合、shadowAccount オブジェクトクラスに含まれる shadowLastChange(最終パスワード変更日)などの属性も、パスワードと一緒に更新されることが多いです。
そのため、to attrs=userPassword,shadowLastChange のようにまとめて許可を与えるのが実用的です。


第4章:実践ACL(2) 自分の情報は自分で変える(Self Write)

「電話番号や住所が変わったら、自分で更新してほしい」。
管理者の負担を減らすために、ユーザー自身による情報更新を許可します。

要件

  • 自分自身のエントリ全体に対して、書き込み権限を与える。
  • ただし、uiduidNumber などのシステム識別子は変更させたくない。

ACL設定

# ルールA:システム属性は変更禁止(readのみ)
to attrs=uid,uidNumber,gidNumber,homeDirectory,loginShell
  by * read

# ルールB:それ以外は自分なら書き込みOK
to *
  by self write
  by users read
  by * none

解説:
ここでも順序が重要です。
ルールAで重要な属性を「readのみ」に固定し、その後にルールBで「それ以外はwrite」を許可します。
by users read は、「認証済みユーザーなら他人の情報(電話番号など)を検索・閲覧できる」という設定です。
社内アドレス帳として使うなら必須ですが、個人情報保護の観点で閉じるなら by users none にします。


第5章:実践ACL(3) 管理者グループへの権限委譲

「特権管理者 (RootDN) のパスワードを共有するのは危険」。
そこで、特定のLDAPグループ(例:cn=Admins,ou=Groups...)に所属するメンバーに、管理権限を与えます。

静的グループ (groupOfNames) を使う場合

set 演算子や group 識別子を使います。

to *
  by group/groupOfNames/member="cn=Admins,ou=Groups,dc=linuxkoubou,dc=com" write
  by * read

解説:

  • group/groupOfNames/member: 「groupOfNamesオブジェクトクラスを持ち、member属性にアクセス者のDNが含まれている場合」という条件です。
  • これにより、cn=Admins グループにメンバーを追加するだけで、そのユーザーは管理者権限(書き込み権限)を持つようになります。

💡 プロの視点:OU単位の委譲
「営業部の管理者は、営業部のOU配下だけ管理させたい」という場合。
to dn.subtree="ou=Sales,dc=..." というターゲット指定を使えば、特定のツリー配下のみに権限を限定できます。
大規模組織では必須のテクニックです。


第6章:LDIFによるACLの適用と修正手順

ACLの理論は分かりました。では、実際に cn=config に適用するにはどうすればいいでしょうか?
ACLは olcDatabase={2}mdb,cn=config エントリの olcAccess 属性として格納されています。

1. 現在のACLを確認する

まずは現状を把握します。

ldapsearch -Y EXTERNAL -H ldapi:/// -b "olcDatabase={2}mdb,cn=config" olcAccess

出力例:

olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to * by * read

{0}, {1} という番号(インデックス)が付いている点に注目してください。これが評価順序です。

2. ACLを変更する (ldapmodify)

ACLの変更は、既存の値を全置換(replace)するのが最も安全で分かりやすいです。

acl_update.ldif

dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to attrs=userPassword,shadowLastChange
  by self write
  by anonymous auth
  by * none
olcAccess: {1}to dn.base="" by * read
olcAccess: {2}to *
  by self write
  by users read
  by * none

コマンド実行:

ldapmodify -Y EXTERNAL -H ldapi:/// -f acl_update.ldif

3. 特定の行だけ挿入・削除する場合

全置換ではなく、間に挿入したい場合はインデックス指定を使います。

# インデックス1番(2番目のルール)の前に挿入
add: olcAccess
olcAccess: {1}to attrs=uidNumber by * read

これで、元々の {1} 以降は自動的に繰り下がります。


第7章:トラブルシューティング。slapaclの使い方

「設定したはずなのに書き込めない!」「見えてはいけないものが見えている気がする」。
ACLのトラブルは複雑怪奇になりがちです。
そんな時は、テストツール slapacl を使いましょう。

slapacl コマンド

実際にサーバーにアクセスすることなく、ACLの設定ファイルだけを読み込んで、「誰が何に対してどんな権限を持つか」をシミュレーションできます。

# 書式: slapacl -b <対象DN> -D <アクセス者DN> <属性名>

例:Taroさんが自分のパスワードを変更できるかテスト

slapacl -b "uid=taro,ou=People,dc=linuxkoubou,dc=com" \
  -D "uid=taro,ou=People,dc=linuxkoubou,dc=com" \
  userPassword

結果:

auth: write (=xw)

write と出ればOKです。もし readnone なら設定が間違っています。

💡 注意点:RootDNの特権
データベース設定(olcDatabase)で定義された RootDN(管理者) は、ACLの設定に関わらず常に全権限(manage)を持ちます。
「管理者はアクセスできるのに、一般ユーザーができない」という場合は、ACLが原因です。
逆に「管理者でもアクセスできない」場合は、ACLではなく、データベース自体が壊れているか、設定ファイル記述ミスの可能性があります。


まとめ:ACLは「狭く、厳しく」が鉄則

お疲れ様でした!
第5回は、OpenLDAPのセキュリティの要、ACLについて解説しました。

今回の重要ポイント:

  • ACLは上から順に評価され、最初にマッチしたルールが適用される(First Match Wins)。
  • 具体的・例外的なルール(パスワードなど)を上に書き、汎用的なルール(to *)を最後に書く。
  • by anonymous auth はログイン認証のために必須。
  • トラブル時は slapacl でシミュレーションを行う。
ウィンドウズ先生

「面倒だから全許可」は、情報漏洩の時限爆弾を抱えるようなものです。
今回紹介したテンプレートを使えば、最低限の安全性は確保できます。
まずは基本形を適用し、運用しながら徐々に調整していくのが良いでしょう。

さて、これで内部的なアクセス制御は完璧です。
しかし、通信経路そのものが盗聴されたら、ACLも意味を成しません。
次回は、通信経路の暗号化について学びます。

次回、第6回は「セキュリティ強化。TLS/SSL化と証明書管理」です。
Let’s Encryptなどの証明書を使って、LDAP通信(ポート389)を暗号化(StartTLS/LDAPS)し、盗聴リスクをゼロにする手順を解説します。お楽しみに!

▼ ACL設定を安全に試す ▼

自分だけのラボ環境を構築
「おすすめVPS」

おすすめVPSを見る

セキュリティエンジニアへ
「ITエンジニア転職」

転職エージェントを見る

コメント