2009/11/01

OpenLDAP: access権限の管理

olcAccessディレクティブの管理

slapd.confに代ってslapd.dを使っていると、Access権限(olcAccess)の管理が少しだけ面倒に思えてきます。 それはslapd.confのようにテキストエディタで古いものを削って、新しく付け足すわけではないから。

例えば最上位DNからの一括検索を拒否しつつ、パスワード情報は認証時以外には開示しない設定だとします。 slapd.dディレクトリの中で、アクセス権限は次のように管理されています。

olcAccess: {0}to dn.base="dc=example,dc=org" by * none
olcAccess: {1}to attrs="userPassword" by anonymous auth by * none
olcAccess: {2}to dn.children="dc=example,dc=org" by self read

この状態で下記のldifファイル(update.ldif)に対してldapmodifyを実行したとします。

dn: olcDatabase={1}bdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: to dn.base="dc=example,dc=org" by * read
$ ldapmodify -x -W -D cn=admin,cn=config -f update.ldif

適当なところが一行置き換わるのかなと思いきや、3行だったolcAccessが1行に変更されています。

olcAccess: {0}to dn.base="dc=example,dc=org" by * read

不思議なことは何もないのですが、管理をする上では挙動をチェックして把握しておくのが重要だったりします。

管理用に何かWebベースやGUIなソフトウェアを使うかもしれません。 cn=config以下ならデータサイズが限られているので良いのですが、 データ件数が多いエントリをGUIなどのツールで開く時には、hard limitsに逹っするまでのサーバー側の負荷はもちろんですが、多くのエントリ情報を格納するツール側もそれなりのメモリを消費するためハングアップに気をつける必要があります。

台帳的な管理の手法

既に定義されているolcAccessの間に定義を挿入するというのは、少し面倒そうなので、簡単なシェルスクリプトを作成しました。

ツールは主に2つのパートから成ります。

  1. show_olcAccess.sh: 定義済みolcAccessエントリの確認ツール
  2. gen_access_ldif.sh: 一括登録、削除、更新用のldif生成ツール

どういう風に使えば便利そうかを想定すると…

$ ./show_olcAccess.sh > current.ldif ## olcAccessの行だけをcurrent.ldifに書き出す
$ vi current.ldif ## 追加したいolcAccess行を追加する
$ ./gen_access_ldif.sh < current.ldif | ldapmodify -x -W -D cn=admin,cn=config
## 最後は一気にldif形式のフォーマットを出力してldapmodifyに流し込む

show_olcAccess.sh: 定義済みolcAccessエントリの確認ツール

とりあえずは、"olcDatabase={1}bdb,cn=config"を決め打ちにしてolcAccessの各行を出力するようにします。

#!/bin/bash
ldapsearch -LLL -x -s base -W -D "cn=admin,cn=config" -b "olcDatabase={1}bdb,cn=config" olcAccess | while read line
do
  if /bin/echo -E "$line"|egrep ^olcAccess >/dev/null 2>&1 ; then
    l="$(/bin/echo -E "$line" | sed 's/{[0-9]*}//')"
    echo -E "$l"
  fi
done

これを実行すると次のような表示になります。

$ ./show_olcAccess.sh
olcAccess: to dn.base="dc=example,dc=org" by * none
olcAccess: to attrs="userPassword" by anonymous auth by * none
olcAccess: to dn.children="ou=accounts,dc=example,dc=org" by users read

わざわざ"olcAccess: {0}to"にある"{0}"の部分を取り去っているのは、後から編集する時に邪魔になるからです。 みるだけなら良いのですが、olcAccessを間に1行追加するのに、数字を全部後ろにずらしていくのは不毛でしょう。

gen_access_ldif.sh: 一括登録、削除、更新用のldif生成ツール

次はさきほど1行追加するのに使ったような"changetype: modify"を含むldapmodify用のLDIFファイルを生成します。

#!/bin/bash
db=${1:-"{1}bdb"}
opt="${2:-replace}"
## show header
echo "dn: olcDatabase=$db,cn=config"
echo "changetype: modify"
echo "$opt: olcAccess"
while read line
do
  echo -E "$line"
done

これを実行すると、LDIFファイルを出力します。 入力は”show_olcAccess.sh”で出力されたようなものです。

./gen_access_ldif.sh < access.ldif
dn: olcDatabase={1}bdb,cn=config
changetype: modify
replace: olcAccess
olcAccess: to dn.base="dc=example,dc=org" by * none
olcAccess: to attrs="userPassword" by anonymous auth by self read by * none
olcAccess: to dn.children="ou=accounts,dc=example,dc=org" by users read

もし既存の設定を消したければ、./gen_access_ldif.sh "" delete < access.ldif でできます。 複数のDBがあれば、第一引数に./gen_access_ldif.sh {2}hdbのように指定する事もできます。 次は、olcSuffixとolcDatabaseとの関連を一覧にできれば便利かなぁ。

まとめ

こういうスクリプトって本質的なものじゃないんですけれど、テンプレート+αな操作の場合は準備しておくと、 誰かに頼むとか、手順で置いておかなきゃいけない時に、作業が簡潔になり早くできたりして便利です。

ldapmodifyを実行する部分もスクリプトにしても良いですが、そこは本質的なところではないので。 また、これ以上作り込んでしまうと、トラブルシュートができない。

スクリプト化は勉強にならない、という批判もありそうですが、本物のマニュアル手順を"plan B"として載せておけば良いでしょう。

スクリプトの中で特殊な事はしていませんが、"$1"が未定義の場合に"{1}bdb"をセットするところはダブルクォートなしに書くと、そのまま展開されてしまいます。 ${1:-{1\}bdb}でも良さそうだけれど、ここら辺のドキュメントって見た事ないなぁ。

0 件のコメント: