最初に
前回
これまで
syncreplが提供するレプリケーション
一般的なデータベースの冗長構成ではデータの完全同期が期待さることが多いかもしれません。たとえば、
一方、
OpenLDAPのsyncrepl機能もまた非同期のレプリケーションですが、
- 極力リアルタイムにレプリケーションを行う
- 適度なインターバルをもってレプリケーションを行う
といったことが可能です。通常の用途では前者を選択することが多いと思いますが、
refreshOnlyとrefreshAndPersist
前述の2通りのレプリケーションですが、
refreshOnlyを指定する場合、
一方、
まず、
# レプリケーションのためのインデックス(後述)
index entryCSN,entryUUID eq
index objectClass eq,pres
# syncrepl用のモジュールをロード
overlay syncprov
次に、
syncrepl rid=100 # コンシューマ識別ID(数字3桁)
provider=ldap://10.0.100.21:389 # プロバイダの接続先とポート
type=refreshOnly # レプリケーション方式(定期的な更新確認)
interval=00:00:05:00 # 接続間隔(5分)
searchbase="dc=example,dc=com" # 同期を行う対象の検索ベース
bindmethod=simple # 認証モード
binddn="cn=Manager,dc=example,dc=com" # バインドDN
credentials=secret # バインドパスワード
syncrepl rid=100 # コンシューマ識別ID(数字3桁)
provider=ldap://10.0.100.21:389 # プロバイダの接続先とポート
type=refreshAndPersist # レプリケーション方式(接続維持を行う)
retry="5 10 300 +" # 接続失敗した場合のリトライ間隔
searchbase="dc=example,dc=com" # 同期を行う対象の検索ベース
bindmethod=simple # 認証モード
binddn="cn=Manager,dc=example,dc=com" # バインドDN
credentials=secret # バインドパスワード
これらの挙動の違いをさらに理解するために、
01:55:32.035247 IP 10.0.100.22.51995 > 10.0.100.21.389: S 2972302010:2972302010(0) win 5840 <mss 1460,sackOK,timestamp 66828619 0,nop,wscale 6>
01:55:32.035493 IP 10.0.100.21.389 > 10.0.100.22.51995: S 2447691039:2447691039(0) ack 2972302011 win 5792 <mss 1460,sackOK,timestamp 217778436 66828619,nop,wscale 7>
01:55:32.035510 IP 10.0.100.22.51995 > 10.0.100.21.389: . ack 1 win 92 <nop,nop,timestamp 66828619 217778436>
01:55:32.035644 IP 10.0.100.22.51995 > 10.0.100.21.389: P 1:49(48) ack 1 win 92 <nop,nop,timestamp 66828619 217778436>
01:55:32.035780 IP 10.0.100.21.389 > 10.0.100.22.51995: . ack 49 win 46 <nop,nop,timestamp 217778436 66828619>
01:55:32.036386 IP 10.0.100.21.389 > 10.0.100.22.51995: P 1:15(14) ack 49 win 46 <nop,nop,timestamp 217778436 66828619>
01:55:32.036394 IP 10.0.100.22.51995 > 10.0.100.21.389: . ack 15 win 92 <nop,nop,timestamp 66828619 217778436>
01:55:32.036534 IP 10.0.100.22.51995 > 10.0.100.21.389: P 49:206(157) ack 15 win 92 <nop,nop,timestamp 66828619 217778436>
01:55:32.036913 IP 10.0.100.21.389 > 10.0.100.22.51995: P 15:66(51) ack 206 win 54 <nop,nop,timestamp 217778436 66828619>
01:55:32.036958 IP 10.0.100.22.51995 > 10.0.100.21.389: P 206:213(7) ack 66 win 92 <nop,nop,timestamp 66828619 217778436>
01:55:32.037007 IP 10.0.100.22.51995 > 10.0.100.21.389: F 213:213(0) ack 66 win 92 <nop,nop,timestamp 66828619 217778436>
01:55:32.037212 IP 10.0.100.21.389 > 10.0.100.22.51995: F 66:66(0) ack 213 win 54 <nop,nop,timestamp 217778436 66828619>
01:55:32.037220 IP 10.0.100.22.51995 > 10.0.100.21.389: . ack 67 win 92 <nop,nop,timestamp 66828619 217778436>
01:55:32.037228 IP 10.0.100.21.389 > 10.0.100.22.51995: . ack 214 win 54 <nop,nop,timestamp 217778436 66828619>
02:00:32.037537 IP 10.0.100.22.40337 > 10.0.100.21.389: S 3389899619:3389899619(0) win 5840 <mss 1460,sackOK,timestamp 66903620 0,nop,wscale 6>
02:00:32.037821 IP 10.0.100.21.389 > 10.0.100.22.40337: S 2858513305:2858513305(0) ack 3389899620 win 5792 <mss 1460,sackOK,timestamp 217808436 66903620,nop,wscale 7>
02:00:32.037838 IP 10.0.100.22.40337 > 10.0.100.21.389: . ack 1 win 92 <nop,nop,timestamp 66903620 217808436>
02:00:32.037917 IP 10.0.100.22.40337 > 10.0.100.21.389: P 1:49(48) ack 1 win 92 <nop,nop,timestamp 66903620 217808436>
02:00:32.038052 IP 10.0.100.21.389 > 10.0.100.22.40337: . ack 49 win 46 <nop,nop,timestamp 217808436 66903620>
02:00:32.038730 IP 10.0.100.21.389 > 10.0.100.22.40337: P 1:15(14) ack 49 win 46 <nop,nop,timestamp 217808436 66903620>
02:00:32.038738 IP 10.0.100.22.40337 > 10.0.100.21.389: . ack 15 win 92 <nop,nop,timestamp 66903620 217808436>
02:00:32.038827 IP 10.0.100.22.40337 > 10.0.100.21.389: P 49:206(157) ack 15 win 92 <nop,nop,timestamp 66903620 217808436>
02:00:32.040482 IP 10.0.100.21.389 > 10.0.100.22.40337: P 15:694(679) ack 206 win 54 <nop,nop,timestamp 217808436 66903620>
02:00:32.040492 IP 10.0.100.21.389 > 10.0.100.22.40337: P 694:1299(605) ack 206 win 54 <nop,nop,timestamp 217808436 66903620>
02:00:32.040497 IP 10.0.100.22.40337 > 10.0.100.21.389: . ack 1299 win 134 <nop,nop,timestamp 66903620 217808436>
02:00:32.040501 IP 10.0.100.21.389 > 10.0.100.22.40337: P 1299:1904(605) ack 206 win 54 <nop,nop,timestamp 217808436 66903620>
02:00:32.040724 IP 10.0.100.21.389 > 10.0.100.22.40337: P 1904:2006(102) ack 206 win 54 <nop,nop,timestamp 217808436 66903620>
02:00:32.040733 IP 10.0.100.22.40337 > 10.0.100.21.389: . ack 2006 win 153 <nop,nop,timestamp 66903620 217808436>
02:00:32.055063 IP 10.0.100.22.40337 > 10.0.100.21.389: P 206:213(7) ack 2006 win 153 <nop,nop,timestamp 66903624 217808436>
02:00:32.055077 IP 10.0.100.22.40337 > 10.0.100.21.389: F 213:213(0) ack 2006 win 153 <nop,nop,timestamp 66903624 217808436>
02:00:32.055326 IP 10.0.100.21.389 > 10.0.100.22.40337: F 2006:2006(0) ack 214 win 54 <nop,nop,timestamp 217808438 66903624>
02:00:32.055334 IP 10.0.100.22.40337 > 10.0.100.21.389: . ack 2007 win 153 <nop,nop,timestamp 66903624 217808438>
02:05:32.040132 IP 10.0.100.22.56558 > 10.0.100.21.389: S 3801473658:3801473658(0) win 5840 <mss 1460,sackOK,timestamp 66978620 0,nop,wscale 6>
02:05:32.040392 IP 10.0.100.21.389 > 10.0.100.22.56558: S 3269951867:3269951867(0) ack 3801473659 win 5792 <mss 1460,sackOK,timestamp 217838436 66978620,nop,wscale 7>
02:05:32.040412 IP 10.0.100.22.56558 > 10.0.100.21.389: . ack 1 win 92 <nop,nop,timestamp 66978620 217838436>
02:05:32.040441 IP 10.0.100.22.56558 > 10.0.100.21.389: P 1:49(48) ack 1 win 92 <nop,nop,timestamp 66978620 217838436>
02:05:32.040664 IP 10.0.100.21.389 > 10.0.100.22.56558: . ack 49 win 46 <nop,nop,timestamp 217838436 66978620>
02:05:32.041292 IP 10.0.100.21.389 > 10.0.100.22.56558: P 1:15(14) ack 49 win 46 <nop,nop,timestamp 217838436 66978620>
02:05:32.041300 IP 10.0.100.22.56558 > 10.0.100.21.389: . ack 15 win 92 <nop,nop,timestamp 66978620 217838436>
02:05:32.041398 IP 10.0.100.22.56558 > 10.0.100.21.389: P 49:206(157) ack 15 win 92 <nop,nop,timestamp 66978620 217838436>
02:05:32.041893 IP 10.0.100.21.389 > 10.0.100.22.56558: P 15:66(51) ack 206 win 54 <nop,nop,timestamp 217838436 66978620>
02:05:32.041937 IP 10.0.100.22.56558 > 10.0.100.21.389: P 206:213(7) ack 66 win 92 <nop,nop,timestamp 66978621 217838436>
02:05:32.042001 IP 10.0.100.22.56558 > 10.0.100.21.389: F 213:213(0) ack 66 win 92 <nop,nop,timestamp 66978621 217838436>
02:05:32.042186 IP 10.0.100.21.389 > 10.0.100.22.56558: F 66:66(0) ack 213 win 54 <nop,nop,timestamp 217838437 66978621>
02:05:32.042194 IP 10.0.100.22.56558 > 10.0.100.21.389: . ack 67 win 92 <nop,nop,timestamp 66978621 217838437>
02:05:32.042202 IP 10.0.100.21.389 > 10.0.100.22.56558: . ack 214 win 54 <nop,nop,timestamp 217838437 66978621>
コンシューマ側のslapdを起動すると、
次はrefreshAndPersist時の結果です。
01:29:10.377858 IP 10.0.100.22.36157 > 10.0.100.21.389: S 3928508035:3928508035(0) win 5840 <mss 1460,sackOK,timestamp 66433204 0,nop,wscale 6>
01:29:10.378147 IP 10.0.100.21.389 > 10.0.100.22.36157: S 3406805294:3406805294(0) ack 3928508036 win 5792 <mss 1460,sackOK,timestamp 217620270 66433204,nop,wscale 7>
01:29:10.378165 IP 10.0.100.22.36157 > 10.0.100.21.389: . ack 1 win 92 <nop,nop,timestamp 66433205 217620270>
01:29:10.378226 IP 10.0.100.22.36157 > 10.0.100.21.389: P 1:49(48) ack 1 win 92 <nop,nop,timestamp 66433205 217620270>
01:29:10.378417 IP 10.0.100.21.389 > 10.0.100.22.36157: . ack 49 win 46 <nop,nop,timestamp 217620270 66433205>
01:29:10.379048 IP 10.0.100.21.389 > 10.0.100.22.36157: P 1:15(14) ack 49 win 46 <nop,nop,timestamp 217620270 66433205>
01:29:10.379056 IP 10.0.100.22.36157 > 10.0.100.21.389: . ack 15 win 92 <nop,nop,timestamp 66433205 217620270>
01:29:10.379228 IP 10.0.100.22.36157 > 10.0.100.21.389: P 49:206(157) ack 15 win 92 <nop,nop,timestamp 66433205 217620270>
01:29:10.379588 IP 10.0.100.21.389 > 10.0.100.22.36157: P 15:52(37) ack 206 win 54 <nop,nop,timestamp 217620270 66433205>
01:29:10.421379 IP 10.0.100.22.36157 > 10.0.100.21.389: . ack 52 win 92 <nop,nop,timestamp 66433215 217620270>
01:29:19.877158 IP 10.0.100.21.389 > 10.0.100.22.36157: P 52:711(659) ack 206 win 54 <nop,nop,timestamp 217621220 66433215>
01:29:19.877173 IP 10.0.100.22.36157 > 10.0.100.21.389: . ack 711 win 112 <nop,nop,timestamp 66435579 217621220>
01:29:24.507106 IP 10.0.100.21.389 > 10.0.100.22.36157: P 711:1370(659) ack 206 win 54 <nop,nop,timestamp 217621683 66435579>
01:29:24.507118 IP 10.0.100.22.36157 > 10.0.100.21.389: . ack 1370 win 133 <nop,nop,timestamp 66436737 217621683>
01:29:28.850948 IP 10.0.100.22.36157 > 10.0.100.21.389: P 206:213(7) ack 1370 win 133 <nop,nop,timestamp 66437823 217621683>
01:29:28.850966 IP 10.0.100.22.36157 > 10.0.100.21.389: F 213:213(0) ack 1370 win 133 <nop,nop,timestamp 66437823 217621683>
01:29:28.851690 IP 10.0.100.21.389 > 10.0.100.22.36157: F 1370:1370(0) ack 214 win 54 <nop,nop,timestamp 217622117 66437823>
01:29:28.851703 IP 10.0.100.22.36157 > 10.0.100.21.389: . ack 1371 win 133 <nop,nop,timestamp 66437823 217622117>
まず、
次に、
注意点としては、
このように、
同期対象エントリの把握
2通りのレプリケーションがあることはわかりましたが、
まずキーワードとなるのはentryCSN
% ldapsearch -x -D "cn=Manager,dc=example,dc=com" -w secret -b "dc=example,dc=com" "objectClass=*" entryCSN # example.com dn: dc=example,dc=com entryCSN: 20090328154606.075631Z#000000#000#000000 # Group, example.com dn: ou=Group,dc=example,dc=com entryCSN: 20090328154606.151415Z#000000#000#000000
内容から容易に想像できるように、
まずは、
このとき、
コンシューマに対する更新要求
同期のタイミングを考慮しないものとすれば、
adding new entry "ou=1238266045,dc=example,dc=com" ldap_add: Server is unwilling to perform (53) additional info: shadow context; no update referral
これは当然のことで、
そのため、
# 更新のためにプロバイダを使用する
updateref ldap://10.0.100.21:389
こうすることによってエラー内容が次のように変わります。
adding new entry "ou=1238266045,dc=example,dc=com" ldap_add: Referral (10) referrals: ldap://10.0.100.21:389/ou=1238266192,dc=example,dc=com
やはりエラーにはなってしまうのですが、
ちなみに、
セキュアなレプリケーション用DN
refreshOnly、
「レプリケーション用にcn=Manager,dc=example,dc=comを使用していますが、
といった記述を見かけます。事実筆者も今まで多くの場合このような解説をしてきました。ですが、
dn: cn=replication,dc=example,dc=com
というDNをレプリケーション専用のDNとすることにしましょう。まずはプロバイダ側でエントリの作成です
dn: cn=replication,dc=example,dc=com
objectClass: person
cn: replication
sn: replication account
userPassword: {SSHA}+cGs2GJzG38V76E3KZIu3W0ZsZWTZTLh
ではいつものようにエントリを登録します。
% ldapadd -x -D "cn=Manager,dc=example,dc=com" -w secret -f replication.ldif adding new entry "cn=replication,dc=example,dc=com"
次に、
access to *
by dn="cn=replication,dc=example,dc=com" write
としてしまっては、
- cn=replication用の権限は全エントリの閲覧のみ
(データ更新の必要はない) - cn=replicationはコンシューマからのみ利用される
(接続元を指定)
を実現することで、
access to attrs=userPassword
by self write
by dn="cn=replication,dc=example,dc=com" peername.ip=10.0.100.22 read
by dn="cn=replication,dc=example,dc=com" peername.ip=0.0.0.0%0.0.0.0 none
by anonymous auth
by * none
access to *
by dn="cn=replication,dc=example,dc=com" peername.ip=10.0.100.22 read
by dn="cn=replication,dc=example,dc=com" peername.ip=0.0.0.0%0.0.0.0 none
by self write
by * read
まとめ
今回はOpenLDAPの基本形となる2通りのレプリケーション方法を解説してきました。2台以上のLDAPサーバを立て、
しかし実際には様々な課題が存在します。まずはこの方式で冗長性を実現させるためには、
uri ldap://接続先1/ ldap://接続先2/
というフォーマットが許可されています。しかし、
それ以外でも、
設定ファイル
今回の設定ファイル全体を貼り付けておきますので、
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
database bdb
suffix "dc=example,dc=com"
rootdn "cn=Manager,dc=example,dc=com"
rootpw secret
directory /var/lib/ldap
loglevel 256
index objectClass eq,pres
index entryCSN,entryUUID eq
access to attrs=userPassword
by self write
by dn="cn=replication,dc=example,dc=com" peername.ip=10.0.100.22 read
by dn="cn=replication,dc=example,dc=com" peername.ip=0.0.0.0%0.0.0.0 none
by anonymous auth
by * none
access to *
by dn="cn=replication,dc=example,dc=com" peername.ip=10.0.100.22 read
by dn="cn=replication,dc=example,dc=com" peername.ip=0.0.0.0%0.0.0.0 none
by self write
by * read
overlay syncprov
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
pidfile /var/run/openldap/slapd.pid
argsfile /var/run/openldap/slapd.args
database bdb
suffix "dc=example,dc=com"
rootdn "cn=Manager,dc=example,dc=com"
rootpw secret
directory /var/lib/ldap
loglevel 256
index objectClass eq,pres
index entryCSN,entryUUID eq
access to attrs=userPassword
by self write
by dn="cn=replication,dc=example,dc=com" peername.ip=0.0.0.0%0.0.0.0 none
by anonymous auth
by * none
access to *
by dn="cn=replication,dc=example,dc=com" peername.ip=0.0.0.0%0.0.0.0 none
by self write
by * read
# 即時レプリケーションを行う場合
syncrepl rid=100
provider=ldap://10.0.100.21:389
type=refreshAndPersist
retry="5 10 300 +"
searchbase="dc=example,dc=com"
bindmethod=simple
binddn="cn=Manager,dc=example,dc=com"
credentials=secret
# 定期的にレプリケーションを行う場合
#syncrepl rid=100
# provider=ldap://10.0.100.21:389
# type=refreshOnly
# interval=00:00:60:00
# searchbase="dc=example,dc=com"
# bindmethod=simple
# binddn="cn=Manager,dc=example,dc=com"
# credentials=secret
updateref ldap://10.0.100.21:389