■OpenLDAPスレーブサーバ構築

OpenLDAPは本来のソースからコンパイルしたものがすでに動作している前提で
下記説明を続けていきます。

構成的にはシングルマスター構成しか行えません。

マスターサーバ一台(データ更新可能)
スレーブサーバ複数台(データ更新不可能)

という構成です。

※マルチマスター構成はソースを書き換えたものが世の中に
 存在するようです。(NTTコム開発)
 将来的にはマルチマスター構成が標準でできるようになると思われます。



[前提]
マスターのslapdサーバが正常に稼動していること。

[準備]
●マスターサーバ

・replicaディレクティブを追記
・replogfileディレクトリを追記

# vi /etc/openldap/slapd.conf

############# FOR REPLICATION#########
replica uri=ldap://10.208.36.166
binddn="cn=replicator,dc=testdom,dc=jp"
bindmethod=simle credentials=secret
replogfile /var/log/replog.log

を追記

# touch /var/log/replog.log
# touch /var/log/replog.log.lock
# chown ldap:ldap /var/log/replog*

●スレーブサーバ
スレーブサーバとなるサーバにopenldapをインストールします。

インストール方法はこちらも参考

まずマスター側のslapd.confを持ってきます。
そちらを編集していく方が同じサーバを作り上げるのに正確なためです。

持ってきたマスター側のslapd.confの中にある
・replicaディレクティブとreplogfileディレクティブを削除
・updatednディレクティブを追記
・updatednで指定したDNが書き込み件を持つようにする
・updaterefディレクティブを追記


上記を行ったらマスターサーバを停止します。

# cp /usr/local/etc/openldap/slapd.conf /usr/local/etc/openldap/slapd.conf.bak
# scp root@masterhost:/etc/openldap/slapd.conf /usr/local/etc/openldap
root@masterhost のパスワード:
slapd.conf 100% |***************************************| 3514 00:00

※ここはftpで持ってきてもどんな手段でもいいので
 マスター側のslapdを持ってきましょう。


# vi /usr/local/etc/openldap/slapd.conf

rootdn "cn=replicator,dc=testdom,dc=jp"
rootpw secret
updatedn cn=replicator,dc=testdom,dc=jp
updateref ldap://10.208.36.166

マスターサーバのslapd.confとの違いは
上記の説明したとおり。
最後にマスター&スレーブのslapd.confをつけておくので参照。

●データのコピー

なぜこの作業が必要かというと

・スレーブにマスターと同じデータベースを持たせる
・マスター&スレーブで起動する
・マスターのデータ更新する
・マスターからスレーブのデータを更新しにいく


というのがマスタースレーブの仕組みなので
スレーブ側にマスターと同じデータが必要ということになります。

なのでどんな手段でもいいので
マスターが停止した時点のデータを取得しスレーブ側に同じデータベースを構築できればよい。
ということです。

実際の作業は

・マスターサーバ上で

# service ldap stop
or
# /etc/init.d/ldap stop

マスターサーバを停止したらすべてのデータベースをスレーブにコピー

・スレーブサーバ上で
3通りほどデータコピーの例としてあげておきます。

# ftp master-server
ftp> cd /var/lib/ldap
ftp> bin
ftp> mget *
ですべて持ってくる

もしくは

slapcatですべてのデータベースをldifに書き出して
slapaddでひとまず追加してしまう。

もしくは

slapcatで取得したすべてのデータベースのldifファイルを
ldapaddに食わせる。

もしくは

・ひとまずスレーブサーバのslapd.confから
 updatednやupdaterefをコメントアウトし
 マスターサーバとして起動する。

・マスターのslapcatで取得したldifファイルを
 ldapadd -x -D "cn=replicator,dc=testdom,dc=jp" -w secret -f ${slapcat.ldif}
 としていつもどおり登録。

・スレーブサーバを停止

などが考えられる。自由にデータコピーは考えてよい。

●マスターサーバとスレーブサーバを起動

・RHEL側
# service ldap start
とするとslapd.confにreplicaの設定をしていると
slurpdも自動で起動してくれます。

# ps aux|grep slapd
# ps aux|grep slurpd
プロセスが起動しているかどうか確認しておききます。

・solaris側
# /usr/local/libexec/slapd -f /usr/local/etc/openldap/slapd.conf
# ps -ef|grep slapd

■実際の設定ファイル

===>マスターサーバ側のslapd.conf<===
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/nis.schema
allow bind_v2
pidfile /var/run/slapd.pid
argsfile /var/run/slapd.args
access to *
by self write
by users read
by anonymous auth
database bdb
suffix "dc=testdom,dc=jp"
rootdn "cn=Manager,dc=testdom,dc=jp"
rootpw secret
directory /var/lib/ldap
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
index uidNumber,gidNumber,loginShell eq,pres
index uid,memberUid eq,pres,sub
index nisMapName,nisMapEntry eq,pres,sub
replica host=slave_server
binddn="cn=replicator,dc=testdom,dc=jp"
bindmethod=simple
credentials=secret
replogfile /var/log/replog.log
===>スレーブサーバ側のslapd.conf<===
include /usr/local/etc/openldap/schema/core.schema
include /usr/local/etc/openldap/schema/cosine.schema
include /usr/local/etc/openldap/schema/inetorgperson.schema
include /usr/local/etc/openldap/schema/nis.schema
allow bind_v2
loglevel 256
pidfile /usr/local/var/run/slapd.pid
argsfile /usr/local/var/run/slapd.args
access to *
by self write
by users read
by anonymous auth
database bdb
suffix "dc=testdom,dc=jp"
rootdn "cn=replicator,dc=testdom,dc=jp"
rootpw secret
directory /usr/local/var/openldap-data
index objectClass eq,pres
index ou,cn,mail,surname,givenname eq,pres,sub
index uidNumber,gidNumber,loginShell eq,pres
index uid,memberUid eq,pres,sub
index nisMapName,nisMapEntry eq,pres,sub
updatedn cn=replicator,dc=testdom,dc=jp
updateref ldap://master_server

今回は
RHELは付属のopenldapを使用。
soalrisはソースからコンパイルしたopenldapを使用。

よってディレクトリの位置などslapd.confが多少環境が異なっていたりします。



●マスターサーバ側でデータ更新

現状の構成としては
dc=testdom,dc=jp
 |
 |--cn=Manager,dc=testdom,dc=jp
 |
 |--ou=people,dc=testdom,dc=jp
 |     |
 |     |--uid=test,ou=testdom,dc=jp
 |--ou=gorup,dc=testdom,dc=jp

となっているものとします。

そういう中でdn: uid=test,dc=testdom,dc=jp
の中にcn属性があるのでそちらを

<変更前>
cn: test
<変更後>
cn: test2

に変更してみます。
その際のログなどを確認します。

<実際の変更前ldif>

###test user
dn: uid=test,ou=people,dc=testdom,dc=jp
uid: test
cn: test
objectclass: posixAccount
objectclass: account
userPassword:{MD5}CY9rzUYh03PK3k6DJie09g==
loginshell: /bin/bash
uidNumber: 10000
gidNumber: 10000
homeDirectory: /var/tmp
gecos: test
description: "Test User"

<実際の変更後ldif>

###test user
dn: uid=test,ou=people,dc=testdom,dc=jp
uid: test
cn: test2
objectclass: posixAccount
objectclass: account
userPassword:{MD5}CY9rzUYh03PK3k6DJie09g==
loginshell: /bin/bash
uidNumber: 10000
gidNumber: 10000
homeDirectory: /var/tmp
gecos: test
description: "Test User"

# ldapmodify -x -h masterhost -D "cn=manager,dc=testdom,dc=jp" -w secret -f /home/share/test.ldif

modifying entry "uid=test,ou=people,dc=testdom,dc=jp"

===>スレーブ側のslapdのログ<===
Apr 15 16:00:59 solaris10 slapd[13659]: [ID 249368 local4.debug] conn=2 op=4 MOD dn="uid=test,ou=people,dc=testdom,dc=jp"
Apr 15 16:00:59 solaris10 slapd[13659]: [ID 396994 local4.debug] conn=2 op=4 MOD attr=uid cn objectClass userPassword loginShell uidNumber gidNumber homeDirectory gecos description entryCSN modifiersName modifyTimestamp
Apr 15 16:00:59 solaris10 slapd[13659]: [ID 588225 local4.debug] conn=2 op=4 RESULT tag=103 err=0 text=

===>マスター側のslapdのログ<===
Apr 18 12:37:25 as4 slapd[6727]: conn=1 fd=14 ACCEPT from IP=127.0.0.1:32825 (IP=0.0.0.0:389)
Apr 18 12:37:25 as4 slapd[6727]: conn=1 op=0 BIND dn="cn=manager,dc=testdom,dc=jp" method=128
Apr 18 12:37:25 as4 slapd[6727]: conn=1 op=0 BIND dn="cn=Manager,dc=testdom,dc=jp" mech=SIMPLE ssf=0
Apr 18 12:37:25 as4 slapd[6727]: conn=1 op=0 RESULT tag=97 err=0 text=
Apr 18 12:37:25 as4 slapd[6727]: conn=1 op=1 MOD dn="uid=test,ou=people,dc=testdom,dc=jp"
Apr 18 12:37:25 as4 slapd[6727]: conn=1 op=1 MOD attr=uid cn objectclass userPassword loginshell uidNumber gidNumber homeDirectory gecos description
Apr 18 12:37:25 as4 slapd[6727]: conn=1 op=1 RESULT tag=103 err=0 text=
Apr 18 12:37:27 as4 slapd[6727]: conn=1 op=2 UNBIND
Apr 18 12:37:27 as4 slapd[6727]: conn=1 fd=14 closed

===>replica/slurp.log<===
replica: 10.208.36.175
time: 1145331445
dn: uid=test,ou=people,dc=testdom,dc=jp
changetype: modify
replace: uid
uid: test
-
replace: cn
cn: test2
-
replace: objectClass
objectClass: posixAccount
objectClass: account
-
replace: userPassword
userPassword:: e01ENX1DWTlyelVZaDAzUEszazZESmllMDlnPT0=
-
replace: loginShell
loginShell: /bin/bash
-
replace: uidNumber
uidNumber: 10000
-
replace: gidNumber
gidNumber: 10000
-
replace: homeDirectory
homeDirectory: /var/tmp
-
replace: gecos
gecos: test
-
replace: description
description: "Test User"
-
replace: entryCSN
entryCSN: 20060418033725Z#000001#00#000000
-
replace: modifiersName
modifiersName: cn=Manager,dc=testdom,dc=jp
-
replace: modifyTimestamp
modifyTimestamp: 20060418033725Z

===>更新時のport389のパケット<===
as4 -> solaris10 LDAP C port=32819 Modify Request Replace
solaris10 -> as4 LDAP R port=32819 Modify Response Success
as4 -> solaris10 LDAP C port=32819

詳細なパケットダンプは実際に取ってみてください。

# ldapsearch -x -D "uid=tes,tou=people,dc=testdom,dc=jp" -h slavehost -b "ou=people,dc=testdom,dc=jp" uid=test -w test

※コマンドが面倒ならLDAP blowserなどを使って確認しましょう。

で実際にcn: test2に変更されていることを確認しましょう。

■更新したタイミングでスレーブが起動していなかった場合
実際に更新する際にマスターは起動しているがスレーブが起動していない場合
なども考えられますが、スレーブが復活した際にマスターから更新に行きます。

■スレーブサーバにデータ更新をしに行った場合

# ldapmodify -h 10.208.36.175 -x -D "uid=test,ou=people,dc=testdom,dc=jp" -w test -f

/home/share/test.ldif
modifying entry "uid=test,ou=people,dc=testdom,dc=jp"
ldap_modify: Referral (10)
        referrals:
                ldap://10.208.36.166/uid=test,ou=people,dc=testdom,dc=jp

となり更新ができずにupdaterefで指定したldapサーバを参照するようメッセージが出ます。

ただrootdnでbindしてスレーブのデータを更新してしまうと更新が可能です。
そうしてしまうと、今度マスターとデータの整合性が取れなくなります。
そしてスレーブで変更した箇所の更新がマスターで行われた場合
マスターからのmodifyがスレーブに反映しません。
よって不整合のままになるのでrootdnでの更新は気をつけて行いましょう。