2016年7月21日

ブロードバンドタワー國武です。

今回は、CentOS7.2 を用いたマルチマスターなLDAPサーバの構築方法について紹介させて頂きます。

目次

基本構成

今回 2台のサーバを

  • ldap1
    • IPv4: 192.0.2.1/24
  • ldap2
    • IPv4: 192.0.2.2/24

として構築します。

事前準備

必要なパッケージのインストール

ldap1, ldap2 の両サーバで実行します。

$ sudo yum -y install openldap-servers openldap-clients

前者が slapd, 後者が ldap操作に関するコマンドセットになっています。

設定ファイルのコピー

CentOS7 から、LDAPのバックエンドデータベースが BDBからHDBに変更されていますが、DB_CONFIG については、標準でついている Berkeley DB用のサンプルがそのまま利用可能なようです。今回はこれを流用します。

$ sudo cp /usr/share/openldap-servers/DB_CONFIG.example \
 /var/lib/ldap/DB_CONFIG
$ sudo chown ldap:ldap /var/lib/ldap/DB_CONFIG
$ sudo chmod 600 /var/lib/ldap/DB_CONFIG

OpenLDAPのデータ自体は、/var/lib/ldap に保存されます。

firewalldの設定

今回、ldap1 と ldap2 の間でマルチマスタ構成を取るので、ldap(389番ポート)を開けておきます。もし LDAPS を使うなら、同様に ldaps(636番ポート)を開けておきます(今回の例では、ldaps の設定はしません)

$ sudo firewall-cmd --add-service=ldap --zone=public
$ sudo firewall-cmd --add-service=ldap --zone=public --permanent

/etc/hosts への登録

ホスト名でアクセスできるように、ldap1, ldap2 を /etc/hosts へ登録しておきます。

192.0.2.1        ldap1
192.0.2.2        ldap2

 

slapd(OpenLDAPサーバ)の起動

ldap1, ldap2 の両サーバで実行します。

$ sudo systemctl start slapd
$ sudo systemctl enable slapd

同期設定

概要

CentOS7ではOpenLDAPをインストールした時点で、標準設定が

  • /etc/openldap/slapd.d/

に入っています。以前は /etc/slapd.conf や /etc/openldap/slapd.conf を利用していましたが、CentOS7 に含まれる OpenLDAPのバージョンでは使われず、このディレクトリ内の設定ファイルが利用されます。しかし直接手動で書き換えることは基本的にできません。設定ファイルの先頭行を眺めると

# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
# CRC32 bcae0ac6

このように、CRC32 による書き換えチェックが走ってます。直接書き換える方法もありますが、openldap-clients パッケージに含まれるユーティリティを用いて修正することが推奨されます。

本文書では、 基本的にLDIF(LDAP Data Interchange Format)を用いて設定していきます。

パスワード設定の準備

slappasswd コマンドを使って LDIFで利用可能な userPassword値を生成します。slappasswd は、入力されたパスワード文字列に対応するハッシュ値を返してくれるコマンドで、直接パスワードを設定するコマンドではありません。利用できる scheme としては

  • {CRYPT}
  • {MD5}
  • {SMD5}
  • {SSHA}
  • {SHA}

が利用可能です。-h “scheme” で指定可能ですが、未指定の場合は、{SSHA} が利用されます。

$ slappasswd
New password:
Re-enter new password:
{SSHA}C6c3gIDtIC/sfoQouOa8roQ8ojineTTJ

ここではパスワードとして “test1234” を打ち込みましたが、SSHAはソルト付のハッシュ関数なのでみなさんの環境とは違ったハッシュ値が得られているかと思います。ここで得られた値は次の項目で利用します。

BaseDN(Suffix)の修正

以降は、ldap1, ldap2 両サーバで実行していきます。初期状態では Suffix が

dc=my-domain,dc=com

で設定されています。ついでなので、ここでは下記に変更してみます。

dn=ldap,dc=example,dc=co,dc=jp

下に挙げたのは、suffix を上記で置き換え、”cn=Manager,dc=ldap,dc=example,dc=co,dc=jp” へパスワードを付与するLDIFです。olcRootPWは、前項で生成した値です。

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=ldap,dc=example,dc=co,dc=jp" read by * none

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=ldap,dc=example,dc=co,dc=jp

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,dc=ldap,dc=example,dc=co,dc=jp

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: {SSHA}C6c3gIDtIC/sfoQouOa8roQ8ojineTTJ

上記内容でテキストファイルを 01_change-domain.ldif として作成し、ldapadd コマンドでLDAPサーバに流し込みます。検索などで設定例を調べると、”{2}bdb,cn=config” となっているものが多いかもしれませんが、前述したように CentOS7 では、bdb から hdb に変更されています。LDIF が正しいと

$ sudo ldapadd -Y EXTERNAL -H ldapi:// -f 01_change-domain.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={1}monitor,cn=config"

modifying entry "olcDatabase={2}hdb,cn=config"

modifying entry "olcDatabase={2}hdb,cn=config"

modifying entry "olcDatabase={2}hdb,cn=config"

のように登録されます。OpenLDAPサーバの初期状態でのACL設定により、この操作にはroot権限が必要です。一般ユーザで実行すると下記のように権限がないと弾かれます。

$ ldapadd -Y EXTERNAL -H ldapi:// -f 01_change-domain.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=1001+uidNumber=1001,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "olcDatabase={1}monitor,cn=config"
ldap_modify: Insufficient access (50)

なお、uidNumber=1001やgidNumber=1001 は、実行したユーザの uid/gid です。

ちなみに LDIFに誤りがあった場合は下記のようなエラーがでます。

$ sudo ldapadd -Y EXTERNAL -H ldapi:// -f xx_badsyntax.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
ldapadd: invalid format (line 4) entry: "olcDatabase={0}config,cn=config"

”:”左側をLDAP属性と呼びますが、よくある誤りは、このLDAP属性を ”:” ごと書き忘れること、LDAP属性名自体を間違えたり、定義されたスキーマにないLDAP属性を書いてしまった場合などでしょうか。

設定の確認は

$ sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" "olcDatabase={1}monitor"
$ sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" "olcDatabase={2}hdb"

で可能です(なお、上記の例では実行結果を省略してあります)

必要モジュールの導入

次に、同期用のレプリケーションモジュールを導入するための LDIF ファイルを作成します(ファイル名を 02_olcModuleLoad.ldif とします)

dn: cn=module,cn=config
objectClass: olcModuleList
cn: module
olcModulePath: /usr/lib64/openldap
olcModuleLoad: syncprov

今回の例では、登録に root 権限が必要です。

$ sudo ldapadd -Y EXTERNAL -H ldapi:// -f 02_olcModuleLoad.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=module,cn=config"

登録確認は下記の通りです。

$ sudo ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" "cn=module{0}"
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib64/openldap
olcModuleLoad: {0}syncprov

ServerIDの設定

次に ServerID を設定していいます。ServerID は、0-4095 までの整数で、それぞれのサーバでユニークである必要があります。ここでは、ldap1 は 1, ldap2 は 2で設定します。

dn: cn=config
changetype: modify
replace: olcServerID
olcServerID: 1 ldap://ldap1/
olcServerID: 2 ldap://ldap2/

上位の内容で 03_olcServerID.ldif  として保存します。反映は下記の通りです。

$ sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f  03_olcServerID.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=config"

設定の投入

いよいよ同期設定を投入します。下記の内容で、04_olcSyncRepl.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=ldap,dc=example,dc=co,dc=jp"
  credentials=test1234 searchbase="dc=ldap,dc=example,dc=co,dc=jp"
  type=refreshAndPersist
  retry="5 5 300 5" timeout=1
olcSyncRepl: rid=002 provider=ldap://ldap2/ bindmethod=simple
  binddn="cn=Manager,dc=ldap,dc=example,dc=co,dc=jp"
  credentials=test1234 searchbase="dc=ldap,dc=example,dc=co,dc=jp"
  type=refreshAndPersist
  retry="5 5 300 5" timeout=1
-
add: olcMirrorMode
olcMirrorMode: TRUE

これを今までと同様に実行します。

$ sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f 04_olcSyncRepl.ldif

ここまで ldap1, ldap2 にエラーなく設定が投入できたでしょうか。いままでの設定で、同期がすでに始まっています。次の項目で、実際にエントリーを投入しています。

同期確認

試しにエントリーを ldap1 から投入してみましょう。testentry.ldif として下記を保存します。

dn: dc=ldap,dc=example,dc=co,dc=jp
objectClass: top
objectClass: dcObject
objectClass: organization
dc: ldap
o: under ldap

dn: cn=Manager,dc=ldap,dc=example,dc=co,dc=jp
objectClass: organizationalRole
cn: Manager
description: Directory Manager

dn: ou=People,dc=ldap,dc=example,dc=co,dc=jp
objectClass: organizationalUnit
ou: People

dn: ou=Group,dc=ldap,dc=example,dc=co,dc=jp
objectClass: organizationalUnit
ou: Group

せっかくなので、cn=Manager 権限で設定を投入してみましょう。

$ ldapadd -x -D "cn=Manager,dc=ldap,dc=example,dc=co,dc=jp" -W -f testent.ldif
Enter LDAP Password:

ここで聞かれるパスワードは、最初に設定したパスワード “test1234” です。パスワードが一致していれば、問題なく投入できたはずです。ldap1, ldap2 のそれぞれで

$ ldapsearch -x -LLL -H ldap:/// -b dc=ldap,dc=example,dc=co,dc=jp

を実行してみてください。両サーバでエントリーが確認できるはずです。なお、ldap2 で設定が確認できなかった場合は、同期に時間がかかっている可能性があります。少しだけ時間を置いてから実行してみください。

参考URL

OpenLDAP Software 2.4 Adinistrator’s Guide 18.3.3. N-Way Multi-Master

本ブログの情報につきましては、自社の検証に基づいた結果からの情報提供であり、
品質保証を目的としたものではございません。

投稿者: Koichi KUNITAKE

XenServerやLinux周りを触ってます。IPv6はボチボチ……