以前から幾つかのコンポーネントで認証を統一したいなあという希望はあった。まっさきに思い浮かぶのは当然LDAPの導入なんだけど、若かりし頃にすべてのストレージエンジンをmysqlに任せたいなんて思う頃があって、openldap+mysql環境を作ってしまってどハマリした経験がある。それ以来、構造が複雑化しがちなLDAPの導入を避けてきたんだけど、最近は扱うミドルウェア数も増えてきて、認証の統一だけでなく、単純にノードを超えたアカウント管理が欲しくなってきた。
そういう訳で久々にopenldapに触る。まずはサーバから。うちの環境は常に2台のサーバでfailsafeな構成を取りたいので、openldapサーバもマルチマスターとして構築する。サーバはldap1とldap2の2台と仮定して、2台同時に同じ作業を進める。必要なパッケージをyumで入れたら、DBの設定をコピーしてサービスを起動し、必要となる設定を投入していく。
yum install -y openldap-servers openldap-clients
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
systemctl start slapd
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
slappasswdで管理用パスワードのhashを生成して、以下のようなdomainの設定を作る。このldifもldapaddで追加する。
slappasswd
New password:
Re-enter new password:
{SSHA}yuOsR/O5bwEyFXRWwRLVq/zcquTMmxnh
cat <<EOF>domain.ldif
dn: olcDatabase={1}monitor,cn=config
changetype: modify
replace: olcAccess
olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth"
read by dn.base="cn=manager,dc=domain,dc=com" read by * none
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=domain,dc=com
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=manager,dc=domain,dc=com
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}yuOsR/O5bwEyFXRWwRLVq/zcquTMmxnh
EOF
ldapadd -Y EXTERNAL -H ldapi:// -f domain.ldif
続いて、同期用のモジュール追加と、ServerIDの設定、そしてレプリの設定を加えていく。
cat<<EOF>sync.ldif
dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib64/openldap
olcModuleLoad: syncprov
EOF
ldapadd -Y EXTERNAL -H ldapi:/// -f sync.ldif
cat<<EOF>server.ldif
dn: cn=config
changetype: modify
replace: olcServerID
olcServerID: 1 ldap://ldap1/
olcServerID: 2 ldap://ldap2/
EOF
ldapmodify -Y EXTERNAL -H ldapi:/// -f server.ldif
cat<<EOF>repli.ldif
dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=ldap://ldap1/ bindmethod=simple
binddn="cn=manager,dc=domain,dc=com"
credentials=xxxxxxxx searchbase="dc=domain,dc=com"
type=refreshAndPersist
retry="5 +"
olcSyncRepl: rid=002 provider=ldap://ldap2/ bindmethod=simple
binddn="cn=manager,dc=domain,dc=com"
credentials=xxxxxxxx searchbase="dc=domain,dc=com"
type=refreshAndPersist
retry="5 +"
-
add: olcMirrorMode
olcMirrorMode: TRUE
EOF
ldapmodify -Y EXTERNAL -H ldapi:/// -f repli.ldif
systemctl restart slapd
2台のサーバにこれらの設定を行えば準備は完了。以下のような初期設定用のldifを用意していずれかのサーバで流してみる。repliがうまくいっていいれば、どちらのサーバでも設定を参照することができるはずだ。
cat<<EOF>inif.ldif
dn: dc=domain,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: domain.com
dc: domain
dn: cn=manager,dc=domain,dc=com
objectClass: organizationalRole
cn: Manager
dn: ou=people,dc=domain,dc=com
objectClass: organizationalUnit
ou: People
dn: ou=group,dc=domain,dc=com
objectClass: organizationalUnit
ou: Group
EOF
ldapadd -x -wxxxxxxxx -D cn=manager,dc=domain,dc=com -f init.ldif
ssh ldap1 ldapsearch -x -LLL -H ldap:/// -b dc=domain,dc=com
ssh ldap2 ldapsearch -x -LLL -H ldap:/// -b dc=domain,dc=com
以上でマルチマスターなLDAPサーバが完成した。久々にやってみたけど、ここまでは意外と簡単。ldapクライアントの設定と各ミドルウェアがLDAPサーバを参照するように設定していく。それを進めていくと構成管理的に複雑化していくんだよなあ。まあ、無理しない程度に適用範囲を広げていってみよう。