QNAPのLDAPのReplicaを作る

[OLCのみで構築するOpenLDAPのReplica (syncrepl)](http://qiita.com/items/f806bc4820ab3d61723e)

今回試したのは QNAP TS-219P ですが、他のシリーズでも基本的に同じようになるのではないかと踏んでます。違ったらごめんなさい。

# QNAP上のプロバイダの準備

まずQNAP上で稼働しているOpenLDAPについてはOLCを一切使っていませんでした。slapd.confを設定します。

＃ 2013-05-20時点で拾えるGPLソースでは2.4.7と2.4.23なのですが、使ってない、と。

モジュールとして syncprov を読み込む必要がありそうと思いきや、組み込まれているようです。おー。コンパイルの必要がないっていいね。

というわけで、QNAP側の設定はわかってしまうと簡単で、以下のように(古風な)設定を書けば動作するようです。

    #######################################################################
    # BDB database definitions
    #######################################################################
    database        bdb
    suffix  dc=imari,dc=in,dc=mokha,dc=co,dc=jp
    rootdn  cn=admin,dc=imari,dc=in,dc=mokha,dc=co,dc=jp
    rootpw  {SSHA}EPBdsDK1pgx6pu8QRT6ymieNcDI8xKx0
    
    checkpoint 1024 30
    # The database directory MUST exist prior to running slapd AND
    # should only be accessible by the slapd and slap tools.
    # Mode 700 recommended.
    directory       /var/openldap-data
    # Indices to maintain
    index   objectClass     eq,pres
    index   uid     eq,pres
    index   uidNumber       eq,pres
    index   gidNumber       eq,pres
    index   memberUid       eq,pres
    index   sambaSID        eq,pres
    index   cn      eq,pres
    index   sn      eq,pres
    
    #### ここから追加 ####
    index   entryCSN eq
    index   entryUUID eq
    
    overlay syncprov
    syncprov-checkpoint     1000    60
    #### ここまで追加 ####

んで、/etc/init.d/ldap_server.sh restart とかやるんですが、こちら、上記の設定ファイルでエラーが出てもこのスクリプト自体ではサーバのリスタートに失敗したことを検知してくれないようです。restartをかけたあと、ちゃんとサーバが生き返っているかはpsなりで確認してあげることです。

## syncprov が動作していることを一応確認する

ところで、前回のOLC+Replicaのときも含めて疑問だったのですが syncprov/syncrepl が正しく動作していることをざっくり簡単に確認する手段があまり見当たらないんですよね。

ここでいう「正しく動作している」というのは、[RFC 4533](http://www.rfc-editor.org/rfc/rfc4533.txt)で規定されてる syncCookie などを、ProviderとConsumer間でやりとりしてrefreshOnlyにおいてきっちり差分だけ取得したり、refreshAndPersistににおいて同期的に取得している、といったお話です。syncprovがない場合でも初回のsearch自体は成功してしまうので、「だいじょうぶかこれー？」とか思ったのです。

ldapsearch等のツールでsyncCookieを見ることが出来ないか試そうとしたんですがちょっと良くわかりませんでした。理想的にはcookie指定してsync動作をコマンドラインでエミュレート出来ると楽しいのですが……。

一応、目に見えてsyncprovが動作していることを確認する方法として、 ldapsearch の -E sync=rp を用いてConsumer側からProvider側にアクセスをかける方法が考えられます。

    # ldapsearch -LLL -H ldap://(hostname) -x -W -D "(QNAP内LDAPのroot DN)" -b "(base DN)" -E sync=rp
    Enter LDAP Password: (パスワード
    dn: ..
    ou: people
    objectClass: organizationalUnit
    
    dn: uid=dmiyakawa,..
    objectClass: top
    objectClass: posixAccount
    objectClass: shadowAccount
    objectClass: person
    objectClass: organizationalPerson
    objectClass: inetOrgPerson
    objectClass: sambaSamAccount
    objectClass: sambaIdmapEntry
    objectClass: apple-user
    cn: dmiyakawa
    uid: dmiyakawa
    uidNumber: 1000000
    userPassword:: ..
    homeDirectory: /home/dmiyakawa
    gecos: Daisuke Miyakawa
    mail: dmiyakawa@mokha.co.jp
    shadowLastChange: 15679
    shadowMin: 0
    shadowMax: 99999
    shadowWarning: 7
    shadowExpire: -1
    shadowInactive: 0
    shadowFlag: 0
    displayName: dmiyakawa
    sambaSID: ..
    sambaLMPassword: ..
    sambaNTPassword: ..
    sambaPasswordHistory: ..
    sambaPwdLastSet: ..
    sambaAcctFlags: ..        ]
    sambaKickoffTime: 0
    gidNumber: 1000000
    sn: Miyakawa
    givenName: Daisuke
    
    ..
    SyncInfo Received

この末尾で判断出来たりします。ここで__SyncInfo Received__と出るか出ないかで、一応ProviderであるQNAP側にsyncprovが組み込まれているかを確認することが出来たようでした。つまり、上述した (slapd.confの)

    index	entryCSN eq
    index	entryUUID eq
    
    overlay	syncprov
    syncprov-checkpoint	1000	60

という部分が存在しない場合には、"SyncInfo"はConsumerに届きません。同期的にアップデートを待つためセッションは残ります。ただ、この状態でQNAP側LDAPでユーザを追加・変更・削除しても、syncprovがオーバーレイされているときには届きますし、そうでないときには届きません。

＃ ログはどこー、という気分でした。QNAP側でOpenLDAPのログを保持してるのは誰なんでしょう..

# Consumer側を設定する

これは前回とあまり変わらないので「頑張れ」、という感じなんですが……

一点注意として、QNAP内のLDAPはSamba関係のLDIFとApple関係のLDIFを追加で入れており、objectClassが通常設定のOpenLDAPより多い点を挙げておく必要はある気がします。これを忘れるとsyncreplがエラーを吐くんですね  (http://itdavid.blogspot.jp/2012/06/howto-openldap-24-replication-on-centos.html)

> syncrepl_message_to_entry: rid=000 mods check (objectClass: value #1 invalid per syntax)
> 
> It means that you're missing a schema in on the consumer server. Of course the rid=000 can be different on your server. It's the replication ID configured in the olcSyncrepl: config of the consumer server. Compare the schemas on both machines and fix the consumer so that it has exactly the same schemas as the provider. So, the first thing you must do is check the schemas on the provider :

このトラブルシューティングがそのまま役に立ちました。

その、Consumer側になさそうな objectClassの部分ですが、上のldapsearchの結果の一部である……

    dn: uid=dmiyakawa,..
    objectClass: top
    objectClass: posixAccount
    objectClass: shadowAccount
    objectClass: person
    objectClass: organizationalPerson
    objectClass: inetOrgPerson
    objectClass: sambaSamAccount
    objectClass: sambaIdmapEntry
    objectClass: apple-user

これな。

この中で、sambaSamAccount、sambaIdmapEntry, apple-user については(おそらく)通常のパッケージインストールで終えた各種ディストリビューションのschemaには入ってません。Ubuntu 12.04 LTSでは少なくとも標準のOpenLDAPスキーマの一部としては含まれませんでした。

対策は例えば[こちら](https://help.ubuntu.com/10.04/serverguide/samba-ldap.html)を参考にして、QNAP内の/etc/openldap/schema/ 下にある関連したschemaファイルを変換してLDIFにしてConsumer側のOpenLDAPサーバに読み込んでおきます。

* [samba.ldif](https://gist.github.com/dmiyakawa/5610863)
* [apple_auxillary.ldif](https://gist.github.com/dmiyakawa/5610867)
* [apple.ldif](https://gist.github.com/dmiyakawa/5610868)

    > sudo ldapadd -Y EXTERNAL -H ldapi:/// -f samba.ldif
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    adding new entry "cn=samba,cn=schema,cn=config"
    
    > sudo ldapadd -Y EXTERNAL -H ldapi:/// -f apple_auxillary.ldif
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    adding new entry "cn=apple_auxillary,cn=schema,cn=config"
    
    > sudo ldapadd -Y EXTERNAL -H ldapi:/// -f apple.ldif
    SASL/EXTERNAL authentication started
    SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
    SASL SSF: 0
    adding new entry "cn=apple,cn=schema,cn=config"

# 疑問

個人的にはrefreshOnlyのCookieを正しく使ってることを確認したいんですよね……手元のOpenLDAPの本でも検証方法は書いてないので「うーん」と唸ってます。一応Replicaとしては動作してはいるようなんですけど。