14. LDAP Sync 複製

LDAP Sync 複製エンジン(略して syncrepl)はコンシューマ側の複製エンジンであり、コンシューマの LDAP サーバが DIT の一部分のシャドーコピーを管理できるようにします。 syncrepl エンジンは slapd (8) のスレッドの1つとしてコンシューマ側に存在しています。syncrepl は複製プロバイダに接続し、初期 DIT 内容をロードした後に定期的な内容の調査かタイムリな変更内容の更新を行うことにより、コンシューマ側の複製を作成/管理します。

syncrepl は 複製同期プロトコルとして LDAP Content Synchronization (略して LDAP Synnc)プロトコルを使います。

syncrepl は push ベースと pull ベースの両方の同期をサポートするステートフルな複製を提供し、更新履歴を使用しません。

syncrepl は同期処理用の cookie を管理/交換することにより、複製内容の状態の軌跡を保持します。 syncrepl のコンシューマとプロバイダはそれぞれ内容の状態を管理しているので、コンシューマはプロバイダの内容を調べることができ、これによりコンシューマの複製がプロバイダの最新の内容と同一になるような関係するエントリを抽出し、差分同期を行います。また、syncrepl は、複製の状態を維持していることにより、複製の適切な管理を可能にしています。コンシューマの複製は、どの同期状態であってもコンシューマ側あるいはプロバイダ側のバックアップから構築できます。 syncrepl は、コンシューマの複製を最新のプロバイダの内容と再同期化できます。

syncrepl は push ベースと pull ベースの両方の同期をサポートします。基本の refreshOnly モードの同期では、プロバイダが pull ベースの同期を利用します。このモードでコンシューマサーバは接続を維持し続ける必要がなく、履歴情報は管理されません。定期的な調査要求を処理するためにプロバイダに要求される情報は、要求自体の同期 cookie に格納されます。 pull ベースの同期の最適化のために、syncrepl は LDAP Sync プロトコルの存在フェーズと削除フェーズを利用し、頻繁な再ロードに頼ることはしません。 pull ベースの同期をさらに最適化するために、プロバイダは履歴の記録としてスコープ単位のセッションログを管理できます。同期の refreshAndPersist モードでは、プロバイダが push ベースの同期を使います。このモードでプロバイダは、永続検索を要求するコンシューマサーバとの接続を維持し、プロバイダの複製対象が更新された場合に必要な更新情報をコンシューマサーバに送ります。

syncrepl を使えば、コンシューマサーバはプロバイダサーバの設定変更も再起動も無しに複製を作成できます。ただし、コンシューマサーバは、DIT のうちの複製対象に対して適切なアクセス権を持っている必要があります。また、コンシューマサーバは、プロバイダ側の変更も再起動も無しに複製を停止できます。

syncrepl は部分複製も疎(sparse)複製の両方をサポートします。複製対象は、ベース、スコープ、フィルタ、属性リストから成る一般的な検索条件によって定義されます。また、複製は syncrepl 複製接続の bind で用いる利用者 ID が持つアクセス権限にしたがいます。

14.1. LDAP Content Synchronization プロトコル

LDAP Sync プロトコルは DIT の断片の同期化された複製をクライアントが保守できるようにします。 LDAP Sync 操作は、LDAP 検索操作を拡張する制御その他のプロトコル要素のセットとして定義されています。この節では、LDAP Content Sync プロトコルについて簡略に説明します。より詳しくは Internet Draft の For more information, refer to the Internet Draft The LDAP Content Synchronization Operation <draft-zeilenga-ldup-sync-05.txt> を参照してください。

LDAP Sync プロトコルは polling と listening の2つの変更をサポートしていて、それぞれの同期操作を定義しています。その同期操作とは refreshOnlyrefreshAndPersist です。 polling は refreshOnly 操作により実現します。クライアントの複製は polling の時間にサーバの複製対象と同期化します。サーバは、検索操作を終了するのに通常の検索と同様に SearchResultDone を返します。listening は refreshAndPersist 操作により実現します。現状で検索条件に一致するエントリすべてを返した後、同期検索を終了するのではなく、サーバで継続させます。その後でサーバの同期対象に更新があると、追加の更新エントリがクライアントに送られます。

refreshOnly 操作と refreshAndPersist 操作のリフレッシュステージは、存在フェーズまたは削除フェーズを実行することがあります。

存在フェーズでサーバは検索スコープ内で直前の同期から更新されたエントリをクライアントに送ります。サーバは、更新されたエントリ中のすべての要求属性と、それが更新されたか否かを送ります。スコープ中の更新されていないエントリについて、サーバはエントリ名と状態が存在であることを示す同期制御から成る存在メッセージを送ります。存在メッセージではエントリの属性に関する情報を送りません。クライアントは更新と存在のメッセージを受け取った後、サーバに追加されたエントリを加え、サーバで更新されたエントリを置換し、更新されていながサーバに存在しないエントリをクライアントから削除することによりクライアントの新しいコピーを確定します。

削除フェーズにおいて、更新されたエントリの転送は存在フェーズと同様です。サーバは検索スコープ内で直前の同期から更新されたエントリの要求された属性をクライアントに送ります。しかし、削除フェーズでは検索スコープ内で削除されたエントリについて削除メッセージを送ります。削除メッセージはエントリ名と削除状態を示す同期制御から成ります。新しいクライアントコピーは、 SearchResultEntry メッセージに付加した同期制御にしたがってエントリを追加、更新、削除することにより確定します。

LDAP Sync サーバが更新履歴を管理していて、クライアントコピーから除外するエントリを判定できるのであれば、サーバは削除フェーズを使います。サーバが更新履歴を管理していなくて、更新履歴からは除外するエントリを判定できるない場合、もしくは更新履歴がクライアントの期限切れの同期状態を扱わない場合、サーバは存在フェーズを使います。存在フェーズの利用は、同期のトラフィックに関していえば完全な内容のリロードに比べてかなり効率的です。さらに同期のトラフックを減らすために、 LDAP Sync プロトコルは、entryUUID を正規化して転送したり、単一の syncIdSet メッセージで複数の entryUUID を転送するといった最適化も実現しています。

refreshOnly 同期の終了時にサーバは、同期が完了した後のクライアントコピーの状態を示すものとして同期 cookie をクライアントに送ります。クライアントは次の同期をサーバに要求するときに、受信した cookie を提示します。

refreshAndPersist 同期を利用する場合、サーバは TRUE refreshDone の Sync Info メッセージを送ることによるリフレッシュステージの終了で同期 cookie を送ります。また、同期検索の永続ステージで生成する SearchResultEntry に同期 cookie を付加して送ります。永続ステージの間、サーバがクライアントサイドの状態を更新したい時点で、サーバは同期 cookie を含んだ Sync Info メッセージを送ることもできます。サーバはまた、永続ステージの終了時にクライアントの同期状態を更新します。

LDAP Sync プロトコルにおいて、エントリは entryUUID 属性値で一意に識別されます。これはエントリの信頼できる識別子として機能します。一方でエントリの DN は経時変化する可能性があるので信頼できる識別子とは認められません。entryUUID は、同期制御の一部として個々の SearchResultEntrySearchResultReference に付加されます。

14.2. syncrepl の詳細

syncrepl エンジンにおいては、LDAP Sync プロトコルの refreshOnlyrefreshAndPersist 操作の両方とも利用できます。データベース定義に syncrepl の指定があれば、slapd (8) は syncrepl エンジンを slapd (8) スレッドとして起動し、その実行をスケジューリングします。 refreshOnly 操作が指定されていれば syncrepl エンジンは同期操作が完了した後に指定の時間間隔で再スケジュールを行います。 refreshAndPersist 操作が指定されていれば、エンジンは動作し続け、プロバイダからの永続同期メッセージを処理します。

syncrepl エンジンにおいては、リフレシュ同期の存在フェーズと削除フェーズのの両方とも利用できます。プロバイダサーバにはスコープ単位のセッションログを設定でき、複製対象から削除された有限個のエントリの entryUUID と名前を記録します。単一のプロバイダ内容に対する複数の複製については同じスコープ単位のセッションログを共有します。 syncrepl エンジンは、このセッションログが存在し、コンシューマサーバの状態が、直前のクライアントの同期後、セッションログのエントリが切捨てられていない程度に十分に新しい場合、削除フェーズを使います。 syncrepl エンジンは、複製対象についてセッションログを設定していない場合、またはコンシューマの複製がセッションログでカバーできないほど古い場合に存在フェーズを使います。セッションログの現在の仕様では情報をメモリに記録するので、セッションログの情報は、複数回のプロバイダ起動の間で引き継がれるようにはなっていません。現在のところ、セッションログに記録されている情報への LDAP 操作でのアクセスはサポートしていません。また、セッションログに対するアクセス制御もサポートしていません。

さらに最適化するために、同期検索がどのセッションログとも関連づけられていない場合であっても、複製対象に何も更新がなければコンシューマサーバにはエントリを何も転送しません。

slapd (8) が LDAP Sync プロバイダとして機能するのは、 back-bdb または back-hdb バックエンドのどちらかに設定されている場合のみですが、コンシューマ側の複製エンジンである syncrepl エンジンは、どのバックエンドでも動作できます。

LDAP Sync プロバイダは各データベースについて、プロバイダの複製対象の現在の同期状態を示すものとして contextCSN を管理しています。 contextCSN の値は、プロバイダの複製対象の中でこれより小さな entryCSN の値を持つエントリに関してトランザクションが未処理で残っていないことを示します。 contextCSN は最後に発行された entryCSN に設定されるわけではありません。なぜなら entryCSN はトランザクションが開始する前に獲得され、この発行順にトランザクションがコミットされるわけでもないからです。

プロバイダは複製対象の contextCSN を DN が cn=ldapsync,<suffix> でオブジェクトクラスが syncProviderSubentry であるエントリの syncreplCookie 属性に格納します。

コンシューマは同期 cookie として受信したプロバイダの複製状態である contextCSN を、DN が cn=syncrepl<rid>,<suffix> でオブジェクトクラスが syncConsumerSubentry であるエントリの syncreplCookie 属性に格納します。この複製状態はコンシューマサーバで管理され、次にプロバイダサーバと増分同期を行うときに同期状態を示すものとして使われます。これはまた、多段の複製設定で第2プロバイダサーバとして機能する場合にプロバイダ側の同期状態として使われます。ここで <rid> は、syncrepl コンシューマサーバの中で一意に複製を識別するための複製IDです。この <rid> は3桁以内の10進数です。

syncrepl の設定では一般的な検索フィルタを指定するので、対象中のすべてのエントリが同期内容として返るわけではありません。そこで syncrepl エンジンは、複製対象の一部に穴がある場合に、グルー(glue)エントリを生成して穴を埋めます。グルーエントリは ManageDsaIT 制御が与えられていない場合には検索の結果をして返りません。

個々のエントリについて、それをベースオブジェクトとし、ベーススコープで LDAP 検索することにより、{EX:syncProviderSubentry}} と syncConsumerSubentry の取得が可能です。

14.3. syncrepl の設定

syncrepl はコンシューマ側の複製エンジンであるので、 syncrepl に関する指定はコンシューマサーバの slapd.conf (5) に設定し、プロバイダサーバには設定しません。複製内容の初期ロードを行うには、同期 cookie 無しで syncrepl エンジンを起動するか、プロバイダでバックアップとしてダンプされている LDIF ファイルをコンシューマに追加して降格します。 slapadd (8)は複製の昇格と降格をサポートします。

バックアップをロードする場合、バックアップしてあるプロバイダの内容は最新のものでなくてもかまいません。syncrepl エンジンは初期のコンシューマの複製をプロバイダの内容と自動的に同期します。したがって、内容のバックアップとロードの処理の間に更新が入って矛盾が発生するのを避けるために、プロバイダサーバを停止する必要はありません。

大規模なディレクトリを複製する場合、特に帯域幅が制限された環境においては、syncrepl を使った完全初期ロードよりも、バックアップからコンシューマ複製をロードするほうを勧めます。

14.3.1. プロバイダ slapd の設定

セッションログディレクティブを除き、特別な slapd.conf (5) ディレクティブはありません。 LDAP 同期検索はアクセス制御に従うので、複製される内容について適切なアクセス権を設定しておきます。

slapadd (8) を使って LDIF ファイルからプロバイダのデータベースを作成する場合、contextCSN とエントリ syncProviderSubentry が作成されなければなりません。 slapadd -p -w は、追加したエントリの entryCSN から新しい contextCSN を作成します。適切な contextCSN 値を持った syncProviderSubentry が LDIF ファイルに直に含まれていれば、その LDIF から作成することもできます。 slapadd -p はプロバイダの contextCSN を維持するか、コンシューマの contextCSN を変更して、複製をプロバイダの内容に昇格します。 slapcat (8) に -m フラグを与えれば LDIF ファイルに syncProviderSubentry を含められます。 slapcat (8) に -k フラグを与えれば LDIF ファイルに syncConsumerSubentry を含められます。

セッションログは次の形式のディレクティブで設定します。

        sessionlog <sid> <limit>

このディレクティブの <sid> はプロバイダサーバにおけるスコープ単位のセッションログの ID です。<limit> はセッションログストアに記録できるセッションログエントリの最大数です。 <sid> は3桁以内の整数です。コンシューマサーバが sid=<sid> を含んだ同期 cookie を送る場合、この <sid> と一致する ID を持ったセッションログストアが LDAP Sync 検索で利用されます。

14.3.2. コンシューマ slapd の設定

syncrepl 複製では、slapd.conf (5) のデータベースセクションで複製対象を設定します。 syncrepl エンジンはバックエンドに依存していないので、データベースの種類によらず定義が可能です。

        syncrepl rid=123
                provider=ldap://provider.example.com:389
                type=refreshOnly
                interval=01:00:00:00
                searchbase="dc=example,dc=com"
                filter="(objectClass=organizationalPerson)"
                scope=sub
                attrs="cn,sn,ou,telephoneNumber,title,l"
                schemachecking=off
                updatedn="cn=replica,dc=example,dc=com"
                bindmethod=simple
                binddn="cn=syncuser,dc=example,dc=com"
                credentials=secret

上記の例で、コンシューマは、プロバイダ slapd ldap://provider.example.com にポート 389 で接続し、1日に1度 polling モード(refreshOnly)の同期を行います。バインドは簡易認証で行い、その際の DN は cn=syncuser,dc=example,dc=com でパスワードは "secret" です。 cn=syncuser,dc=example,dc=com のアクセス権は、複製対象を期待するどおりに取得するために、プロバイダに適切な設定にしておかなければなりません。コンシューマは updatedn= ディレクティブに指定した cn=replica,dc=example,dc=com エントリの権限で、データベースに書き込みます。したがって updatedn エントリは複製を書き込むアクセス権を有している必要があります。

上記の例での同期検索は、dc=example,dc=com をベースとしたサブツリー全体に対し、objectClass が organizationalPerson であるエントリを検索します。取得する属性は cn, sn, ou, telephoneNumber, title, l です。スキーマ検査は無効にしてあるので、コンシューマ slapd (8) はプロバイダ slapd (8) から得た更新情報の処理時にエントリのスキーマ検査を行いません。

syncrepl ディレクティブについてより詳しい説明は、この管理者ガイドの slapd の設定ファイルの章にある syncrepl の節を参照してください。

14.3.3. プロバイダとコンシューマの slapd の起動

プロバイダ slapd (8) は再起動の必要がありません。 contextCSN は必要に応じて自動的に生成されます。つまり、元々 LDIF ファイルに含まれていることもあれば、 slapadd によって生成されることもあり、内容の変更時に生成されることも、プロバイダに対する LDAP Sync 検索で生成されることもあります。

コンシューマ slapd (8) を起動する時には、同期 cookie をコマンドラインオプション -c cookie で与えることができ、これにより特定の状態から同期を開始できます。この cookie には name=value のペアをカンマで区切ったリストを指定します。現在のところサポートしている syncrepl cookie フィールドには csn=<csn>, sid=<sid>, rid=<rid> があります。 <csn> はコンシューマ複製の現在の同期状態を表します。 <sid> は、このコンシューマと関連するプロバイダサーバが持つスコープ単位のセッションログの ID です。 <rid> はコンシューマサーバ内のコンシューマ複製を識別するためのものです。これは、slapd.conf 内の syncrepl 指定から、同じ複製 ID を持った ものを cookie と関係づけるために利用されます。 <sid><rid> も3桁以内の十進数を持ちます。コマンドラインに指定した cookie は、コンシューマ複製データベースに格納された cookie に優先します。