!!!技術的雑談-OpenLDAP2.3でsyncreplを試す !!環境 * CentOS5.2 * OpenLDAP 2.3.27(CentOS5.2標準) !!目的 *syncrepl方式でプロバイダ-コンシューマ方式の冗長化を試す !!手順 ! プロバイダをセットアップする まず、syncreplを使うには「syncprov.la」モジュールを使うように設定する。 slapd.confに以下の設定を行う。(これは動的設定ファイルでは設定不可っぽい。) modulepath /usr/lib/openldap moduleload syncprov.la あ、CentOS5.2の場合、OpenLDAPがsyncprov込みでコンパイルされているようで、modulepathとmoduleload無しでもOKみたい。 プロバイダのデータを保持するDBの設定を追加する。 (これはslapd.confでも動的設定でもOKなはず。) 今回はslapd.confに書いたのでslapd.confに設定する。 suffixはプロバイダとコンシューマで合わせる。 # sample.com database database bdb suffix "dc=sample,dc=com" rootdn "cn=Manager,dc=sample,dc=com" rootpw {SSHA}Um+mHLNo3Wht1TEiVuFzpsKOxxxxxxxx directory /var/lib/ldap/sample.com index objectClass eq,pres これをベースにsyncreplの設定を追加していく。 # syncreplで利用する運用属性にインデックスをつける index entryCSN,entryUUID eq # syncprovオーバレイの利用を指定 overlay syncprov # セッションログの利用を指定(100操作分) syncprov-sessionlog 100 ! コンシューマ側の設定を行う modulepath,moduleload,indexの設定は同じ。 コンシューマ側には「syncrepl」とその設定を書き込む。 syncrepl rid=001 ← ridはプロバイダに対して一意の値をコンシューマに振る(3桁の10進数) provider=ldap://192.168.64.131 ← プロバイダへの接続URL type=refreshOnly ← 同期方式(ここでは毎回接続して切断) interval=00:00:03:00 ← 同期間隔(ここでは3分) searchbase="dc=sample,dc=com" ← 同期する根 scope=sub ← attrs="*" ← 同期する属性(ここでは全て) schemachecking=off ← Schemaのチェック(ここでは行わない) bindmethod=simple ← プロバイダに接続する認証方式 binddn="cn=Manager,dc=sample,dc=com" ← プロバイダへバインドするDN credentials=hogehoge ← バインド時のパスワード(平文!!) ! 起動 この状態でプロバイダ→コンシューマの順番で立ち上げる。 コンシューマは設定された時間毎にプロバイダに接続しに行き、差分があった場合にそれを自身のDBに反映する。 その時、コンシューマ側では以下のようなログが出力される。 Apr 13 xx:21:13 test-slave slapd[17999]: slapd starting Apr 13 xx:21:13 test-slave slapd[17999]: is_entry_objectclass("", "2.5.17.0") no objectClass attribute Apr 13 xx:21:13 test-slave slapd[17999]: is_entry_objectclass("", "2.5.6.1") no objectClass attribute Apr 13 xx:21:13 test-slave slapd[17999]: is_entry_objectclass("", "2.16.840.1.113730.3.2.6") no objectClass attribute Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 fd=12 ACCEPT from IP=192.168.64.1:3618 (IP=0.0.0.0:389) Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=0 BIND dn="cn=Manager,dc=sample,dc=com" method=128 Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=0 BIND dn="cn=Manager,dc=sample,dc=com" mech=SIMPLE ssf=0 Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=0 RESULT tag=97 err=0 text= Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=1 SRCH base="dc=sample,dc=com" scope=0 deref=3 filter="(objectClass=*)" Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=1 SRCH attr=1.1 Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text= Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=2 SRCH base="" scope=0 deref=3 filter="(objectClass=*)" Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=2 SRCH attr=subschemaSubentry Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=2 SEARCH RESULT tag=101 err=0 nentries=1 text= Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=3 SRCH base="cn=Subschema" scope=0 deref=3 filter="(objectClass=*)" Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=3 SRCH attr=attributeTypes objectClasses matchingRules ldapSyntaxes * Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=3 SEARCH RESULT tag=101 err=0 nentries=1 text= Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=4 SRCH base="dc=sample,dc=com" scope=0 deref=3 filter="(objectClass=*)" Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=4 SRCH attr=1.1 Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=4 SEARCH RESULT tag=101 err=0 nentries=1 text= Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=5 SRCH base="dc=sample,dc=com" scope=1 deref=2 filter="(objectClass=*)" Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=5 SRCH attr=objectclass Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=5 SEARCH RESULT tag=101 err=0 nentries=1 text= Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=6 SRCH base="dc=sample,dc=com" scope=0 deref=2 filter="(objectClass=*)" Apr 13 xx:21:46 test-slave slapd[17999]: conn=0 op=6 SEARCH RESULT tag=101 err=0 nentries=1 text= Apr 13 xx:21:48 test-slave slapd[17999]: conn=0 op=7 SRCH base="uid=user1,dc=sample,dc=com" scope=0 deref=2 filter="(objectClass=*)" Apr 13 xx:21:48 test-slave slapd[17999]: conn=0 op=7 SEARCH RESULT tag=101 err=0 nentries=1 text= Apr 13 xx:21:48 test-slave slapd[17999]: conn=0 op=8 SRCH base="dc=sample,dc=com" scope=0 deref=2 filter="(objectClass=*)" Apr 13 xx:21:48 test-slave slapd[17999]: conn=0 op=8 SEARCH RESULT tag=101 err=0 nentries=1 text= プロバイダ側では普通にLDAPのClientから接続が来たかのようなログが出力される。 ちなみに、syncreplを書いたコンシューマー側は自動的に(?)書き込みLDAP操作が禁止されて参照のみになるっぽい。 ! 確認 プロバイダー側にJXplorerなどで接続し、何か変更をしてみる。 しばらく経ってその変更がコンシューマ側でも読み取れれば成功。 !!問題点 上記の設定では以下の問題があります。 * 同期に使われているBind DNがプロバイダのManager。セキュリティー上好ましくない。同期専用のアカウントを用意するべき。 * 同様に、このままでは勝手にコンシューマを立ち上げてプロバイダの内容をすべて抜かれる可能性がある。アクセス制限をするべき。 * 「type=refreshOnly」だと毎回接続に行って効率が悪い。refreshAndPersistを使うべき。 * 同期の度にプロバイダ側の全てのエントリーを舐めるらしく、効率が悪い。両方でaccessdbを設定すると効率が上がるらしいが、accessdb自体が本来のLDAPの負荷を上げるらしい。 * コンシューマ側にLDAP接続して更新操作をした時に、updaterefが設定されていれば自動的にプロバイダを教えるようにもできるらしい。 * どのみちプロバイダ側が落ちているときはLDAP DBに対する更新操作はできない。(運用制限) * コンシューマ側が落ちているときにsyncprov-sessionlog以上の個数の変更が行われると、コンシューマが再接続したときにどうなるの?(切り捨てられる?) !!履歴 2009/04/13 -- 初版 [[技術的雑談]]へ戻る !!突っ込み {{comment}} [[技術的雑談]]へ戻る {{trackback}} [[技術的雑談]]へ戻る