12 Replikation des OpenLDAP-Baums

Bislang haben wir uns eine Umgebung mit einem einzelnen LDAP-Server angeschaut. Das mag in einigen Situationen eventuell genügen. Aber . . .

Image       . . . was machen Sie, wenn der LDAP-Server ausfällt? Wie kritisch ist der jeweilige LDAP-Dienst? Können Sie sich die Zeit bis zu dessen Wiederherstellung leisten?

Image       . . . wenn Sie verschiedene Standorte haben: Sind die Netzwerkverbindungen schnell genug für die Zugriffe eines Clients oder einer Anwendung an einem entfernten Standort auf den lokalen LDAP-Server?

Image       . . . ist ein LDAP-Server genug für die eventuell hohe Anzahl an Anfragen und Zugriffen?

Zu den Beispielen, die wir hier im Buch einrichten und erklären, benötigen Sie weitere Systeme, wenn Sie die einzelnen Schritte nachvollziehen möchten.

In alten Dokumentationen finden Sie oft noch die Begriffe Master und Slave. Diese Begriffe wurden durch Provider und Consumer abgelöst. Dabei geht es nicht nur um die politisch korrekten Begriffe, sondern auch die Funktionen sind heute nicht mehr so eindeutig zu differenzieren.

Der Provider ist heute nicht mehr nur ausschließlich ein System, das Daten zur Verfügung stellt und auf den schreibend zugegriffen werden kann. Es ist vielmehr ein Teil der Aufgabe. Weitere Aufgaben sind das dynamische Erstellen von Gruppen, die Bereitstellung von Zertifikaten und anderen zur Authentifizierung benötigten Informationen. Ein System, das Sie heute als Provider einrichten, kann morgen schon zusätzlich als Consumer dienen.

Der Consumer nimmt im ersten Schritt nur Daten vom Provider entgegen und stellt sie den Clients zur Verfügung. Aber auch der Consumer generiert eventuell dynamische Gruppen aufgrund der Daten, die er besitzt. Ein Consumer kann später auch zusätzlich als Provider fungieren.

Provider und Consumer sind somit nur Dienste, die auch parallel auf demselben System laufen können.

Wir werden hier beginnen mit der einfachen Replikation von einem Provider auf einen Consumer. Für diese Beispiele benötigen Sie einen weiteren, mit den Symas-Paketen ausgerüsteten Server. Der erste, in den vorherigen Kapiteln eingerichtete LDAP-Server wird der Provider werden und der zweite, neue LDAP-Server der Consumer.

Wir werden Ihnen dann zeigen, wie Sie einen Multi-Provider-Cluster aufbauen und erweitern können. Für die Einrichtung des Clusters, inklusive der Erweiterung um zusätzliche Server, benötigen Sie zwei weitere Server, auch auf den Systemen können Sie die Symas-Pakete schon vorinstallieren.

Im letzten Teil werden wir Ihnen dann zeigen, wie Sie Consumer an den Cluster anbinden und wie Sie die Inhalte, die auf Consumer repliziert werden, einschränken können. Für diesen Teil benötigen Sie zwei Consumer. Sie können aber auch erst die eine Variante und dann die andere Variante ausprobieren. Dann benötigen Sie nur einen Consumer.

Um die Funktionalität des Multi-Providers mit mehreren Consumern auszuprobieren, benötigen Sie mindestens drei LDAP-Server, für den vollen Funktionsumfang sind es fünf LDAP-Server.

12.1 Grundlagen zur Replikation

Sie sehen: Sie werden also in der Praxis stets mehr als einen LDAP-Server benötigen. Und damit sind wir beim Thema Replikation. Die einzelnen Kopien einer Datenbank auf den beteiligten Servern müssen identisch gehalten werden. Wir wollen uns in diesem Kapitel die Mechanismen und die einzelnen Replikationsmodelle näher anschauen und umsetzen.

Für die Replikation werden bestimmte Informationen in den Objekten benötigt, dass eine „Absprache“ zwischen Provider und Consumer überhaupt möglich ist. Da wäre einmal die entryUUID, eine eindeutige Nummer, die ein Objekt definiert. Solange ein Objekt im Baum vorhanden ist, behält es seine eindeutige ID. Das zweite wichtige Attribut ist die entryCSN. Diese entryCSN enthält eine Menge an Zeitinformationen, die für die Replikation sehr wichtig sind. Aus diesem Grund werden wir im nächsten Abschnitt genauer darauf eingehen. Jedes Objekt im LDAP-Baum besitzt eine eindeutige entryUUID und einen entryCSN. Beide Attribute sind interne Attribute, die Sie mit einem einfachen ldapsearch nicht angezeigt bekommen. Wenn Sie die internen Attribute eines Objekts sehen wollen, ergänzen Sie Ihre Suchanfrage durch ein + am Ende der Anfrage. Dann erhalten Sie alle internen Attribute angezeigt.

Eins noch: Beide Attribute sind absolut relevant für die Replikation, aus diesem Grund sollte immer ein Index für beide Attribute auf den Providern und Consumern vorhanden sein.

12.1.1 Change Sequence Number

Zunächst benötigen Sie ein Kriterium, um festzustellen, dass sich etwas geändert hat. An dieser Stelle sind Zeitstempel das Mittel der Wahl. Jeder Teilnehmer einer Replikation besitzt einen Zeitstempel mit der letzten Änderung an seiner lokalen Kopie. Nehmen die Teilnehmer Kontakt auf, dann vergleichen sie ihre lokalen Zeitstempel. Ist einer der Teilnehmer aktueller als die anderen, dann teilt er seine Neuigkeiten den anderen Teilnehmern mit. Nehmen wir also zwei Server hostA und hostB. Die beiden haben sich um 13:00 Uhr das letzte Mal untereinander aktualisiert. Um 13:03 Uhr wird eine Änderung an den Daten auf hostB vorgenommen. Um 13:05 Uhr nehmen die beiden Server wieder Kontakt auf, und hostA stellt fest, dass seine Daten veraltet sind. Er bekommt dann von hostB die aktuellen Informationen.

Gut, ganz so simpel ist das mit der Synchronisation zwar nicht. Hier soll erstmal nur das Prinzip der Zeitstempel an sich beleuchtet werden. An die Details arbeiten wir uns langsam heran. Die Zeitstempel haben noch mehr Informationen. Der genaue Aufbau sieht wie folgt aus:

YYYYmmddHHMMSSz.uuuuuu#<Zähler>#<ServerID>#000000

Die einzelnen Parameter dieser als Change Sequence Number (CSN) bezeichneten Zeitstempel sehen Sie in Tabelle 12.1.

Tabelle 12.1 Aufbau einer Change Sequence Number

YYYY

Jahreszahl (0001-9999)

mm

Monat (01-12)

dd

Tag (01-31)

HH

Stunde (00-23)

MM

Minute (00-59)

SS

Sekunde (00-59)

z

der Buchstabe ‚z‘ zu Kennzeichnung der Zeitzone UTC

uuuuuu

Mikrosekunde (000000-999999)

<Zähler>

hexadezimaler Zähler der Änderungen zu dem vorher angegebenen Zeitpunkt

<ServerID>

eindeutige hexadezimale Kennung jedes an der Replikation beteiligten Servers

000000

Wären mehrere Änderungen pro modify-Operation möglich, ließen sich diese an dieser Stelle durchnummerieren. In OpenLDAP ist dieser Wert momentan immer auf 000000, da jede Operation nur eine Änderung enthält.

Die CSN gibt also an, die wievielte Änderung zu einem bestimmten Zeitpunkt auf einem Server aktuell ist. Wir werden im Verlauf des Kapitels noch sehen, an welchen Stellen solche CSNs in der Datenbank auftreten und wie sie bei den einzelnen Replikationsszenarien zum Einsatz kommen. Am Ende des Kapitels finden Sie dann ein praktisches Beispiel, wie Ihnen die CSN beim Troubleshooting helfen kann.

12.1.2 Zeitsynchronisation

Wie Sie am CSN sehen können, ist es kritisch, dass die beteiligten Server einer Replikation eine einheitliche Zeit besitzen. Es ist eine der Achillesfersen der Replikation. Das muss nicht zwingend die Realzeit sein. Die Server müssen sich nur einig sein, wie spät es jetzt gerade ist. Für das Monitoring, eventuelles Auditing sowie das Troubleshooting ist es durchaus sehr sinnvoll, die Serverzeit möglichst identisch mit der tatsächlichen Zeit zu halten. Daher wollen wir uns an dieser Stelle die Zeit nehmen, uns damit zu beschäftigen, wie Ihre Server eine einheitliche und mit der Realzeit identische Zeit bekommen.

Problemsituation

In Situationen mit mehreren beschreibbaren Kopien einer LDAP-Datenbank (siehe dazu Abschnitt 12.1.3, «Serverrollen») kommen Sie bei fehlender Zeitsynchronisation schnell in eine der beiden folgenden Situationen. In beiden Beispielen nehmen wir an, alle Server (bis auf einen) sind sich einig darüber, dass es jetzt 12:00 Uhr ist. Der unsynchronisierte Server hat eine Zeitabweichung von 60 Minuten. An diesem Server (nennen wir ihn Host A) wurde der Nachname eines Benutzerobjekts auf Mayer geändert. An einem anderen Server (Host B) wurde der Nachname auf Meier geändert.

Image       Die Uhr auf Host A ist in der Zukunft.
Für Host A ist es also schon 13:00 Uhr, und die Änderung findet in diesem Moment zunächst in seiner Kopie der Datenbank statt. Diese Änderung wird daher mit diesem Zeitstempel zu allen anderen Servern repliziert. Eine halbe Stunde später fällt auf, dass der Nachname falsch geschrieben wurde und auf Meier geändert werden soll. Diesmal landet die Änderung auf Host B. Dieser verwirft die Änderung allerdings, da er für dieses Attribut einen Zeitstempel von 13:00 Uhr in seiner Datenbank vorfindet, es seiner Zeit nach aber erst 12:30 Uhr ist. Die Änderung kann also frühestens nach weiteren 30 Minuten durchgeführt werden.

Image       Die Uhr auf Host A ist in der Vergangenheit.
Die Uhr auf Host A steht also auf 11:00 Uhr. Diesmal „verliert“ Host A. Findet die Änderung zunächst auf Host B statt (um 12:00 Uhr dessen Zeit), übernimmt Host A diese Änderung in seiner Datenbank mit dem entsprechenden Zeitstempel. Landet die nächste Änderung innerhalb der kommenden 59 Minuten auf Host A, so verwirft er diese, da es für ihn ja noch nicht 12:00 Uhr ist.

Network Time Protocol (NTP)

Sorgen Sie also dafür, dass Sie die Zeit zwischen den Servern synchronisieren. Dafür hat sich in der Praxis das Network Time Protocol (NTP) durchgesetzt.

Dabei gibt es mehrere Abstufungen der Genauigkeit, Stratum genannt. Zeitanbieter vom Stratum 0 (die Zeit) sind dabei die Atom- oder Funkuhren. Diese liefern ihre Zeit an die genauesten NTP-Server vom Stratum 1. Diese haben eine maximale Abweichung von maximal 101 Mikrosekunden zur realen Zeit der Atom- und Funkuhren. Stratum-1-Server geben ihre Zeit an Server vom Stratum 2 weiter. Diese dürfen wiederum eine maximale Zeitdifferenz von 102 Mikrosekunden von ihren Anbietern aufweisen usw. In Bild 12.1 ist die Hierarchie hinsichtlich des Stratums nochmal dargestellt.

Bild 12.1 NTP-Stratum

Das maximale Stratum ist 16. Dieses Stratum ist die ungenaueste Stufe der Zeitsynchronisation. Daher wird dieses Stratum auch als unsynchronized bezeichnet. In diesem Stratum beginnen alle NTP-Clients beim Start des NTP-Dienstes.Nach dem Start versucht der NTP-Dienst nun, sich an den NTP-Server mit dem geringsten Stratum anzunähern. Gelingt es ihm, sich lange genug in der benötigten Genauigkeit zu seinem NTP-Server zu bewegen, darf er das entsprechend nächste Stratum annehmen.

Überlegen Sie sich für Ihre Umgebung, welche NTP-Hierarchie Sie implementieren. Um die Zeitserver im Internet nicht über die Maßen zu belasten, richten Sie sich ein oder zwei Server ein, die sich die Zeit über NTP von außen holen. Diese nutzen Sie dann für die internen Server als NTP-Zeitquelle. Alternativ können Sie natürlich auch Funkuhren in Ihrem Netzwerk einrichten, die das DCF77-Funksignal der Atomuhr der Physikalisch-Technischen Bundesanstalt in Braunschweig über den Langwellensender in Mainflingen empfangen und per NTP angesprochen werden können. Je nach Größe oder Sicherheitsrichtlinien fügen Sie noch weitere Ebenen in Ihrer Synchronisationshierarchie ein. Wie Sie aus den Mechanismen von NTP ersehen, ist auch ein Stratum 3 oder 4 sehr nah an der realen Zeit und genügt in den meisten Umgebungen, solange Sie keine extrem zeitkritischen Anwendungen besitzen.

Grau ist alle Theorie. Jetzt wollen wir uns die grundsätzliche NTP-Einrichtung in der Praxis anschauen. Unter Debian installieren Sie die Pakete ntp sowie ntpdate und konfigurieren den Dienst über die Datei /etc/ntp.conf. Dort können Sie mit dem Parameter server die von Ihnen gewählten NTP-Server oder mit dem Parameter pool einen NTP-Server-Pool wie pool.ntp.org eintragen. Falls die Zeit Ihres Servers zu sehr von der aktuellen Zeit abweicht, können Sie die Zeit vor Start des NTP-Dienstes mit ntpdate <Server> direkt mit der Zeit eines externen Servers abgleichen. Anschließend aktivieren und starten Sie den ntp-Dienst. Befehle wie ntptrace und ntpq geben Ihnen Hilfestellungen bei der Kontrolle des Dienstes. Listing 12.1 zeigt Ihnen die Einrichtung, den Start und die Kontrolle des NTP-Dienstes:

Listing 12.1 Einrichtung von NTP unter Debian

provider01:~# apt-get install ntp ntpdate Reading package lists... Done Building dependency tree Reading state information... Done [...] root@provider01:~# ntpdate -u pool.ntp.org 11 Feb 14:08:40 ntpdate[1006]: adjust time server 176.9.166.35 offset -0.006628 sec provider01:~# grep ^pool /etc/ntp.conf pool 0.debian.pool.ntp.org iburst pool 1.debian.pool.ntp.org iburst pool 2.debian.pool.ntp.org iburst pool 3.debian.pool.ntp.org iburst root@provider01:~# ntptrace -m 1 localhost: stratum 3, offset -0.001700, synch distance 0.018540 root@provider01:~# ntpq -p remote refid st t when poll reach delay offset jitter ========================================================================== 0.debian.pool.n .POOL. 16 p - 64 0 0.000 +0.000 0.000 1.debian.pool.n .POOL. 16 p - 64 0 0.000 +0.000 0.000 2.debian.pool.n .POOL. 16 p - 64 0 0.000 +0.000 0.000 3.debian.pool.n .POOL. 16 p - 64 0 0.000 +0.000 0.000 -45.131.109.21 ( 192.53.103.103 2 u 64 64 37 41.158 -6.103 4.165 *185.232.69.65 ( 79.133.44.136 2 u 63 64 37 20.911 +3.598 5.709 +h2954360.strato 208.90.67.116 3 u 64 64 37 18.761 +3.552 6.080 #chat.k-ten.de 131.188.3.222 2 u 61 64 37 20.042 +4.167 8.380 #vsrv02141.custo 116.203.151.74 3 u 61 64 37 25.122 +5.128 6.647 #bachschmotz.de 192.53.103.108 2 u 64 64 37 42.979 -10.236 5.030 +ntp1.wtnet.de 10.129.9.96 2 u 67 64 37 16.571 +3.940 6.080 -3.uberrider-cdn 185.125.190.58 3 u 66 64 37 19.853 -2.020 5.753 #nono.com 218.73.139.35 2 u 62 64 37 27.674 +5.447 7.079 +server2.as2.ch 129.69.1.153 2 u 67 64 37 26.164 +4.522 6.076 +ntp.creoline.ne 131.188.3.222 2 u 63 64 37 20.226 +2.631 5.815 -time.cloudflare 10.124.8.190 3 u 62 64 37 16.965 +1.160 5.180 #us.ntp.tlercher 228.188.15.147 2 u 61 64 37 102.892 +2.381 155.983 -server1b.meinbe 79.133.44.146 2 u 60 64 37 21.437 +3.467 6.782 -telesto.hot-chi 131.188.3.222 2 u 62 64 37 26.597 +5.135 6.246

(Nach dem Start kann es einige Minuten dauern, bis der Server sein Stratum erreicht hat, und er wird zunächst im Stratum 16 bleiben. Geben Sie ihm Zeit.)

Redhat verwendet das Paket chrony. Die Konfiguration erfolgt über die Datei /etc/chrony.conf ebenfalls über server- und/oder pool-Einträge. Für die Kontrolle des Dienstes können Sie das Tool chronyc nutzen. Listing 12.2 liefert Ihnen die Befehle, die Sie zum Einrichten, Starten und zur Kontrolle des Dienstes benötigen:

Listing 12.2 Einrichtung von Chrony unter CentOS

provider01:~# yum install chrony -y Last metadata expiration check: 3:31:19 ago on Sun Jan 15 12:58:39 2023. Dependencies resolved. [...] provider01:~# grep ^pool chrony.conf pool 2.centos.pool.ntp.org iburst provider01:~# systemctl enable chronyd provider01:~# systemctl start chronyd provider01:~# chronyc tracking Reference ID : D94FB36A (mail.unkn0wn.ch) Stratum : 3 Ref time (UTC) : Sun Jan 15 16:38:58 2023 System time : 0.000057110 seconds slow of NTP time Last offset : +0.000060181 seconds RMS offset : 0.029195314 seconds Frequency : 0.096 ppm fast Residual freq : -0.002 ppm Skew : 0.071 ppm Root delay : 0.041319627 seconds Root dispersion : 0.010151371 seconds Update interval : 1027.4 seconds Leap status : Normal provider01:~# chronyc sources 210 Number of sources = 4 MS Name/IP address Stratum Poll Reach LastRx Last sample ============================================================================= ^+ ntp-gps.beuth-hochschule> 2 10 377 268 -1247us[-1186us] +/- 42ms ^* mail.unkn0wn.ch 2 10 377 107 +855us[ +916us] +/- 45ms ^+ s2.eideo.de 3 10 377 26m +3323us[+3391us] +/- 82ms ^+ twilight.domainfactory.de 3 10 377 625 -351us[ -288us] +/- 57ms

Image

Tipp: Für NTP und Chrony existieren zusätzliche Sicherheitsmechanismen und Konfigurationsmöglichkeiten. Die würden an dieser Stelle den Rahmen sprengen. Konsultieren Sie dazu die Manuals der einzelnen Befehle und Dateien.

Image

Sie sollten nach der Einrichtung auch auf den korrekten Betrieb Ihrer NTP-Synchronisation achten und diese möglichst überwachen (zum Beispiel mit Munin). Mehr zum Thema Überwachung finden Sie in Kapitel 17, «Monitoring mit Munin».

12.1.3 Serverrollen

Betrachten wir noch die möglichen Rollen, die ein LDAP-Server bei einer Replikation spielen kann: Provider und Consumer – der eine bietet Daten an, der andere nutzt diese. Bild 12.2 stellt die beiden Serverrollen noch einmal dar:

Bild 12.2 Serverrollen bei der Replikation

Image       Provider
Der Provider besitzt entweder eine beschreibbare oder schreibgeschützte Replik der Datenbank. Er repliziert seine Datenbank zu einem oder mehreren Consumern. Ein Provider kann auch für mehrere Datenbanken verantwortlich sein.

Image       Consumer
Der Consumer besitzt eine schreibgeschützte Kopie der Datenbank seines Providers. Er kann allerdings wieder als Provider für weitere Consumer auftreten.

In Bild 12.3 wird eine Situation mit mehreren Servern dargestellt:

Bild 12.3 Provider und mehrere Consumer

In der Praxis werden etwa 90% der Zugriffe reine Lesezugriffe sein. Daher genügt es in den meisten Umgebungen, einen Provider- sowie einen oder mehrere Consumer-Server einzusetzen. Für die Authentifizierung der Clients empfiehlt es sich zudem, diesen einen Consumer-Server zuzuweisen. Damit entlasten Sie den Provider, schützen Ihre Datenbank und erhöhen somit die Sicherheit Ihrer Umgebung. Wenn Sie dann noch zwischen Provider und Consumer eine Firewall setzen, ist der Schutz Ihrer Daten noch besser.

12.1.4 Replikationsumfang

Bei der Einrichtung der Replikation können Sie auswählen, welche Daten Sie von einem Provider auf welche Ihrer Consumer replizieren wollen. Diese Einschränkung kann auf Kontext-, Objekt- oder Attributsebene erfolgen. So können Sie durch die Einrichtung entsprechender LDAP-Filter bestimmen, dass nur die Objekte aus einer bestimmten organisatorischen Einheit, nur Objekte einer bestimmten Klasse oder nur ausgewählte Attribute repliziert werden sollen. Dies kann beispielsweise sinnvoll sein, wenn Sie einen LDAP-Server einsetzen wollen, auf welchen Ihre Telefoniesoftware oder Ihr Mailserver zugreifen soll. Damit können Sie das Replikationsvolumen und somit die Server- und Netzwerklast beschränken und erhöhen zusätzlich noch die Sicherheit Ihrer Daten, denn eine Telefonanlage, die Adressen aus dem LDAP ausliest, benötigt nicht die Passwörter der Benutzer. Eine zweite Möglichkeit, die Daten der Replikation einzuschränken, ist der Einsatz von ACLs und unterschiedlichen Replikationsbenutzern. Wir werden hier im Buch beide Wege aufzeigen und die Vor- und Nachteile ansprechen.

12.2 Replikationsmethoden

In diesem Abschnitt lernen Sie die drei verschiedenen Methoden kennen, die zwei Server für die Replikation nutzen können:

Image       refreshOnly

Image       refreshAndPersist

Image       DeltaSync

Egal für welche Methode Sie sich in Ihrer Umgebung entscheiden, eine Gemeinsamkeit gibt es: Auf dem oder den Servern, welche später als Provider arbeiten sollen, muss das in Kapitel 10, «Erweiterte Funktionen durch Overlays», beschriebene Overlay syncprov eingerichtet werden. Dieses aktiviert die sogenannten contextCSN, also den Zeitstempel für das Wurzelobjekt der jeweiligen Datenbank. Diese Information wird benötigt, damit Provider und Consumer feststellen können, ob sich Daten innerhalb der Datenbank geändert haben oder ob beide Datenbanken noch den gleichen Stand aufweisen. Außerdem benötigt der Consumer einen Benutzer zur Authentifizierung beim und zur Autorisierung gegenüber dem Provider, um Daten aus dessen Datenbank auszulesen und in seine Datenbank replizieren zu können. In Bild 12.4 sind die Voraussetzungen für die Replikation schematisch dargestellt:

Bild 12.4 Voraussetzungen für die Replikation

Die contextCSN wird immer im Arbeitsspeicher gepflegt und auch nur dort geändert. Nur wenn der LDAP-Dienst ordnungsgemäß angehalten wird, wird die contextCSN gespeichert und beim nächsten Neustart gelesen. Wird der Dienst abgebrochen oder stürzt der Server ab, wird keine contextCSN geschrieben. Kann beim Start des LDAP-Diensts keine contextCSN gelesen werden, wird eine neue auf Grundlage aller Informationen der Datenbank gebildet. Die Dauer dieses Vorgangs ist abhängig von der Anzahl der Objekte im Baumund kann in großen Bäumen schon mal mehrere Minuten dauern.

12.2.1 LDAP Synchronization Replication – Die vollständige Replikation

Haben Sie alle technischen Voraussetzungen getroffen, stehen zwei Modelle der Replikation zur Wahl. Wir schauen uns zuerst die vollständige Replikation zwischen Provider und Consumer an. In vielen LDAP-Dokumentationen ist diese auch unter der Bezeichnung LDAP Synchronization Replication oder kurz SyncRepl zu finden. Hierbei wird bei einer Änderung an einem Attribut eines Objekts das gesamte Objekt (also auch die nicht geänderten Attribute) vom Provider zum Consumer übertragen.

Nehmen wir als Beispiel einen Benutzer John Doe, momentan wohnhaft in Kiel. Diesen zieht es aus Kiel an der Ostsee nach Ostwestfalen, genauer nach Bielefeld. Die Änderung am Benutzerobjekt sehen Sie in Bild 12.5:

Bild 12.5 Änderung eines Objektattributs

Bei der vollständigen Replikation wird nun das gesamte Objekt von John Doe vom Provider zum Consumer übertragen, wie auch in Bild 12.6 dargestellt:

Bild 12.6 Replikation des gesamten Objekts mit SyncRepl

Es gibt zwei unterschiedliche Varianten dieser Methode: refreshOnly und refresh And-Persist. Diese wollen wir uns nun etwas näher anschauen.

12.2.2 refreshOnly

Bei der refreshOnly-Methode kontaktiert der Consumer regelmäßig seinen Provider und bittet ihn um ein Auffrischen seiner Datenbank. Anschließend wird die Verbindung wieder beendet. Im Einzelnen sehen die Schritte wie folgt aus:

1.      Zu Beginn authentifiziert sich der Consumer beim Provider und baut eine Verbindung auf.

2.      In nächsten Schritt sendet der Consumer seinen aktuellen Stand in Form eines sogenannten SyncCookies an den Provider. Dieses SyncCookie beinhaltet in der Hauptsache die erwähnte contextCSN (also den Zeitstempel der letzten Änderung) des Consumers der jeweiligen Datenbank. Ebenfalls gesendet wird eine Suchanfrage nach Objekten. Diese kann entweder den ganzen Baum der Datenbank oder nur einzelne Kontexte, Objektklassen und/oder Attribute enthalten.

3.      Der Provider vergleicht den contextCSN des Consumers mit seinem eigenen und stellt fest, ob es Änderungen innerhalb der Datenbank gegeben hat.

4.      In der nun eventuell folgenden present phase werden dem Consumer folgende Informationen gesendet:

Image       sämtliche Attribute der geänderten Objekte, unabhängig davon, ob der Consumer diese schon hat oder nicht,

Image       DNs und UIDs aller nicht geänderten Objekte,

Image       keinerlei Informationen zu den gelöschten Objekten.

5.      Sind Objekte zu löschen, beginnt der Provider noch die delete phase. In dieser sendet er dem Consumer die UIDs und zugehörigen DNs der zu löschenden Objekte.

6.      Schließlich sendet der Provider nun noch die aktuelle contextCSN sowie die Meldung SearchResultDone.

7.      Der Consumer beendet daraufhin die Verbindung.

In Bild 12.7 ist die Methode nochmal skizziert:

Bild 12.7 Schematische Darstellung der refreshOnly-Replikation

Diese Methode ist ein bisschen so, als würden Sie einmal in der Woche Ihre mitteilungsbedürftigen Bekannten anrufen und fragen, was es denn bei ihr bzw. ihm und seiner Familie so alles Neues gab, und sie bzw. er erzählt Ihnen dann über jeden, zu dem es etwas zu erzählen gibt . . . nicht nur, was es Neues gibt, sondern die ganze Lebensgeschichte. Alle anderen werden zumindest mit Namen erwähnt.

Die Replikation muss sich dabei nicht über die gesamte Datenbank erstrecken. Über die herkömmlichen LDAP-Suchfilter können Sie die Replikation auf einen Teil der Datenbankeinschränken, beispielsweise nur auf bestimmte Objektklassen oder Objekte mit bestimmten Eigenschaften (von Ihrem bzw. Ihrer Bekannten wollen Sie vielleicht nur die Neuigkeiten aller Familienmitglieder aus Norddeutschland oder Ostwestfalen hören).

Einrichtung

Zunächst muss auf dem Server, welcher als Provider dienen soll, das Overlay syncprov für alle zu replizierenden Datenbanken eingerichtet werden. Blättern Sie dazu noch einmal zurück in Kapitel 10, «Erweiterte Funktionen durch Overlays». Damit liefert der Provider die nötigen Informationen für die Replikation.

Für die Konfiguration des Overlays sieht die entsprechende LDIF-Datei so wie in Listing 12.3 aus:

Listing 12.3 Laden des syncprov-Moduls für refreshOnly

# Laden des syncprov-Moduls dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: syncprov.la # Overlay für LDAP-Datenbank und -Konfiguration aktivieren dn: olcOverlay=syncprov,olcDatabase={2}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpSessionlog: 300

Im ersten Teil wird das benötigte Modul für das Overlay geladen, und im zweiten Teil wird das Overlay für die gewünschte Datenbank eingerichtet. Jede Datenbank, die Sie auf einem Provider für Consumer bereitstellen wollen, benötigt eine eigene Konfiguration des Overlays. Aus diesem Grund ist es sehr wichtig, dass Sie auf die Nummer der Datenbank achten. Da wir hier die Objektdatenbank replizieren wollen, handelt es sich bei uns um die Datenbank mit der Nummer 2.

In diesem Beispiel wird einer der Parameter für das syncprov-Overlay explizit gesetzt: olcSpSessionLog. Dieser Wert bestimmt, wie viele Datenbankänderungen der Provider in seinem Sitzungsprotokoll vorhält. Diesen Wert sollten Sie so hoch setzen, dass auch der langsamste Ihrer Consumer immer alle nötigen Änderungen erhält: In Listing 12.9 werden Sie sehen, dass sich ein Consumer in bestimmten Zeitabständen beim Provider meldet, um nach Änderungen zu fragen. Meldet er sich beispielsweise nur einmal in der Stunde und sind in dieser Zeit 200 Änderungen geschehen, aber das Protokoll fasst nur 150 Einträge, bleiben die 50 ältesten Änderungen für den Consumer verborgen, gehen aber nicht verloren. Die LDAP-Server werden eine neue vollständige Replikation durchführen. Je nach Größe der Datenbank kann dieser Vorgang die Systeme stark belasten. Überlegen Sie, wie viele Änderungen bei Ihnen in der Zeit zwischen zwei Replikationszyklen anfallen, und setzen Sie den Wert entsprechend.

Als Nächstes wird ein Benutzer benötigt, welcher genug Rechte besitzt, um auf die zu replizierenden Objekte zugreifen zu können, sprich: Leserechte auf alle zu replizierenden Objekte und Attribute in der Datenbank. An dieser Stelle wollen wir auf jeden Fall die gesamte Datenbank mit allen Attributen replizieren. Später werden wir Ihnen zeigen, wie Sie die Objekte und Attribute, die repliziert werden sollen, einschränken können.

Als Benutzer wird hier wieder ein simpleSecurityObject erstellt. Einen solches Objekt können Sie beispielsweise mit folgender LDIF-Datei aus Listing 12.4 erstellen:

Listing 12.4 Benutzer für die Synchronisation einrichten

dn: uid=repl-user,ou=users,dc=example,dc=net objectClass: account objectClass: simpleSecurityObject objectClass: top uid: repl-user userPassword: {ARGON2}$argon2i$v=19$m=4096,t=3,p=1$c2Fs...

Image

Wichtig: Der Benutzer für die Replikation sollte keiner Kennwortrichtlinie unterliegen, welche eine regelmäßige Kennwortänderung erfordert. Ansonsten wird dieses Konto sich irgendwann nicht mehr authentifizieren können, sobald das Kennwort abgelaufen ist. Die Replikation wird dann fehlschlagen. Alternativ müssen Sie regelmäßig das Kennwort und die Einstellungen Ihrer Synchronisation ändern. Sinnvoller ist daher eine eigens für diesen Benutzer erstellte Kennwortrichtlinie.

Image

Dieser Benutzer benötigt jetzt noch das Leserecht an allen Objekten und Attributen, um die gesamte Datenbank zu replizieren. In Kapitel 9, «Berechtigungen mit ACLs», haben wir schon komplexe ACLs für den Provider eingerichtet. In Listing 12.5 noch einmal eine Übersicht über die ACLs:

Listing 12.5 Übersicht über alle ACLs

olcAccess: {0}to dn.exact=dc=example,dc=net by users read olcAccess: {1} to attrs=userPassword by anonymous auth by self write by dn.exact=uid=ldap-admin,ou=users,dc=example,dc=net write by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by set="[cn=pw-set,ou=groups,dc=example,dc=net]/Member* & user" write by * none olcAccess: {2} to attrs=shadowLastChange by anonymous auth by self write by dn.exact=uid=ldap-admin,ou=users,dc=example,dc=net write by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by set="[cn=pw-set,ou=groups,dc=example,dc=net]/Member* & user" write by * none olcAccess: {3}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by dn.exact=uid=sssd-user,ou=users,dc=example,dc=net read by dn.exact=uid=ldap-admin,ou=users,dc=example,dc=net write by dn.exact=uid=lam-user,ou=users,dc=example,dc=net read by * break olcAccess: {4} to dn.exact="cn=u1 verw,ou=users,ou=verwaltung,ou=firma,\ dc=example,dc=net" by peername.regex=192\.168\.56\.201 read by peername.regex=192\.168\.56\.12 read by * none olcAccess: {5} to dn.regex=ou=adressen,cn=(.+),ou=users,ou=(.+),\ ou=firma,dc=example,dc=net filter=(objectClass=posixAccount) by dn.regex=cn=(.+),ou=users,ou=(.+),ou=firma,dc=example,dc=net read by * break olcAccess: {6}to dn.regex="ou=adressen,cn=(.+),ou=users,ou=(.+),\ ou=firma,dc=example,dc=net$" by dn.regex="$1,ou=users,ou=$2,ou=firma,dc=example,dc=net$" write by * none olcAccess: {7}to dn.sub=ou=verwaltung,ou=firma,dc=example,dc=net by set="this/manager & user" write by set="this/manager/secretary & user" \ write by "dn.children=ou=users,ou=verwaltung,ou=firma,dc=example,dc=net" read by * none olcAccess: {8}to dn.sub=ou=produktion,ou=firma,dc=example,dc=net by set="this/manager & user" write by set="this/manager/secretary & user" \ write by "dn.children=ou=users,ou=produktion,ou=firma,dc=example,dc=net" read by * none olcAccess: {9}to "dn.exact=ou=firma,dc=example,dc=net" by users read by * none

Welche ACLs benötigen denn eine Änderung? Alle, die die Rechte des Replikationsbenutzers einschränken. Wie können Sie jetzt ermitteln, welche ACLs das sind? Gehen Sie die Liste der ACLs der Reihe nach durch, um die benötigten Änderungen zu finden.

Image       olcAccess: 0to dn.exact=dc=example,dc=net
Diese ACL muss nicht geändert werden, denn der Replikationsbenutzer meldet sich an und kann somit auf die oberste Ebene zugreifen.

Image       olcAccess: 1 to attrs=userPassword
Da die Benutzer sich später auch gegen den Consumer authentifizieren können sollen, werden alle Daten für die Passwörter auch auf allen Consumern benötigt. Somit ist es auf jeden Fall notwendig, diese ACL so anzupassen, dass der repl-user das Leserecht bekommt.

Image       olcAccess: 2 to attrs=shadowLastChange
Das Attribut wird auch auf allen Consumern benötigt, um feststellen zu können, wann ein Benutzer das letzte Mal sein Passwort geändert hat. Also muss auch hier der repluser an diesem Attribut das Leserecht erhalten.

Image       olcAccess: 3to *
Hier werden die Rechte für den gesamten Rest des Baums vergeben. Wenn Sie hier dem repl-user das Leserecht geben, kann der repl-user den gesamten Baumlesen und somit auch replizieren.

Image       olcAccess: 6to dn.regex=öu=adressen,cn=(.+),ou=users,ou=(.+),ou=firma,dc=example, dc=net$"
Wenn Sie vergessen, dem repl-user das Leserecht an den privaten Adressbüchern der Mitarbeiter zu geben, dann werden diese aufgrund fehlender Rechte nicht repliziert.

Nach der ACL mit der Nummer 6 sind alle anderen ACLs für den repl-user nicht mehr relevant. Listing 12.6 zeigt alle Änderungen:

Listing 12.6 Alle ACL-Änderungen für den repl-user

changetype: modify delete: olcAccess olcAccess: {6} - delete: olcAccess olcAccess: {3} - delete: olcAccess olcAccess: {2} - delete: olcAccess olcAccess: {1} - add: olcAccess olcAccess: {1}to attrs=userPassword by anonymous auth by self write by dn.exact=uid=ldap-admin,ou=users,dc=example,dc=net write by dn.exact=uid=repl-user,ou=users,dc=example,dc=net read by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by set="[cn=pw-set,ou=groups,dc=example,dc=net]/Member* & user" write by * none - add: olcAccess olcAccess: {2} to attrs=shadowLastChange by anonymous auth by self write by dn.exact=uid=ldap-admin,ou=users,dc=example,dc=net write by dn.exact=uid=repl-user,ou=users,dc=example,dc=net read by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by set="[cn=pw-set,ou=groups,dc=example,dc=net]/Member* & user" write by * none - add: olcAccess olcAccess: {3} to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by dn.exact=uid=sssd-user,ou=users,dc=example,dc=net read by dn.exact=uid=ldap-admin,ou=users,dc=example,dc=net write by dn.exact=uid=repl-user,ou=users,dc=example,dc=net read - add: olcAccess olcAccess: {6}to dn.regex="ou=adressen,cn=(.+),ou=users,ou=(.+),\ ou=firma,dc=example,dc=net$" by dn.regex="$1,ou=users,ou=$2,ou=firma,dc=example,dc=net$" write by dn.exact=uid=repl-user,ou=users,dc=example,dc=net read by * none

Testen Sie nach dem Einspielen der Änderung, ob der repl-user wirklich alle Daten lesen kann. Am einfachsten können Sie das mit dem Kommando ldapsearch realisieren. Erst wenn der repl-user wirklich alle benötigten Daten lesen kann, können Sie mit der Einrichtung der Replikation fortfahren.

Sorgen Sie dafür, dass der Replikationsbenutzer auch alle Objekte lesen kann. In der Grundkonfiguration haben wir den Wert für searchLimit auf 500 festgelegt. Dieser Wert gilt für alle Benutzer außer für den rootdn. Wenn Sie das Limit für den Replikationsbenutzer nicht anpassen, werden immer nur die ersten 500 Objekte repliziert. In Listing 12.7 sehen Sie die Änderungen, die Sie benötigen:

Listing 12.7 Anpassen des Limits

dn: olcDatabase={2}mdb,cn=config changetype: modify add: olcLimits olcLimits: dn.exact="cn=uid=repl-user,ou=users,dc=example,dc=net" time=unlimited size=unlimited

Die folgenden Schritte sind für die Einrichtung des Consumers notwendig:

Image       Installieren Sie die identischen OpenLDAP-Pakete wie schon auf dem Provider.

Image       Spielen Sie dieselbe Grundkonfiguration wie die des Providers ein.

Image       Erstellen Sie die Zertifikate für den LDAP-Server und fügen die TLS-Parameter zur Konfiguration hinzu.

Image       Spielen Sie die ACLs ein, die Sie benötigen. Da der Provider und der Consumer identisch seien sollen, übernehmen Sie die ACLs vom Provider.

Image       Achten Sie darauf, dass auf dem Provider und dem Consumer die identischen Indexeinträge vorhanden sind.

Um die Replikation zu optimieren, ist es sinnvoll, dass Sie Ihrer Datenbank noch einen Index über die Attribute entryUUID und entryCSN hinzufügen. Für die OLC-Konfiguration erreichen Sie dies mit der LDIF-Datei aus Listing 12.8:

Listing 12.8 OLC-Eintrag für die Indexierung der Datenbank

dn: olcDatabase={2}mdb,cn=config changetype: modify add: olcDbIndex olcDbIndex: entryUUID,entryCSN eq

Fügen Sie die Indizes auf allen Providern und Consumern zur Objektdatenbank hinzu.

Image

Tipp: Wenn Sie die Replikation im Log verfolgen wollen, fügen Sie das Loglevel sync sowohl auf dem Provider als auch auf dem Consumer zur Konfiguration hinzu. Wenn Sie dann auf beiden Systemen das Log mit journalctl -f -u symas-openlap-server.service öffnen und dann erst die nachfolgende Änderung einspielen, können Sie die Replikation genau verfolgen (in unserer Grundkonfiguration ist das Loglevel schon enthalten).

Image

Jetzt ist es soweit, Sie können die Replikation auf dem Consumer einrichten. Ein Beispiel für die LDIF-Datei finden Sie in Listing 12.9:

Listing 12.9 Konfiguration für den Consumer (refreshOnly)

dn: olcDatabase={2}mdb,cn=config changetype: modify add:olcSyncrepl olcSyncrepl: rid=000 provider=ldaps://provider01.example.net type=refreshOnly interval=00:00:05:00 retry="60 10 120 5" searchbase="dc=example,dc=net" filter="(objectClass=*)" scope=sub schemachecking=off bindmethod=simple binddn="uid=repl-user,ou=users,dc=example,dc=net" credentials=geheim

Sie sehen, es handelt sich bei der Konfiguration nur um ein einzelnes zusätzliches Attribut, welches als Wert diverse Konfigurationsparameter enthält: olcSyncrepl. Denn der Open-LDAP interpretiert die gesamte Syncrepl-Direktive als eine Zeile. Auch hier ist es wichtig, dass Sie nach einem Zeilenumbruch zwei Leerzeichen an den Anfang der nächsten Zeile stellen. Das erste Leerzeichen ist der Zeilenumbruch, das zweite, das Trennzeichen zwischen den Wörtern. Zu den Parametern im Einzelnen:

Image       rid
Diese dreistellige ID muss auf dem Consumer lokal eindeutig sein und bezeichnet eine lokal replizierte Datenbank. Besitzt der Consumer mehrere replizierte Datenbanken, so benötigen diese eindeutige IDs. Haben Sie mehrere Consumer, können die IDs auf allen Consumern unterschiedlich sein. Es empfiehlt sich aber, die IDs auf allen Consumern identisch zu halten. Das macht die Sache übersichtlicher.

Image       Provider
Hier geben Sie die URI des Providers der Datenbank an.

Image       type
Die Art der Replikation: in diesem Fall refreshOnly.

Image       interval
Das Intervall, in welchem der Consumer den Provider für eine Abfrage des aktuellen Stands der Datenbank kontaktiert. Die Angabe erfolgt in der Form dd:hh:mm:ss, also Tage:Stunden:Minuten:Sekunden, im vorliegenden Beispiel also alle fünf Minuten.

Image       retry
Sollte der Provider beim Versuch einer Replikation nicht erreichbar sein, können Sie hier angeben, wie oft und in welchen Zeitabständen der Consumer einen Versuch unternimmt, den Provider zu erreichen. Im angegebenen Beispiel versucht er es in einem Intervall von 60 Sekunden höchstens 10 mal, anschließend startet er im Abstand von 120 Sekunden 5 weitere Versuche. Das Symbol + statt der Anzahl der Versuche steht für beliebig oft. Bei einem Eintrag von retry="60 10 120 +" würde es der Consumer also nach den ersten 10 Fehlversuchen alle 120 Sekunden beliebig oft versuchen, den Provider zu erreichen.

Image       searchbase
Tragen Sie hier den Kontext innerhalb der Datenbank ein, in welchem sich die zu replizierenden Objekte befinden.

Image       scope
Liegen die zu replizierenden Objekte nur in dem unter searchbase angegebenen Kontext oder auch darunter, so geben Sie hier base, one oder sub (der Standardwert) an.

Image       filter
An dieser Stelle können Sie über einen LDAP-Suchfilter diejenigen Objekte bestimmen, welche zu diesem Consumer zu replizieren sind, also beispielsweise nur Benutzerobjekte, bei denen die Telefonnummer mit einem Wert belegt ist. Wir wollen hier alles replizieren, deshalb setzen wir den Filter auf objectClass=*. Da alle Objekte mindestens eine Objektklasse besitzen, werden auch alle Objekte repliziert.

Image       schemachecking
Setzen Sie diesen Parameter auf on, so wird jeder replizierte Wert eines Attributs gegen das lokale Schema geprüft.

Image       bindmethod
In unserem Beispiel wird die einfache Methode simple bind der Authentifizierung ausgewählt. Sie haben an dieser Stelle auch die Möglichkeit, sasl einzutragen und Methoden wie GSSAPI oder Kerberos zu nutzen.

Image       binddn
Geben Sie hier Ihren (Replikations-) Benutzer an, welcher sich am Provider authentifiziert, um die zu replizierenden Daten zu lesen.

Image       credentials
Für die Anmeldung tragen Sie hier die entsprechenden Anmeldeinformationen des unter binddn festgelegten Benutzers ein. Das Kennwort kann hier nur im Klartext eingetragen werden, da es sich hier um ein simple bind handelt.

In unserem Beispiel findet die Replikation verschlüsselt über das Protokoll LDAPS statt. Das geht nur, da auf dem Provider TLS eingerichtet ist und der Consumer das root-Zertifikat kennt.

Sollten Sie bei der Replikation die Fehlermeldung err=32 object not found erhalten, prüfen Sie noch einmal, ob der repl-user alle Rechte an der Datenbank auf dem Provider besitzt.

Sollten Sie Fehler in der Replikation haben, weil zum Beispiel die ACLs nicht vollständig gesetzt waren, können Sie den Dienst stoppen und die Datenbankdateien im Verzeichnis /var/symas/openldap-data/ löschen. Anschließend starten Sie den Dienst neu und lassen alle Objekte erneut replizieren.

12.2.3 refreshAndPersist

Die refreshAndPersist-Methode ähnelt zunächst der refreshOnly-Methode, unterscheidet sich aber in einem Punkt am Ende:

1.      Fester Aufbau einer Verbindung durch den Consumer zum Provider.

2.      Consumer sendet sein SyncCookie und seine Suchanfrage an den Provider.

3.      Provider prüft Aktualität der Datenbank des Consumers anhand des SyncCookies.

4.      Durchführung von present phase und delete phase.

5.      Der Provider sendet nun aber keine SearchResultDone-Meldung. Die Verbindung wird damit nicht beendet, sondern aufrechterhalten, also persistiert.

6.      Bei einer Änderung an einem Objekt sendet der Provider weitere Ergebnisse der anfangs gesendeten Suchanfrage an den Consumer.

Diese Methode finden Sie in Bild 12.8 schematisch dargestellt:

Bild 12.8 Schematische Darstellung der refreshAndPersist-Replikation

Es wird also eine einmal gestellte Suchanfrage nicht nach der ersten Antwort beendet. Stattdessen bleibt die aufgebaute Verbindung bestehen, und neue Ergebnisse werden laufend gesendet. Wenn wir also nochmal auf Ihre Bekannte/n von vorhin zurückkommen, erhalten Sie bei Ihrem Anruf erst einmal das Update einmalig auf die gleiche Weise wie vorher, legen aber danach nicht auf, sondern bleiben am Telefon. Sobald es etwas Neues über jemanden zu berichten gibt, werden Sie umgehend über diesen Jemand auf dem Laufenden gehalten. Allerdings bekommen Sie dann auch wieder deren oder dessen komplette Lebensgeschichte serviert.

Tabelle 12.2 Vor- und Nachteile von refreshAndPersist

Vorteile

Nachteile

Zeitnahe Synchronisation nach Änderungen

Synchronisation belastet zusätzlich das Netzwerk zu Spitzenzeiten

Geringe Netzwerklast bei Änderungen

Großer Overhead bei der ersten Synchronisation

12.2.3.1 Einrichtung

Die Einrichtung gleicht im Grunde der refreshOnly-Methode mit ein paar kleinen Änderungen. Hier wie dort muss auf dem Provider das syncprov-Modul eingerichtet und aktiviert werden. Sie benötigen ebenfalls einen Benutzer für die Synchronisation mit entsprechenden Leserechten. Damit der Provider sich später zeitnah beim Consumer meldet, benötigen Sie noch zwei Anpassungen an die Parameter des syncprov-Overlays:

Image       syncprov-checkpoint <Operationen> <Minuten>
Mit diesem Parameter legen Sie fest, nach wie viel Änderungen ein Prüfpunkt in der Datenbank des Providers gesetzt und der contextCSN geschrieben wird. Erst dann reicht dieser die Änderungen weiter an den oder die Consumer.

Image       syncprov-sessionlog <Operationen>
Hiermit legen Sie fest, wie viele Änderungen in dem Protokoll vorgehalten werden. Dieser Wert muss so groß gewählt werden, dass der Provider sich auch noch an die Änderungen „erinnert“, welche er dem oder den Consumer/n senden muss.

Das Beispiel aus Listing 12.3 würde sich für die dynamische Konfiguration daher etwas erweitern, wie in Listing 12.10 aufgezeigt:

Listing 12.10 LDIF zum Laden des syncprov-Moduls für refreshAndPersist

dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: syncprov.la dn: olcOverlay={0}syncprov,olcDatabase={2}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpSessionlog: 300 olcSpCheckpoint: 1 60

Haben Sie bereits eine Replikation mit der Methode refreshOnly eingerichtet, können Sie mittels der LDIF-Datei aus Listing 12.11 das Overlay auf dem Provider umstellen:

Listing 12.11 Umstellung des Overlay syncprov auf dem Provider

dn: olcOverlay={0}syncprov,olcDatabase={2}mdb,cn=config changetype: modify add: olcSpCheckpoint olcSpCheckpoint: 1 60

Bei der Einrichtung des Consumers gibt es ebenfalls nur geringe Änderungen. So ist der Parameter type, welcher die Art der Replikation festlegt, in diesem Fall statt auf refreshOnly auf refreshAndPersist zu setzen. Der Parameter interval entfällt, da nach der ersten erfolgreichen Synchronisation nach dem Start des slapd-Dienstes die Verbindung des Consumers zum Provider ja bestehen bleibt und nicht in Intervallen neu aufgebaut wird. Das Beispiel aus Listing 12.9 würde dann etwas geändert, und das Ergebnis finden Sie in Listing 12.12:

Listing 12.12 Konfiguration für den Consumer für refreshAndPersist

dn: olcDatabase={2}mdb,cn=config changetype: modify add: olcSyncrepl olcSyncrepl: rid=000 provider=ldaps://provider01.example.net type=refreshAndPersist retry="60 10 120 5" searchbase="dc=example,dc=net" filter="(objectClass=*)" scope=sub schemachecking=off bindmethod=simple binddn="uid=repl-user,ou=users,dc=example,dc=net" credentials=geheim

Wenn Sie auf dem Consumer bereits die Methode refreshOnly eingerichtet haben, können Sie den Eintrag einfach komplett ersetzen, Sie brauchen lediglich in der LDIF-Datei aus Listing 12.12 die Zeile add:olcSyncrepl durch replace: olcSyncrepl ersetzen.

12.2.4 Zwischenstopp

Die refreshOnly-Methode stellt eine wiederkehrende Pull-Replikation (also vom Consumer initiierte Datensynchronisation) dar. Bei refreshAndPersist startet der Consumer zwar zu Beginn ebenfalls eine Pull-Replikation, während der dann dauerhaft aufrecht erhaltenen Verbindung gehen alle weiteren Replikationen allerdings im Push-Verfahren vom Provider aus.

Zu Zeiten, als standortübergreifende Verbindungen noch nach Zeit berechnet wurden, hatte die refreshOnly-Methode noch eine Berechtigung, da Sie bestimmen können, wann und wie oft der Consumer eine (Wähl-)Verbindung zum Provider aufnimmt. Aber auch bei schmalbandigen Verbindungen zwischen Standorten kann diese Methode von Vorteil sein, da Sie bestimmen. Diese Variante hilft Ihnen also, Geld und/oder Bandbreite einzusparen, Sie erlangen aber eine eventuell starke Verzögerung in der Aktualisierung der Daten an den einzelnen Standorten.

In Zeiten von dauerhaften und breitbandigen Internetverbindungen überwiegt jedoch der Vorteil der refreshAndPersist-Methode, da nach der initialen Replikation weitere Änderungen vom Provider umgehend an seine Consumer weitergegeben werden. Somit sind die Daten zeitnah an den einzelnen Standorten aktualisiert.

Beide Varianten übertragen stets die gesamten Objekte, auch wenn sich nur einzelne Attribute geändert haben. Die Netzwerk- und Serverlast ist bei häufigen Änderungen insbesondere beim refreshOnly-Verfahren daher hoch. Herrscht auf Ihrer Verbindung, über welche die LDAP-Server replizieren müssen, von vornherein schon eine hohe Last und sind die LDAP-Server netzwerkseitig schon durch Lesezugriffe stark ausgelastet, ist eventuell die folgende Methode die bessere Wahl.

12.2.5 DeltaSync

Wie Sie gesehen haben, sind die beiden bisher betrachteten Methoden refreshOnly und refreshAndPersist objektorientiert. Bei jeder Änderung an einem Objekt wird dies stets vollständig übertragen. Bei vielen Objekten und/oder vielen Änderungen bedeutet dies eine große Menge an unnützen Daten, die dauernd über das Netzwerk übertragen und von den beteiligten Servern verarbeitet werden müssen. Nehmen wir ein typisches Objekt mit einer Größe von 500 Byte. Ändert sich an diesem ein Attribut mit einer Größe von 10 Byte, wird trotzdem das ganze Objekt übertragen. In diesem Fall hätten Sie also 98% an Overhead, der über das Netzwerk geht. Gut, bei 490 Byte an Daten, die unnötigerweise übertragen werden, ist das vielleicht vernachlässigbar. Aber Ihre Datenbank wird ja sicher nicht nur aus einem Objekt bestehen, welches geändert wird, sondern aus Hunderten oder Tausenden. Dann ist der überflüssige Netzwerkverkehr schon erheblich.

An dieser Stelle bietet Ihnen die DeltaSync-Replikation eine Alternative. Das Delta steht dabei für Differenz, denn bei dieser Methode wird tatsächlich nur der Unterschied an einem Objekt, also die geänderten Attribute bzw. deren geänderte Werte, übertragen.

Für unseren oben bereits erwähnten John Doe, den es von Kiel nach Bielefeld zieht, bedeutet dies, dass lediglich die Attributsänderung vom Provider zum Consumer übertragen wird. In Bild 12.9 sehen Sie den Unterschied zu den bisherigen Methoden:

Bild 12.9 Replikation des geänderten Attributs

Die Methode setzt auf der vorher betrachteten Methode refreshAndPersist auf. Zusätzlich führt der Provider Protokoll über die einzelnen Änderungen in seiner Datenbank. Diese Änderungen an einzelnen Attributen gibt der Server dann an den Consumer weiter. Dieses Protokoll wird durch ein Overlay bereitgestellt, welches Sie in Kapitel 10, «Erweiterte Funktionen durch Overlays», bereits kennengelernt haben: das accesslog. Dieses Overlay wird auf dem Provider aktiviert und so konfiguriert, dass alle writes protokolliert werden. Mit diesem Overlay ist der Provider nicht mehr allein auf den Vergleich des contextCSN angewiesen, sondern kann auch auf die Liste der Änderungen direkt zurückgreifen. Den Ablauf finden Sie in Bild 12.10 skizziert:

Bild 12.10 Schematische Darstellung der DeltaSync-Replikation

Sprechen wir noch ein letztes Mal über unsere Bekannte/n und die Neuigkeiten, die es zu berichten gibt. Die hier vorgestellte Methode entspricht eher dem norddeutschen oder westfälischen Naturell, denn jetzt wird nur noch das berichtet, was tatsächlich passiert ist seit dem letzten Mal, ohne immer wieder bei Adam und Eva zu beginnen.

Image

Hinweis: Fällt die Replikation über einen längeren Zeitraum aus oder fällt der Consumer zu weit hinter den Stand der Datenbank des Providers zurück, dann wird auf die refreshAndPersist-Methode umgestellt, bis die Datenbanken wieder synchron sind, und anschließend wieder auf die DeltaSync-Methode zurückgestellt.

Image

12.2.5.1 Einrichtung

Wie erwähnt baut die DeltaSync- auf der refreshAndPersist-Methode auf. Dementsprechend richten Sie Provider und Consumer so ein wie weiter oben beschrieben. Darüber hinaus benötigen Sie auf dem Provider das accesslog-Overlay. Beim Consumer sind dann lediglich kleine Änderungen gegenüber der refreshAndPersist-Methode durchzuführen.

Für den Provider sind also die beiden Module syncprov und accesslog zu laden und zu konfigurieren. Die komplette Konfiguration dazu finden Sie in Listing 12.13:

Listing 12.13 Komplette Konfiguration des Providers für DeltaSync

dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: accesslog.la olcModuleLoad: syncprov.la dn: olcOverlay={0}syncprov,olcDatabase={2}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpCheckpoint: 100 10 olcSpSessionlog: 200 dn: olcDatabase={3}mdb,cn=config changetype: add objectClass: olcMdbConfig objectClass: olcDatabaseConfig olcDatabase: {3}mdb olcDbDirectory: /var/symas/accesslog olcAccess: to * by dn.exact="cn=admin,dc=example,dc=net" read by dn.exact="uid=repl-user,ou=users,dc=example,dc=net read olcSuffix: cn=accesslog olcLastMod: TRUE olcMaxDerefDepth: 15 olcReadOnly: FALSE olcRootDN: cn=config olcLimits: dn.exact="cn=uid=repl-user,ou=users,dc=example,dc=net" time=unlimited size=unlimited olcMonitoring: TRUE olcDbCheckpoint: 0 0 olcDbIndex: entryCSN eq olcDbIndex: entryUUID eq olcDbIndex: objectClass eq olcDbIndex: reqEnd eq olcDbIndex: reqResult eq olcDbIndex: reqStart eq olcDbIndex: reqDN eq olcDbMode: 0600 olcDbSearchStack: 16 olcDbMaxsize: 85899345920 dn: olcOverlay={0}syncprov,olcDatabase={3}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpNoPresent: TRUE olcSpReloadHint: TRUE dn: olcOverlay={1}accesslog,olcDatabase={2}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcAccessLogConfig olcOverlay: {1}accesslog olcAccessLogDB: cn=accesslog olcAccessLogOps: writes olcAccessLogPurge: 01+00:00 00+04:00 olcAccessLogSuccess: TRUE

Wenn Sie bereits eine Replikation mit refreshAndPersist eingerichtet haben, benötigen Sie lediglich die Änderungen aus Listing 12.14:

Listing 12.14 Änderungen einer bestehenden Replikation

dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: accesslog.la dn: olcDatabase={3}mdb,cn=config changetype: add objectClass: olcMdbConfig objectClass: olcDatabaseConfig olcDatabase: {3}mdb olcDbDirectory: /var/symas/accesslog olcAccess: to dn.subtree="cn=accesslog" by dn.exact="cn=admin,dc=example,dc=net" read by dn.exact="uid=repl-user,ou=users,dc=example,dc=net" read olcSuffix: cn=accesslog olcLastMod: TRUE olcMaxDerefDepth: 15 olcReadOnly: FALSE olcRootDN: cn=config olcLimits: dn.exact="cn=uid=repl-user,ou=users,dc=example,dc=net" time=unlimited size=unlimited olcMonitoring: TRUE olcDbCheckpoint: 0 0 olcDbIndex: entryCSN eq olcDbIndex: entryUUID eq olcDbIndex: objectClass eq olcDbIndex: reqEnd eq olcDbIndex: reqResult eq olcDbIndex: reqStart eq olcDbIndex: reqDN eq olcDbMode: 0600 olcDbSearchStack: 16 olcDbMaxsize: 85899345920 dn: olcOverlay={0}syncprov,olcDatabase={3}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpNoPresent: TRUE olcSpReloadHint: TRUE dn: olcOverlay={1}accesslog,olcDatabase={2}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcAccessLogConfig olcOverlay: {1}accesslog olcAccessLogDB: cn=accesslog olcAccessLogOps: writes olcAccessLogPurge: 01+00:00 00+04:00 olcAccessLogSuccess: TRUE

Alle hier verwendeten Parameter finden Sie auch in den entsprechenden Manpages. Wir wollen Ihnen hier nur die wichtigsten erklären:

Image       dn: olcDatabase=3mdb,cn=config
Für DeltaSync benötigen Sie eine eigene Datenbank, in der die Änderungen abgelegt werden. Diese Datenbank wird in diesem Abschnitt konfiguriert und beim Einspielen der Änderung auch angelegt.

Image       olcDbDirectory: /var/symas/accesslog
Das Verzeichnis, in dem die Datenbank im Dateisystem angelegt wird. Achten Sie darauf, dass der Benutzer, unter dem Ihr OpenLDAP-Server läuft, alle Rechte besitzt.

Image       olcSuffix: cn=accesslog
Der DN, unter dem die Accesslog-Datenbank angesprochen wird. Sie können später auch mittels ldapsearch auf die Datenbank zugreifen. Achten Sie dabei auf die ACLs. Den Namen können Sie frei wählen; nur achten Sie darauf, dass Sie im Verlauf der weiteren Konfiguration immer den selben Namen nutzen.

Image       olcDbMaxsize: 85899345920
Hier legen Sie die maximale Größe der Datenbank fest. Der Standardwert ist hier 10485760, also 10MB. Wählen Sie den Wert lieber zu groß als zu klein. Sie können den Wert zwar später noch anheben, aber wenn Ihr Server sehr stark ausgelastet ist, wird es zu Verzögerungen in der Replikation kommen.

Image       olcDbIndex
Alle hier aufgeführten Indizes sorgen in der Accesslog-Datenbank für bessere Performance und sollten auch so übernommen werden.

Image       dn: olcOverlay=0syncprov,olcDatabase=3mdb,cn=config
Da der Consumer die Daten der Accesslog-Datenbank lesen können muss, ist das Overlay syncprov auch für die Accesslog-Datenbank erforderlich.

Image       olcSpNoPresent
Durch diesen Parameter wird die Present-Phase bei der Replikation übersprungen. Dies kann und sollte nur dann eingesetzt werden, wenn wie im vorliegenden Fall auf ein Änderungsprotokoll wie accesslog zurückgegriffen werden kann. Der Standardwert ist false.

Image       olcSpReloadHint
Auch dieser Parameter wird nur bei der Delta-Synchronisation eingesetzt. Der Standardwert ist false. Dieser Parameter veranlasst den Provider, das reloadHint-Flag im SynCookie des Consumers zu beachten, mit dem dieser den Provider zu einer Übertragung der vollständigen Datenbank auffordert.

Image       dn: olcOverlay=1accesslog,olcDatabase=2mdb,cn=config
Damit die Änderungen an der Objektdatenbank auch in die Accesslog-Datenbank geschrieben werden, benötigen Sie jetzt noch das Overlay accesslog.

Image       olcAccessLogDB: cn=accesslog
Der Suffix für die Accesslog-Datenbank. Dieser muss mit dem Namen, den Sie in der Konfiguration der Accesslog-Datenbank verwendet haben, übereinstimmen.

Image       olcAccessLogOps: writes
Nur schreibende Zugriffe auf die Objektdatenbank werden in die Accesslog-Datenbank geschrieben.

Image       olcAccessLogPurge: 01+00:00 00+04:00
Der erste Eintrag gibt an, wie alt die Einträge maximal werden dürfen, bevor sie gelöscht werden. Der zweite Eintrag gibt an, wie oft nach alten Einträgen gesucht wird. Das Beispiel bedeutet, dass die Accesslog-Datenbank alle vier Stunden nach alten Einträgen durchsucht wird. Alle Einträge, die älter als ein Tag sind, werden gelöscht. Sowohl das Alter als auch das Intervall werden als Zeitspanne in Tagen, Stunden, Minuten und Sekunden angegeben.

Image       olcAccessLogSuccess: TRUE
Nur komplett abgeschlossene Schreibvorgänge werden in die Accesslog-Datenbank geschrieben, denn nur die sind für die Replikation relevant.

Nach dem Import dieser bzw. einer entsprechenden LDIF-Datei bietet Ihr Server als Provider dann alle nötigen Informationen an, damit ein Consumer seine Replikation über das DeltaSync-Verfahren durchführen kann.

Image

Wichtig: Achten Sie darauf, dass Ihr Replikationsbenutzer das Accesslog auch lesen kann, denn sonst funktioniert die Replikation nicht.

Image

Der Consumer kann dynamisch mit folgender LDIF-Datei aus Listing 12.15 eingerichtet werden:

Listing 12.15 Konfiguration des Consumers für DeltaSync

dn: olcDatabase={2}mdb,cn=config changetype: modify add: olcSyncRepl olcSyncrepl: rid=000 provider=ldaps://provider01.example.net type=refreshAndPersist retry="60 10 120 5" searchbase="dc=example,dc=net" scope=sub schemachecking=off bindmethod=simple binddn="uid=repl-user,ou=users,dc=example,dc=net" credentials=geheim syncdata=accesslog logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))"

Sie sehen, bis auf die letzten drei Parameter entspricht die Konfiguration dem der bereits beschriebenen refreshAndPersist-Methode. Die neuen Parameter sind:

Image       syncdata
Dieser Parameter muss hier auf accesslog stehen. Weitere Möglichkeiten sind changelog und default. Das changelog-Format wird nicht mehr verwendet, bei default werden die beiden folgenden Parameter ignoriert, es findet also eine refreshAndPersist-Replikation statt.

Image       logbase
Hier geben Sie den Kontext auf dem Provider an, unter welchem die benötigten Protokolleinträge zu finden sind.

Image       logfilter
An dieser Stelle tragen Sie einen LDAP-Filter ein, mit welchem Sie die benötigten Protokolleinträge im Suchkontext heraussuchen. Wirklich benötigt werden aus dem Protokoll nur Protokolleinträge mit Änderungen, also add, delete, modify und modRDN. Diese Einträge finden Sie in den Objekten der Klasse auditWriteObject.

Haben Sie bereits eine Replikation auf Ihrem Consumer eingerichtet, können Sie an dieser Stelle wieder den Parameter add: olcSyncRepl durch replace: olcSyncRepl ersetzen und die LDIF-Datei einspielen.

12.2.6 Zusammenfassung und Ergänzung

Sie haben also nun die drei möglichen Formen der Replikation kennengelernt, die hier noch einmal kurz zusammengefasst werden:

Tabelle 12.3 Vergleich der Replikationsarten

refreshOnly

refreshAndPersist

DeltaSync

1.

vollständige Replikation aller geänderten Objekte

1.

vollständige Replikation aller geänderten Objekte

1.

vollständige Replikation aller geänderten Objekte

2.

Abbau der Verbindung

2.

Aufrechterhalten der Verbindung

2.

Aufrechterhalten der Verbindung

3.

nach einem Intervall zurück zu 1.

3.

Senden geänderter Objekte durch Provider bei Bedarf

3.

Senden geänderter Attribute durch Provider bei Bedarf

In den Beispielen wird für die Replikation immer das Klartextpasswort für den binddn verwendet. Dies ist notwendig, da der Eintrag eines verschlüsselten Passworts bei der Verwendung von bindmethod=simple nicht möglich ist. Im Zusammenhang mit Kerberos können Sie allerdings eine Verbindung ohne die Verwendung eines Klartextpassworts aufbauen. Wie Sie die Replikation in Verbindung mit Kerberos einrichten, finden Sie in Abschnitt 15.10.4 in Kapitel «OpenLDAP mit Kerberos».

12.3 Schreiben auf dem Consumer

Bis zu diesem Zeitpunkt haben wir immer gesagt: „Auf dem Consumer kann nicht geschrieben werden“, aber jetzt doch? Nein, geht nicht direkt, aber indirekt ist es schon möglich. Wenn Sie eine Änderung am Consumer einspielen wollen, kann der Consumer die Änderung nicht selber verarbeiten, aber er ist in der Lage, die Änderung an den Provider weiterzuleiten. So ist eine indirekte Änderung an Objekten über den Consumer doch möglich. Alles, was Sie dazu benötigen, ist das Overlay chain, das die Änderung an den Provider weiterleitet. Auch für das Overlay chain benötigen Sie ein Modul. Es ist notwendig, das Modul auf dem Consumer zu laden. Das Overlay hat aber kein eigenes Modul, sondern wird über das Modul back_ldap bereitgestellt. Sorgen Sie dafür, dass das Modul geladen wird, bevor Sie das Overlay chain konfigurieren. Nutzen Sie dazu die LDIF-Datei aus Listing 12.16:

Listing 12.16 Laden des Moduls chain

dn: cn=module{0},cn=config changetype: modify add: olcModuleload olcModuleLoad: back_ldap.la

Das Overlay benötigt einen Benutzer (am besten, Sie erstellen ein simpleSecurityObject), der Schreibrechte an allen Objekten auf dem Provider besitzt, die über den Consumer geändert werden sollen. Sorgen Sie mittels ACLs für die benötigten Berechtigungen.

Im Anschluss können Sie die LDIF-Datei für die Konfiguration des Moduls erstellen und einspielen. Die LDIF-Datei sehen Sie in Listing 12.17:

Listing 12.17 LDIF-Datei für das Modul chain

dn: olcDatabase={2}mdb,cn=config changetype: modify replace: olcUpdateref olcUpdateref: "ldaps://provider01.example.net" dn: olcOverlay={0}chain,olcDatabase={-1}frontend,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcChainConfig olcOverlay: {0}chain olcChainReturnError: TRUE dn: olcDatabase={0}ldap,olcOverlay={0}chain,olcDatabase={-1}frontend,\ cn=config changetype: add objectClass: olcLDAPConfig objectClass: olcChainDatabase olcDatabase: {0}ldap olcDbURI: "ldaps://provider01.example.net" olcDbRebindAsUser: TRUE olcDbIDAssertBind: bindmethod=simple binddn="uid=chain-user,ou=users,dc=example,dc=net" credentials=geheim mode=self flags=prescriptive,proxy-authz-non-critical

Durch die Verwendung von {-1}frontend tragen Sie die Konfiguration des Overlays chain in den globalen Teil der Konfiguration ein. Testen Sie anschließend, ob Sie vom Consumer aus als chain-user Änderungen durchführen können.

Wenn Sie jetzt eine Änderung auf dem Consumer mittels einer LDIF-Datei einspielen, wird die Änderung an den Provider übertragen, und der Consumer erhält dann die Änderung vom Provider. So können Sie Anwendungen, die schreibend auf den LDAP zugreifen müssen, den direkten Zugriff auf den Provider verwehren. Gerade wenn Sie Ihren Provider durch eine Firewall schützen wollen, benötigen jetzt nur noch die Consumer Zugriff auf den Provider. Selbst Passwortänderungen der Benutzer können so indirekt über den Consumer durchgeführt werden.

12.4 Replikationstopologien

In den bislang betrachteten Szenarien hatten wir es jeweils mit einem einzelnen Server als Provider zu tun, welcher eine beschreibbare Datenbank besitzt. Ein Consumer hat sich dann diese Datenbank repliziert. Diese Art der Replikation können Sie nun natürlich erweitern und mehrere LDAP-Server zu Consumern eines Providers machen und/oder Consumer als Provider für weitere Consumer einrichten. Auch die Einrichtung mehrerer gleichzeitig aktiver Provider ist möglich. Damit können Sie Ihre Datenbank zum Beispiel an andere Standorte replizieren und von dort lokal weiter verteilen. Beachten Sie dabei aber: Je weiter Sie dieses Spiel treiben und je mehr Stufen der Replikation hinzukommen, desto länger dauert es, bis die Daten auf allen Servern aktuell sind.

Die Consumer besitzen bislang ausschließlich Nur-Lese-Kopien der Datenbank, können also keine Änderungen vornehmen. Fällt der Server an der „Spitze“ Ihrer Topologie aus, können keine Änderungen mehr vorgenommen werden. Hinsichtlich des Schreibens haben Sie einen Single Point Of Failure, denn Sie besitzen in diesem Fall zunächst keine Möglichkeit mehr, Ihre Datenbank zu ändern. Ihre Hauptaufgabe ist es dann, einen bestehenden Server bestimmen, der zum Provider wird. So können Sie dann Ihre Replikationstopologie umbauen, was gegebenenfalls sehr zeitaufwendig und fehleranfällig sein kann.

Daher wollen wir nun noch zwei weitere Szenarien betrachten, in denen Sie mehr als nur eine beschreibbare Kopie der Datenbank erhalten.

Image

Hinweis: Spätestens jetzt wird das Thema Zeitsynchronisation kritisch. Bevor Sie Server gegenseitig replizieren lassen, sorgen Sie dafür, dass die Uhren auf den beteiligten Servern dauerhaft identisch sind.

Image

12.4.1 Standby-Provider oder Mirror-Mode

Im ersten Fall setzen Sie zwei LDAP-Server ein, welche sich gegenseitig replizieren. Eine Möglichkeit wäre, dann beide Server aktiv für Änderungen zu nutzen, das wäre also eine aktiv-aktiv-Lösung oder ein Multi-Provider-Mode. Bild 12.11 verdeutlicht die Methode noch einmal:

Bild 12.11 Multi-Provider-Mode

Eine weitere Möglichkeit ist ein aktiv-passiv-Betrieb, dann wäre einer der beiden Server als Standby-Provider ausgelegt. Auch in dieser Umgebung replizieren die beiden Server die Datenbank gegenseitig. Änderungen finden aber ausschließlich an einem Server statt: dem aktiven Server. Beim Ausfall des aktiven Servers schwenken Sie manuell oder durch einen Automatismus wie einen Loadbalancer auf den Standby-Server um. Ist später der ausgefallene Server wieder in Betrieb, so erhält dieser (als Consumer des Standby-Servers) automatisch wieder die aktuelle Datenbank. In Bild 12.12 sehen Sie noch einmal den Unterschied zum Mirror-Mode:

Bild 12.12 Standby-Server mit Loadbalancer

Da die Replikation in den neuen OpenLDAP-Versionen noch stabiler und performanter ist, besteht für den Einsatz des Standby-Providers kaum noch Verwendung. Wir können Ihnen nur empfehlen, wenn Sie mehrere Provider einrichten möchten, den Multi-Provider-Mode zu nutzen. Der Vorteil ist nicht nur das Sie auf allen Providern gleichzeitig schreiben können, sondern, im Gegensatz zum Standby-Provider, können Sie hier auch mehr als zwei Provider einrichten. Zusätzlich kommt dazu, dass die Konfiguration auf allen Providern identisch ist und Sie die Konfiguration auf alle Provider replizieren können. Wenn Sie dann später eine Änderung der Konfiguration vornehmen, zum Beispiel neue ACLs einpflegen wollen, ist es egal, auf welchem Provider Sie die Änderung vornehmen, die Änderung wird auf alle Provider repliziert.

Aus diesen Gründen werden wir hier im Buch nur die Multi-Provider-Replikation einrichten.

Hier noch ein paar Anmerkungen zur Multi-Provider-Replikation

In großen Umgebungen müssen Änderungen an mehreren LDAP-Servern möglich sein, insbesondere wenn sich Ihr Netzwerk über mehrere Standorte erstreckt, in denen Änderungen an den Inhalten der Datenbank vorgenommen werden sollen. Also wird das Modell des Mirror-Modes erweitert, und Sie richten zwei oder mehr aktive LDAP-Server als Provider mit einer Schreibkopie der Datenbank ein. Damit erhalten Sie eine Multi-Provider-Architektur.

Je mehr Server Sie einsetzen, umso ausfallsicherer wird Ihre Struktur und umso mehr Server stehen für Änderungen zur Verfügung. Sie erkaufen sich diese Vorteile allerdings mit einer erhöhten Komplexität der Topologie. Bei der Einrichtung ist es wichtig, darauf zu achten, dass Sie diese so wählen, dass die Änderungen an jedem einzelnen dieser Server die Chance haben müssen, zu jedem der anderen Server repliziert zu werden. Bei drei Servern haben Sie (3*(3-1)), also 6 Verbindungen, bei vier Servern (4*(4-1)), also 12 Verbindungen. Die einfache Formel lautet also (Anzahl Server *(Anzahl Server -1)). Auch wird die Fehlersuche dadurch nicht einfacher, und bei mangelhafter Planung und fehlender Überwachung wächst die Gefahr von Inkonsistenzen in den Datenbanken. Bild 12.13 stellt Ihnen die Situation mit mehreren Providern schematisch dar:

Bild 12.13 Multi-Provider

12.4.2 Vorbereitung der Replikation

Als Replikationsmethode verwenden wir refreshAndPersist zusammen mit DeltaSync.

Image

Hinweis: An dieser Stelle wollen wir uns erst auf die Einrichtung der Replikation fokussieren, aus dem Grund werden wir hier die Beispiele mit zwei neu aufgesetzten Providern beginnen und nicht den bestehenden Provider ändern.

Image

Da beide Systeme identisch eingerichtet werden, beginnen wir mit der Einrichtung des ersten Servers und kopieren anschließend die Konfiguration auf den zweiten Server. Wir werden dabei auch gleich die TLS-Verschlüsselung einrichten. Hier ist es jetzt besonders wichtig, dass die Dateinamen der Zertifikate und die Pfade identisch sind, denn wir wollen ja die komplette Konfiguration replizieren.

Damit die Server bei der Replikation auch die Kommunikationspartner kennen, wird eine eindeutige ServerID benötigt. Sie können für die ServerID einen ganzzahligen Wert zwischen 0 und 4095 wählen. Zu finden ist diese Kennung später als Replica ID in den CSNs. Dadurch wird deutlich, an welchem der Server die aktuellste Änderung durchgeführt wurde.

In der generellen Konfiguration Ihrer Provider hinterlegen Sie zunächst eine eindeutige ServerID mit der entsprechenden LDAP-URI für alle an der Replikation teilnehmenden LDAP-Server. Mit der LDIF-Datei aus Listing 12.18 tragen Sie die Änderung in Ihre Konfiguration ein:

Listing 12.18 Einrichtung der Server-ID

dn: cn=config changetype: modify replace: olcServerID olcServerID: 1 ldaps://provider02.example.net olcServerID: 2 ldaps://provider03.example.net

12.4.3 Einrichtung der Replikation cn=config

Im ersten Teil wollen wir mit der Einrichtung der Replikation der Konfiguration beginnen. Der Vorteil ist der, wenn die Grundkonfiguration erst einmal repliziert wird, können Sie die Replikation der Objektdatenbank im Anschluss auf einem der beiden Provider einrichten, und der zweite Provider erhält die Änderungen dann automatisch. Da die Replikation hier (vorerst) mit dem rootdn durchgeführt wird, benötigen Sie für den Vorgang auch noch keinen Benutzer in der Objektdatenbank. In Listing 12.19 sehen Sie die LDIF-Datei für die Änderung der Konfiguration:

Listing 12.19 Replikation der Konfiguration

dn: cn=module{0},cn=config changetype: modify add: olcModuleload olcModuleLoad: syncprov.la dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov dn: olcDatabase={0}config,cn=config changetype: modify replace: olcSyncRepl olcSyncRepl: rid=2 provider=ldaps://provider02.example.net binddn="cn=admin,cn=config" bindmethod=simple credentials=geheim searchbase="cn=config" type=refreshAndPersist retry="5 5 300 20" timeout=1 tls_reqcert=allow olcSyncRepl: rid=3 provider=ldaps://provider03.example.net binddn="cn=admin,cn=config" bindmethod=simple credentials=geheim searchbase="cn=config" type=refreshAndPersist retry="5 5 300 20" timeout=1 tls_reqcert=allow - add: olcMultiprovider olcMultiprovider: TRUE

Image

Hinweis: Nachdem Sie die Konfiguration eingespielt haben, werden Sie im Log jede Menge Fehlermeldungen erhalten. Der LDAP-Server wird hier immer wieder melden slap_client_connect: URI=ldaps://provider03.example.netDN="cn=admin,cn=config"ldap_sasl_bind_s failed. Diesen Fehler können Sie ignorieren, da der provider03 noch gar nicht eingerichtet ist.

Image

Was passiert hier?

Als Erstes wird wieder das Modul syncprov geladen, da es für die Bereitstellung der Daten benötigt wird. Beide LDAP-Server sollen ja als Provider für die Replikation eingerichtet werden.

Dann wird das Overlay syncprov in die Datenbank der Konfiguration

dn: olcOverlay=syncprov,olcDatabase=0config,cn=config eingebunden.

Daraufhin folgt die Einrichtung der Syncrepl-Direktive, und zwar zwei Mal. Jeder der an der Replikation teilnehmenden LDAP-Server ist immer Provider und Consumer. In der Syncrepl-Direktive wird der Consumer-Part eingerichtet. Sie sehen hier, dass der provider02, den wir gerade einrichten, auch auf sich selbst zugreift und Daten repliziert. Wenn jetzt Daten auf dem provider02 geändert werden, werden diese Daten auch auf den provider02 selbst repliziert. So kann der Provider prüfen, ob die Daten auch korrekt repliziert wurden.

Der letzte Teil der Konfiguration add: olcMultiprovider und olcMultiprovider: TRUE konfigurieren den Multi-Provider-Modus.

Damit ist die Konfiguration des ersten LDAP-Servers im Cluster abgeschlossen. Stoppen Sie den LDAP-Server, so können Sie sicher sein, dass keine Änderungen mehr vorgenommen werden, bevor Sie die Konfiguration auf den zweiten Provider übertragen haben.

Sichern Sie jetzt die Konfiguration mit dem Kommando

slapcat -n0 > backup-config.ldif.

Einrichtung des zweiten Providers

Installieren Sie die OpenLDAP-Pakete auf dem zweiten Provider und kopieren Sie die benötigten Zertifikate mit dem identischen Namen in den identischen Pfad wie schon auf dem ersten Provider des Clusters. Sorgen Sie dafür, dass der Dienst nicht läuft und dass das Verzeichnis /opt/symas/etc/openldap/slapd.d auf jeden Fall leer ist.

Kopieren Sie anschließend die gesicherte Konfiguration des ersten Providers auf den zweiten Provider. Anschließend spielen Sie die gesicherte Konfiguration ein. Die einzelnen Schritte sehen Sie in Listing 12.20:

Listing 12.20 Einspielen der Konfiguration

root@provider03:~# slapadd -n0 -F /opt/symas/etc/openldap/slapd.d/ -l backup-config.ldif Closing DB... root@provider03:~# chown -R openldap: /opt/symas/etc/openldap/slapd.d/

Starten Sie anschließend den LDAP-Dienst auf beiden Servern neu. Wenn Sie zwei weitere Konsolen öffnen (für jeden der neuen Server eine), können Sie das Ergebnis mit dem Kommando journalctl -f -u symas-openldap-server.service verfolgen.

Im Log beider Server sehen Sie den Verbindungsaufbau zum jeweils anderen Server.

Jetzt können Sie die Konfiguration ändern und die Replikation auf den anderen LDAP-Server prüfen. Um die Replikation zu testen, können Sie zum Beispiel eine zusätzliche serverID eintragen, auch wenn es momentan keinen weiteren Server gibt. Dazu spielen Sie auf einem der Provider die LDIF-Datei aus Listing 12.21 ein und prüfen anschließend mit ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config | less, ob die Änderung auf beiden Servern durchgeführt wurde:

Listing 12.21 Hinzufügen einer ServerID

dn: cn=config changetype: modify replace: olcServerID olcServerID: 1 ldaps://provider02.example.net olcServerID: 2 ldaps://provider03.example.net olcServerID: 3 ldaps://provider04.example.net

Als Gegenprobe spielen Sie jetzt die LDIF-Datei aus Listing 12.22 auf dem anderen Provider ein und prüfen, ob die serverID wieder auf beiden Providern entfernt wurde:

Listing 12.22 Entfernen der ServerID

dn: cn=config changetype: modify replace: olcServerID olcServerID: 1 ldaps://provider02.example.net olcServerID: 2 ldaps://provider03.example.net

Die Einrichtung der replizierten Konfiguration ist damit abgeschlossen.

12.4.4 Einrichtung der Replikation der Objektdatenbank

Bei der Replikation der Objektdatenbank wollen wir die Replikation via refreshAndPersist zusammen mit DeltaSync einrichten. Bevor Sie die benötigte Konfiguration einspielen können, benötigen Sie erst auf beiden Providern das Verzeichnis, in dem die Accesslog-Datenbank abgelegt wird. Die Verzeichnisse müssen auf beiden Server identisch heißen, und die Rechte müssen gesetzt werden. In Listing 12.23 sehen Sie die Kommandos, die Sie auf beiden Servern identisch verwenden:

Listing 12.23 Einrichten des Verzeichnisses für die Accesslog-Datenbank

root@provider02:~# mkdir /var/symas/accesslog root@provider02:~# chown openldap: /var/symas/accesslog root@provider03:~# mkdir /var/symas/accesslog root@provider03:~# chown openldap: /var/symas/accesslog

Erst jetzt können Sie die Konfiguration der Replikation der Objektdatenbank einspielen. In Listing 12.24 sehen Sie die benötigte LDIF-Datei:

Listing 12.24 LDIF für die Replikation der Objektdatenbank

dn: cn=module{0},cn=config changetype: modify add: olcModuleLoad olcModuleLoad: accesslog.la dn: olcDatabase={3}mdb,cn=config changetype: add objectClass: olcDatabaseConfig objectClass: olcMdbConfig olcDatabase: {3}mdb olcDbDirectory: /var/symas/accesslog olcSuffix: cn=accesslog olcAccess: {0}to dn.subtree="cn=accesslog" by dn.exact="uid=repl-user,ou=users,dc=example,dc=net" read by dn.exact="cn=admin,dc=example,dc=net" read olcLastMod: TRUE olcMaxDerefDepth: 15 olcReadOnly: FALSE olcRootDN: cn=config olcLimits: dn.exact="cn=uid=repl-user,ou=users,dc=example,dc=net" time=unlimited \ size=unlimited olcSizeLimit: unlimited olcTimeLimit: unlimited olcMonitoring: TRUE olcDbCheckpoint: 0 0 olcDbIndex: entryCSN eq olcDbIndex: entryUUID eq olcDbIndex: objectClass eq olcDbIndex: reqEnd eq olcDbIndex: reqResult eq olcDbIndex: reqStart eq olcDbIndex: reqDN eq olcDbMode: 0600 olcDbSearchStack: 16 olcDbMaxsize: 85899345920 dn: olcOverlay=syncprov,olcDatabase={3}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: syncprov olcSpNoPresent: TRUE olcSpReloadHint: TRUE dn: olcOverlay={0}syncprov,olcDatabase={2}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcSyncProvConfig olcOverlay: {0}syncprov olcSpCheckpoint: 100 10 olcSpSessionlog: 200 dn: olcOverlay={1}accesslog,olcDatabase={2}mdb,cn=config changetype: add objectClass: olcOverlayConfig objectClass: olcAccessLogConfig olcOverlay: {1}accesslog olcAccessLogDB: cn=accesslog olcAccessLogOps: writes olcAccessLogSuccess: TRUE olcAccessLogPurge: 01+00:00 00+04:00 dn: olcDatabase={2}mdb,cn=config changetype: modify replace: olcSyncrepl olcSyncrepl: rid=102 provider=ldaps://provider02.example.net bindmethod=simple timeout=0 network-timeout=0 binddn=uid=repl-user,ou=users,dc=example,dc=net credentials=geheim filter="(objectclass=*)" searchbase="dc=example,dc=net" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" logbase=cn=accesslog scope=sub schemachecking=off type=refreshAndPersist retry="60 +" syncdata=accesslog keepalive=240:10:30 tls_reqcert=allow olcSyncrepl: rid=102 provider=ldaps://provider03.example.net bindmethod=simple timeout=0 network-timeout=0 binddn=uid=repl-user,ou=users,dc=example,dc=net credentials=geheim filter="(objectclass=*)" searchbase="dc=example,dc=net" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" logbase=cn=accesslog scope=sub schemachecking=off type=refreshAndPersist retry="60 +" syncdata=accesslog keepalive=240:10:30 tls_reqcert=allow - add: olcMultiprovider olcMultiprovider: TRUE

Image

Hinweis: Auch hier werden Sie noch Fehler in den Log-Dateien sehen, da der Replikationsbenutzer noch nicht angelegt und somit ein Verbindungsaufbau als repl-user noch nicht möglich ist.

Image

Aber schauen wir uns erst einmal die gerade eingespielte Änderung der Konfiguration an: Die ersten Teile kennen Sie schon aus der einfachen Replikation mit DeltaSync zwischen einem Provider und einem Consumer. Da wir hier jetzt zwei Provider haben, die gleichzeitig auch Consumer sind, muss für beide auch die Konfiguration auf beiden Servern vorhanden sein. Es wird also wieder das Overlay syncprov eingerichtet und die benötigte Accesslog-Datenbank.

Dann kommt die eigentliche Replikation. Jetzt wird die Objektdatenbank repliziert, also dn: olcDatabase=2mdb,cn=config. Auch hier, wie schon zuvor bei der Replikation der Konfiguration, wird sich immer jeder der Provider mit sich selbst replizieren. Auf keinen Fall dürfen Sie hier die Aktivierung des olcMultiprovider vergessen.

Jetzt können Sie die ersten Objekte auf einem der Provider aus Listing 12.25 einspielen:

Listing 12.25 Einspielen der ersten Objekte

dn: dc=example,dc=net objectClass: domain objectClass: dcObject dc: example dn: ou=users,dc=example,dc=net objectClass: organizationalUnit ou: users dn: ou=groups,dc=example,dc=net objectClass: organizationalUnit ou: groups dn: uid=repl-user,ou=users,dc=example,dc=net objectClass: simpleSecurityObject objectClass: account userPassword: {ARGON2}$argon2i$v=19$m=4096,t=3,p=1$ZHN....

Beobachten Sie das Log mit jornalctl -f -u symas-openldap-server.service. Sollte die Replikation nicht sofort starten, kann das daran liegen, dass die Zeit aus dem Parameter retry abgelaufen ist. Starten Sie dann den Dienst auf beiden Servern neu.

Image

Hinweis: Sollten Sie den Fehler err=49 für den Zugriff des repl-users erhalten, prüfen Sie das Passwort des Benutzer. Am einfachsten geht das, indem Sie versuchen, mittels ldapsearch -x -D uid=repl-user,ou=users,dc=example,dc=net -W auf den LDAP zuzugreifen. Schlägt das fehl, prüfen und ändern Sie das Passwort des Benutzers.

Image

Der aufmerksame Leser hat bestimmt gemerkt, dass wir bei der Konfiguration einen Punkt außer acht gelassen haben, den wir schon bei der ersten Installation angesprochen haben, nämlich: „Verwenden Sie nie ein rootdn für die Replikation oder den Zugriff von Diensten auf den LDAP-Server.“ Aber genau das haben wir bei der Replikation der Konfiguration gemacht. Das ging an der Stelle auch noch nicht anders, da wir noch keine Objektdatenbank hatten, in der wir den entsprechenden Benutzer anlegen konnten. Diese Schritte folgen jetzt.

Als Erstes benötigen Sie wieder ein simpleSecurityObject. In Listing 12.26 sehen Sie die LDIF-Datei für das von uns genutzte Objekt:

Listing 12.26 LDIF für den repl-conf Benutzer

dn: uid=repl-confg,ou=users,dc=example,dc=net objectClass: account objectClass: simpleSecurityObject objectClass: top uid: repl-config userPassword: {ARGON2}$argon2i$v=19$m=4096,t=3,p=1$Z2Z....

Im nächsten Schritt sorgen Sie dafür, dass das gerade angelegte Objekt auch lesenden Zugriff auf die gesamte Konfiguration erhält. Listing 12.27 zeigt die benötigte LDIF-Datei:

Listing 12.27 ACL für repl-config

dn: olcDatabase={0}config,cn=config changetype: modify delete: olcAccess olcAccess: {0} - add: olcAccess olcAccess: {0} to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by dn.exact=uid=repl-config,ou=users,dc=example,dc=net read

Nachdem Sie die ACL eingespielt haben, prüfen Sie unbedingt, ob Sie mit dem Objekt die gesamte Konfiguration lesen können. Führen Sie am einfachsten ein ldapsearch mit dem Benutzer auf die Konfiguration aus. Erst wenn der Benutzer alles lesen kann, dürfen Sie die nachfolgende Änderung der Replikationskonfiguration anpassen. Für die Änderung sehen Sie in Listing 12.28 die benötigte LDIF-Datei:

Listing 12.28 Änderung der Replikation der Konfiguration

dn: olcDatabase={0}config,cn=config changetype: modify replace: olcSyncRepl olcSyncRepl: rid=2 provider=ldaps://provider02.example.net binddn="uid=repl-config,ou=users,dc=example,dc=net" bindmethod=simple credentials=geheim searchbase="cn=config" type=refreshAndPersist retry="5 5 300 20" timeout=1 tls_reqcert=allow olcSyncRepl: rid=3 provider=ldaps://provider03.example.net binddn="uid=repl-config,ou=users,dc=example,dc=net" bindmethod=simple credentials=geheim searchbase="cn=config" type=refreshAndPersist retry="5 5 300 20" timeout=1 tls_reqcert=allow - add: olcMultiprovider olcMultiprovider: TRUE

Nachdem der Cluster läuft, können Sie jetzt die Daten und Ihre bestehenden ACLs aus einem anderen System einspielen. Achten Sie beim Einspielen der ACLs darauf, dass Sie sich keine der benötigten, aktuellen ACLs überschreiben.

Image

Tipp: Wenn Sie die bisherigen Daten und ACLs vom provider01 in den Cluster übernehmen wollen, finden Sie im Download zum Buch die beiden Dateien replikation/backup-p01-objekte.ldif und replikation/alle-acls-p01.ldif, mit denen Sie den Datenbestand und alle ACLs einspielen können. In der Datei mit den Objekten sind auch alle grundlegenden Objekte enthalten. Vergessen Sie daher beim Einspielen mit ldapadd die Option -c nicht, dann werden bereits vorhandene Objekte übersprungen.

Image

Zwei Provider reichen Ihnen nicht? Kein Problem:

Image       Fügen Sie eine neue serverID in die bestehende Konfiguration ein.

Image       Ergänzen Sie die syncrepl-Direktive um den neuen Provider.

Image       Sichern Sie die Konfiguration auf einem der beiden bestehenden Provider.

Image       Setzen Sie den neuen Provider auf. Erstellen und kopieren Sie die Zertifikate an die richtige Stelle.

Image       Legen Sie das Verzeichnis für das accesslog an.

Image       Kopieren Sie die gesicherte Konfiguration auf den neuen Provider.

Image       Spielen Sie die Konfiguration mit slapadd ein.

Image       Prüfen Sie die Replikation.

Image       Passen Sie eventuell die SRV-Records im DNS an.

So haben Sie in kürzester Zeit einen weiteren Provider eingerichtet.

12.5 Consumer mit eingeschränkter Replikation

Bis zu diesem Zeitpunkt haben wir Ihnen immer gezeigt, wie Sie ganze Bäume replizieren können. Aber es gibt auch verschiedene Szenarien, in denen Sie eventuell nur einen Teil der Objekte oder Attribute replizieren wollen. Die folgende, nicht vollständige Aufzählung nennt ein paar Beispiele:

Image       Bestimmte Objekte sollen nur an bestimmten Standorten zur Verfügung stehen.

Image       Eine Anwendung greift auf die Daten zu, benötigt aber nur bestimmte Attribute; auf gar keinen Fall dürfen Passwörter aus dem LDAP dort verfügbar sein.

Image       Ein anderer Dienst muss lediglich Authentifizierungen prüfen, braucht aber dafür keine Adressdaten Ihrer Kunden.

Jetzt gibt es zwei Möglichkeiten, wie Sie dafür sorgen können, dass nur bestimmte Teile Ihres Baums repliziert werden.

Einschränkung über ACLs

Sie können auf Ihren Providern für jeden Consumer einen eigenen Replikationsbenutzer einrichten und dann über ACLs dafür sorgen, dass die unterschiedlichen Replikationsbenutzer über ACLs in Ihren Rechten beschnitten werden. Das geht sowohl für ganze Teilbereiche eines Baums als auch für bestimmte Attribute und Objekte. So könnten Sie, wenn Sie unsere Beispielobjekte nutzen, je einen Consumer für die ou=produktion und einen für die ou=verwaltung einrichten. Genauso könnten Sie die Adressbücher der Mitarbeiter alle auf einen LDAP-Server replizieren, nicht aber dieMitarbeiterobjekte selbst.

Vorteil dieser Methode: Alle Berechtigungen werden zentral verwaltet, und auf den Consumern werden keine Einschränkungen der Zugriffe durch komplexe ACLs benötigt. Durch die Replikation der Konfiguration werden die Einschränkungen umgehend auf alle Provider übertragen, und es spielt keine Rolle, auf welchen Provider ein Consumer zugreift.

Nachteil dieser Methode: Auf den Consumern ist nicht erkennbar, welche Einschränkungen es gibt. Dadurch ist es oftmals schwer, das Fehlen von Attributen, Objekten oder gar Teilbäumen aufzuklären. Besonders dann, wenn die Administration aufgeteilt ist. Die ACLs auf den Providern werden komplexer, und Sie benötigen weitere simpleSecurityObjects für die einzelnen Replikationen.

Einschränkungen durch Filter

Bei der Einschränkung über Filter benötigen Sie nur einen Replikationsbenutzer, der alles auf Ihren Providern lesen darf. Sämtliche Einschränkungen werden immer auf den Consumern gesteuert. Auf den Consumern gibt es in der syncrepl-Direktive den Parameter filter. Hier können Sie alles an Filtern verwenden, was Sie in Kapitel 8, «LDAP-Filter», gelesen haben. Je mehr Sie filtern möchten, um so komplexer werden Ihre Filter.

Vorteile dieser Methode: Die Filterung findet lokal auf dem Consumer statt, und Sie können immer schnell sehen, welche Eigenschaften gefiltert werden. Alle Änderungen können direkt am Consumer vorgenommen werden, ein Zugriff auf den Provider ist nicht notwendig.

Nachteil der Methode: Sie müssen immer alle Consumer kontrollieren, um zu wissen, wo welche Einschränkung vorhanden ist. Alle Einschränkungen liegen dezentral. Wenn Sie eine geteilte Administration (unterteilt in Provider-Admins und Consumer-Admins) einsetzen, können Sie als Provider-Admin nicht verhindern, dass zu viel repliziert wird.

Selbstverständlich können Sie auch beide Methoden einsetzen. Es wäre sogar möglich, sowohl den Replikationsbenutzer einzuschränken und zusätzlich auf dem Consumer noch Filter zu setzen. Aber das wird sehr schnell unübersichtlich.

Image

Wichtig: Wenn Sie die Replikation einschränken wollen, schränken Sie immer nur die anschließend replizierten Objekte ein. Alle Objekte, die bereits auf dem Consumer vorhanden sind, bleiben davon unberührt. Schränken Sie die übertragenen Objekte ein, dann stoppen Sie den LDAP-Dienst, löschen die komplette Datenbank. Dann starten Sie den LDAP-Dienst neu und lassen die Objekte neu replizieren, dann werden auch die entsprechenden Einschränkungen übernommen. Eine gute Planung ist daher essenziell.

Image

12.5.1 Einschränkungen über ACLs einrichten

Der neue Consumer consumer02 soll seine Daten aus dem neuen Cluster erhalten, der wieder mit allen Daten gefüllt ist. Der consumer02 soll jetzt nur die Objekte der Abteilung ou=verwaltung replizieren. Dazu benötigen Sie jetzt eine neues simpleSecurityObject, das die benötigten Rechte über ACLs erhält. Listing 12.29 zeigt die LDIF-Datei für das von uns verwendete Objekt:

Listing 12.29 Replikationsbenutzer für die Verwaltung

dn: uid=repl-verwaltung,ou=users,dc=example,dc=net objectClass: account objectClass: simpleSecurityObject objectClass: top uid: repl-verwaltung userPassword: {ARGON2}$argon2i$v=19$m=4096,t=3,p=1$dnN....

Damit der Replikationsbenutzer auch nur noch die Daten der Abteilung ou=verwaltung lesen kann, benötigen Sie die ACL aus Listing 12.30:

Listing 12.30 Anpassung der ACLs auf dem Provider

dn: olcDatabase={2}mdb,cn=config changetype: modify delete: olcAccess olcAccess: {8} - delete: olcAccess olcAccess: {7} - delete: olcAccess olcAccess: {6} - delete: olcAccess olcAccess: {2} - delete: olcAccess olcAccess: {1} - add: olcAccess olcAccess: {1}to attrs=userPassword by anonymous auth by self write by dn.exact=uid=ldap-admin,ou=users,dc=example,dc=net write by dn.exact=uid=repl-user,ou=users,dc=example,dc=net read by dn.exact=uid=chain-user,ou=users,dc=example,dc=net write by dn.exact=uid=repl-verwaltung,ou=users,dc=example,dc=net read by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by set="[cn=pw-set,ou=groups,dc=example,dc=net]/Member* & user" write by * none - add: olcAccess olcAccess: {2} to attrs=shadowLastChange by anonymous auth by self write by dn.exact=uid=ldap-admin,ou=users,dc=example,dc=net write by dn.exact=uid=repl-user,ou=users,dc=example,dc=net read by dn.exact=uid=repl-verwaltung,ou=users,dc=example,dc=net read by dn.exact=uid=chain-user,ou=users,dc=example,dc=net write by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by set="[cn=pw-set,ou=groups,dc=example,dc=net]/Member* & user" write by * none - add: olcAccess olcAccess: {6} to dn.regex="ou=adressen,cn=(.+),ou=users,ou=(.+),ou=firma,\ dc=example,dc=net$" by dn.exact=uid=repl-verwaltung,ou=users,dc=example,dc=net read by dn.regex="$1,ou=users,ou=$2,ou=firma,dc=example,dc=net$" write by dn.exact=uid=repl-user,ou=users,dc=example,dc=net read by * none - add: olcAccess olcAccess: {5}to dn.sub=ou=verwaltung,ou=firma,dc=example,dc=net by set="this/manager & user" write by set="this/manager/secretary & user" write by dn.exact=uid=repl-verwaltung,ou=users,dc=example,dc=net read by "dn.children=ou=users,ou=verwaltung,ou=firma,dc=example,dc=net" read by * none - add: olcAccess olcAccess: {6}to dn.sub=ou=produktion,ou=firma,dc=example,dc=net by set="this/manager & user" write by set="this/manager/secretary & \ user" write by "dn.children=ou=users,ou=produktion,ou=firma,dc=example,dc=net" read by * none

Sie sehen hier, dass eine kleine Änderung der Zugriffsrechte einen erheblichen Aufwand bei der Änderung der ACLs mit sich bringen kann. Da der Replikationsbenutzer aufgrund der ursprünglichen ACL in der Lage war, die Adressbücher der Benutzer der Verwaltung zu lesen, mussten hier die ACLs für die Abteilungen vor die ACL für die Adressbücher gesetzt werden. Denn der Replikationsbenutzer für die Verwaltung soll ja auch die Adressbücher der Verwaltungsmitarbeiter replizieren können, nicht aber die der Produktionsmitarbeiter. Nachdem Sie die ACL eingespielt haben, testen Sie mit dem Kommando ldapsearch -x -D uid=repl-verwaltung,ou=users,dc=example,dc=net -W -LLL dn auf dem Provider, ob wirklich nur noch die Verwaltungsobjekte angezeigt werden.

Richten Sie den neuen Consumer wieder mit der Grundkonfiguration ein, um anschließend die Replikation einspielen zu können. Für die Replikation sehen Sie die LDIF-Datei in Listing 12.31:

Listing 12.31 Replikation mit Einschränkungen

dn: olcDatabase={2}mdb,cn=config changetype: modify replace: olcSyncRepl olcSyncrepl: rid=002 provider=ldaps://provider02.example.net tls_reqcert=allow type=refreshAndPersist retry="60 10 120 5" searchbase="dc=example,dc=net" scope=sub schemachecking=off bindmethod=simple binddn="uid=repl-verwaltung,ou=users,dc=example,dc=net" credentials=geheim syncdata=accesslog logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" olcSyncrepl: rid=003 provider=ldaps://provider03.example.net tls_reqcert=allow type=refreshAndPersist retry="60 10 120 5" searchbase="dc=example,dc=net" scope=sub schemachecking=off bindmethod=simple binddn="uid=repl-verwaltung,ou=users,dc=example,dc=net" credentials=geheim syncdata=accesslog logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))"

Neben dem geänderten binddn sehen Sie hier auch, dass wir hier beide Provider als Replikationspartner eingetragen haben. So kann die Replikation auch noch stattfinden, wenn einer der beiden Provider ausfällt. Der Einsatz eines Loadbalancers wäre hier eine Option. Die meisten Loadbalancer können die Anfragen aber nicht aufgrund des Protokolls durchführen und somit auch keine zwingend zusammenhängenden Verbindungen aufrechterhalten. Das kann eventuell zu einer fehlerhaften Replikation führen und somit zu einer defekten Datenbank auf dem Consumer.

Bei der Verwendung von DeltaSync ist es wichtig, dass Sie auf jeden Fall auch noch die Zugriffe auf das accesslog für den Replikationsbenutzer der Verwaltung auf dem Provider freigeben. Die passende Änderung der ACL sehen Sie in Listing 12.32:

Listing 12.32 ACL für das accesslog

dn: olcDatabase={3}mdb,cn=config changetype: modify delete: olcAccess olcAccess: {0} - add: olcAccess olcAccess: to dn.subtree="cn=accesslog" by dn.exact="cn=admin,dc=example,dc=net" read by dn.exact="uid=repl-user,ou=users,dc=example,dc=net" read by dn.exact="uid=repl-verwaltung,ou=users,dc=example,dc=net" read

OpenLDAP bringt aber ab der Version 2.6 einen eigenen Loadbalancer mit, der in der Lage ist, aufgrund des Protokolls und der gestellten Anfragen eine Verbindung eines Consumers fest an einen Provider zu binden. Mehr zum diesem Thema finden Sie in Kapitel 13, «Loadbalancer mit lloadd».

Nachdem Sie die Replikation eingespielt haben, lassen Sie sich alle Objekte einmal mit dem rootdn des Consumers auflisten, dann sollten Sie nur noch die gewünschten Objekte der Verwaltung sehen. Stimmt die Liste nicht mit den Verwaltungsobjekten auf dem Provider überein, prüfen Sie die ACLs und wiederholen Sie die Replikation.

Was kommt jetzt

Nachdem Sie die gewünschten Daten auf den Consumer repliziert haben, ist es jetzt an der Zeit, dafür zu sorgen, dass auch die Zugriffsrechte passen. Im Moment kann jeder den Consumer noch anonym abfragen und bekommt, mit Ausnahme der Passwörter, alles angezeigt. Wenn noch nicht geschehen, sollten sich dann alle Clients möglichst gegen den Consumer authentifizieren. Wenn Sie den sssd nutzen, passen Sie die Authentifizierungsquelle in der Konfiguration an.

Damit Ihre Mitarbeiter auch das Passwort ändern können, haben Sie zwei Möglichkeiten: Sie können im sssd den Parameter ldap_chpass_uri so anpassen, dass die Passwortänderung auf den Provider umgeleitet wird, oder Sie richten das Chaining ein. Dann versuchen die Mitarbeiter, das Passwort auf den Consumer zu schreiben. Dieser leitet die Anfrage aber an den Provider weiter.

Image

Tipp: Benötigen Sie mehrere identische Consumer für einen Bereich, können Sie auch dafür einen Cluster einrichten und so die Konfiguration für alle Consumer gemeinsam verwalten.

Image

12.5.2 Einschränkungen über Filter einrichten

Kommen wir jetzt zum zweiten Teil: Einschränkungen der Replikation über Filter. Ein weiterer Consumer soll lediglich die Attribute sn und cn und, wenn vorhanden, den givenName aller Benutzer der Abteilung Verwaltung erhalten.

Als Erstes benötigen Sie wieder einen Consumer, der sich gegen den Cluster oder einen einfachen Provider repliziert. Wie schon zuvor installieren Sie die Pakete und richten die Grundkonfiguration ein.

Dann folgt die Einrichtung der Replikation mit den entsprechenden Filtern. Listing 12.33 zeigt die LDIF-Datei:

Listing 12.33 Einschränkungen mit Filtern

dn: olcDatabase={2}mdb,cn=config changetype: modify replace: olcSyncRepl olcSyncrepl: rid=002 provider=ldaps://provider02.example.net tls_reqcert=allow type=refreshAndPersist retry="60 10 120 5" searchbase="ou=verwaltung,ou=firma,dc=example,dc=net" filter="(objectClass=inetOrgPerson)" attrs="cn,sn,givenName" scope=sub schemachecking=off bindmethod=simple binddn="uid=repl-user,ou=users,dc=example,dc=net" credentials=geheim syncdata=accesslog logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))" olcSyncrepl: rid=003 provider=ldaps://provider03.example.net tls_reqcert=allow type=refreshAndPersist retry="60 10 120 5" searchbase="ou=verwaltung,ou=firma,dc=example,dc=net" filter="(objectClass=inetOrgPerson)" attrs="cn,sn,givenName" scope=sub schemachecking=off bindmethod=simple binddn="uid=repl-user,ou=users,dc=example,dc=net" credentials=geheim syncdata=accesslog logbase="cn=accesslog" logfilter="(&(objectClass=auditWriteObject)(reqResult=0))"

Sie sehen hier, dass wir die Replikation mit unserem Replikationsbenutzer durchführen, der auf dem Provider alles lesen kann. Testen Sie den Zugriff über die Kommandozeile, können Sie das auch kontrollieren. Jetzt soll bei der Replikation gefiltert werden.

Wir haben hier drei verschiedene Möglichkeiten zur Filterung eingesetzt:

1.      searchbase=”ou=verwaltung,ou=firma,dc=example,dc=net”
Über den Parameter searchbase haben wir den Startpunkt der Suche eingeschränkt, nur die Objekte unterhalb von ou=verwaltung,ou=firma,dc=example,dc=net werden überhaupt repliziert.

2.      filter=”(objectClass=inetOrgPerson)”
Über den Parameter filter schränken wir die Replikation der Objekte noch weiter ein. Wir replizieren lediglich alle Objekte, die eine Objektklasse inetOrgPerson besitzen. Der Filter filtert alle Objekte mit der Objektklasse, aber nicht die Objektklasse selbst. Alle Objekte besitzen auch auf dem Consumer weiterhin alle Objektklassen, die Sie beim Anlegen des Objekts vergeben haben.

3.      attrs=”cn,sn,givenName”
Zusätzlich filtern wir über den Parameter attrs aus den Objekten lediglich die Attribute cn, sn und givenName aus.

Damit haben Sie jetzt zwei verschiedene Möglichkeiten, Teilreplikationen auf einen Consumer durchzuführen, wenn Sie eine Teilreplikation nutzen wollen und sich nicht sicher sind, welche Art für Sie der bessere Weg ist. Denken Sie dran: Sie können die Art der Replikationsbeschränkung jederzeit ändern.

12.5.3 Überprüfung der Replikation mit slapd-watcher

Beim Einsatz von OpenLDAP, gerade in einer Multi-Provider-Umgebung, stellt sich immer wieder die Frage: Funktioniert meine Replikation? Wie ausgelastet sind meine Server? Die Nutzung des monitor-Backend beantwortet die Fragen schon sehr genau. Gerade in einer Multi-Provider-Umgebung, in der auch noch die Konfiguration repliziert wird, sollten Sie auf gar keinen Fall auf den Einsatz von Monitoringsoftware verzichten. Alle aktuellen Systeme zum Monitoring unterstützen das monitor-Backend von OpenLDAP.

Mit der neuen Version (2.5.x und 2.6.x) des OpenLDAP ist aber auch ein kleines Kommandozeilenwerkzeug dazugekommen, mit dem Sie recht einfach viele Informationen über den Zustand der OpenLDAP-Server und der Replikation erhalten können.

Das Kommando heißt slapd-watcher und ist in allen aktuellen Versionen vorhanden. Als Parameter werden die zu überprüfenden Server angegeben und ein Benutzer mit Passwort, der die Informationen auch auslesen kann. Das Listing 12.34 zeigt den Aufruf und die Informationen, die Sie erhalten:

Listing 12.34 Informationen zur Replikation mit slapd-watcher

root@provider02:~# slapd-watcher -b dc=example,dc=net ldaps://provider02.\ example.net ldaps://provider02.example.net -x -D \ cn=admin,dc=example,dc=net -w geheim ldaps://provider02.example.net Entries Bind Unbind Search Compare Modify \ Num 42 25 20 67 0 2 \ Num/s 0.00 0.00 0.00 0.40 0.00 0.00 \ ModDN Add Delete Abandon Extended 0 0 0 0 0 0.00 0.00 0.00 0.00 0.00 contextCSN: 20230220092655.930711Z#000000#001#000000 idle contextCSN: 20230215190939.003656Z#000000#002#000000 idle, sync’d ldaps://provider02.example.net Entries Bind Unbind Search Compare Modify \ Num 42 25 20 69 0 2 \ Num/s 0.00 0.00 0.00 0.40 0.00 0.00 \ ModDN Add Delete Abandon Extended 0 0 0 0 0 0.00 0.00 0.00 0.00 0.00 contextCSN: 20230220092655.930711Z#000000#001#000000 idle, sync’d contextCSN: 20230215190939.003656Z#000000#002#000000 idle

Über die verschiedenen Werte können Sie so sehr schnell sehen, ob die Replikation funktioniert. Die Anzahl der Entries sollte bei einer Multi-Provider-Umgebung auf allen Servern identisch sein. Auch können Sie hier sehr schnell sehen, ob ein Provider stärker ausgelastet ist als alle anderen. Sollte z.B bei einem der Server die Anzahl der Search-Einträge erheblich von den anderen abweichen, kann das daran liegen, dass bestimmte Clients immer nur einen der Server abfragen.

Eine Überprüfung der Replikation zwischen einem Provider und einem Consumer ist mit slapd-watcher auch möglich. Aber denken Sie daran, dass die Auslastung eines Consumers komplett unterschiedlich zu der eines Providers sein wird. Viele Clients greifen auf den Consumer zu, auf den Provider eventuell nur die Consumer. Auch kann die Anzahl der Einträge variieren, denn auf manchen Consumern haben Sie eventuell eine Teilreplikation eingerichtet.

Der Einsatz von slapd-watcher kann kein Monitoring ersetzen, sondern dient dazu, schnell Informationen des Zustands Ihrer Server zu bekommen.

12.5.4 Troubleshooting mit CSN

Besonders in Multi-Provider-Umgebungen wird der Sinn der Context Sequence Number (CSN) deutlich. Der Aufbau dieses Zeitstempels ist

YYYYmmddHHMMSSz.uuuuuu#<Zähler>#<ServerID>#000000

In Tabelle 12.1 ist die Bedeutung der einzelnen Felder dargestellt.

Die CSN zeigt also an, wann und an welchem Provider eine Änderung an einem Objekt (entryCSN) oder einem Kontext (contextCSN) durchgeführt wurde.

Solange Sie nur einen Provider in Ihrer Umgebung einsetzen, kann eine Änderung nur dort durchgeführt werden, und in dem Feld <ServerID> des CSN wird immer der gleiche Wert (000) stehen. Nachdem Sie eine Umgebung aus zwei oder mehr Providern aufgebaut haben, an denen Änderungen vorgenommen werden können, wird dieses Feld interessant und kann Ihnen bei der Fehlersuche helfen.

Wir wollen uns zunächst die beiden CSNs entryCSN (also die CSN eines Objekts) und die contextCSN (die CSN eines Kontexts) anschauen. Führen Sie dazu einen Befehl wie in Listing 12.35 aus:

Listing 12.35 entryCSN und contextCSN

root@provider02:~# ldapsearch -x -D "uid=ldap-admin,ou=users,\ dc=example,dc=net" -W ’(cn=u1 prod)’ -LLL + Enter LDAP Password: dn: cn=u1 Prod,ou=users,ou=Produktion,ou=firma,dc=example,dc=net structuralObjectClass: inetOrgPerson entryUUID: a26e126e-43d4-103d-93fd-275a2c4d4501 creatorsName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth createTimestamp: 20230218123639Z entryCSN: 20230218123639.160003Z#000000#001#000000 modifiersName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth modifyTimestamp: 20230218123639Z entryDN: cn=u1 Prod,ou=users,ou=Produktion,ou=firma,dc=example,dc=net subschemaSubentry: cn=Subschema hasSubordinates: TRUE root@provider02:~# ldapsearch -x -D "uid=ldap-admin,ou=users,\ dc=example,dc=net" -W ’(dc=example)’ -LLL + Enter LDAP Password: dn: dc=example,dc=net structuralObjectClass: domain entryUUID: 50d1470c-41b1-103d-8caf-c9cec2658c9f creatorsName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth createTimestamp: 20230215191847Z entryCSN: 20230215191847.525846Z#000000#001#000000 modifiersName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth modifyTimestamp: 20230215191847Z contextCSN: 20230218155040.702316Z#000000#001#000000 contextCSN: 20230215190939.003656Z#000000#002#000000 entryDN: dc=example,dc=net subschemaSubentry: cn=Subschema auditContext: cn=accesslog hasSubordinates: TRUE

Aus der Ausgabe des ersten Befehls können Sie Folgendes ablesen:

Image       Das Benutzerobjekt wurde am 18.02.2023 um 12:36:39 Uhr (GMT) angelegt: siehe createTimestamp.

Image       Das Objekt wurde seitdem nicht geändert, der modifyTimestamp ist identisch mit dem createTimestamp.

Image       Die letzte Änderung (also seine Erstellung) des Objekts hat auf dem Server mit der ID 001 stattgefunden: siehe (entryCSN).

Die zweite Ausgabe liefert Ihnen die Informationen zum Kontext dc=example,dc=net des Objekts. Hier tritt (neben der entryCSN des Kontextobjekts selbst) nun auch die contextCSN auf, die für die Replikation der Datenbanken zum Vergleich der Aktualität auf den einzelnen Replikationsservern genutzt wird. Im vorliegenden Beispiel waren also die letzten Änderungen an der Datenbank auf dem Server mit der ServerID

Image       001 am 15.02.2023 um 19:09:39 Uhr

Image       002 am 18.02.2023 um 15:50:40 Uhr

Alle Zeiten sind GMT. In Listing 12.36 sehen Sie, wie sich eine Änderung an einer Replik auf dem Server ldap03 mit der ServerID: 1 auf die entryCSN und die contextCSN auswirkt:

Listing 12.36 Objektänderung und CSN

root@provider02:~# cat description-u1-prod.ldif dn: cn=u1 prod,ou=users,ou=produktion,ou=firma,dc=example,dc=net changetype: modify add: description description: Ein Benutzer der Produktion root@provider02:~# ldapmodify -x -D uid=ldap-admin,ou=users,dc=example,\ dc=net -W -f description-u1-prod.ldif modifying entry cn=u1 prod,ou=users,ou=produktion,ou=firma,dc=example,dc=net root@provider02:~# ldapsearch -x -D "uid=ldap-admin,ou=users,dc=example,\ dc=net" -W ’(cn=u1 prod)’ -LLL + Enter LDAP Password: dn: cn=u1 Prod,ou=users,ou=Produktion,ou=firma,dc=example,dc=net structuralObjectClass: inetOrgPerson entryUUID: a26e126e-43d4-103d-93fd-275a2c4d4501 creatorsName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth createTimestamp: 20230218123639Z entryCSN: 20230220092655.930711Z#000000#001#000000 modifiersName: uid=ldap-admin,ou=users,dc=example,dc=net modifyTimestamp: 20230220092655Z entryDN: cn=u1 Prod,ou=users,ou=Produktion,ou=firma,dc=example,dc=net subschemaSubentry: cn=Subschema hasSubordinates: TRUE root@provider02:~# ldapsearch -x -D "uid=ldap-admin,ou=users,\ dc=example,dc=net" -W ’(dc=example)’ -LLL + Enter LDAP Password: dn: dc=example,dc=net structuralObjectClass: domain entryUUID: 50d1470c-41b1-103d-8caf-c9cec2658c9f creatorsName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth createTimestamp: 20230215191847Z entryCSN: 20230215191847.525846Z#000000#001#000000 modifiersName: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth modifyTimestamp: 20230215191847Z contextCSN: 20230220092655.930711Z#000000#001#000000 contextCSN: 20230215190939.003656Z#000000#002#000000 entryDN: dc=example,dc=net subschemaSubentry: cn=Subschema auditContext: cn=accesslog hasSubordinates: TRUE

Nach der Änderung der description ändert sich beim Objekt außer der modifyTimestamp auch die entryCSN. Die Zeit ist dabei identisch (20.02.2023, 09:26:55 Uhr (GMT)). Die contextCSN des Kontexts dc=example,dc=net wurde für den Server mit der ServerID 002 (also provider02) aktualisiert.

Daran, dass die Abfragen nach dem Objekt und dem Kontext auf den beiden anderen Servern durchgeführt wurden und die erwarteten Ergebnisse zeigen, sehen Sie, dass die Replikation hier erfolgreich war und die Änderung auf alle beteiligten Server repliziert wurde.

Die CSN liefert Ihnen damit also nützliche Informationen, sollten Probleme mit der Replikation auftreten.