Replikation stellt sicher, dass der Verzeichnisdienst LDAP verfügbar ist. Seit Version 2.4 funktioniert sie auch dann, wenn ein Master ausfällt. Das Zauberwort heißt Multimaster-Replikation.
Verzeichnisdienste sind in großen Netzwerken fast unverzichtbar, zugleich fällt es schnell auf, wenn Authentifizierung, Autorisierung oder Zertifikatsverwaltung schlecht verfügbar sind. Der Artikel erklärt, wie der Admin einen Open-LDAP-Server für den Masterbetrieb konfiguriert [1], der dann als Vorlage für einen weiteren Masterserver dient.
Wie Abbildung 1 zeigt, lässt sich diese Two-Way-Multimaster-Replikation leicht um einen Zusatzknoten erweitern. Traditionell heißen die an der Replikation beteiligten Server Master und Slave. Jeder Master dient dabei zugleich als Slave für jeden anderen Master. Zwei Knoten bilden also zwei überkreuzte Master-Slave-Umgebungen.
Open LDAP 2.4: Replikation
Dieses Modell der Replikation ([1], [2])klappt erst seit Version 2.4 von Open LDAP, zuvor funktionierte Replikation noch etwas anders [3].
Auf den Master, der als Verzeichnisdienst dient, greifen die Clients schreibend zu. Der Slave erlaubt hingegen nur den Lesezugriff, auf ihn wird repliziert. Open LDAP gleicht Master und Slave über die LDAP Sync Replication Engine (»syncrepl« [4]) ab.
Seit Open LDAP 2.4 gilt diese strikte Unterteilung der Server in Master und Slave nicht mehr. Es ist nun möglich, einen Directory Information Tree (DIT) zwischen mehreren Mastern synchron zu halten. Der Slave heißt im LDAP-Kontext Consumer und fungiert als Client gegenüber dem Server. Den bezeichnen die LDAP-Entwickler als Provider. Auf einem Knoten laufen meist ein Consumer und ein Provider, die – wie erwähnt – über Kreuz miteinander kommunizieren. Nach diesem Schema konfiguriert der Admin mit mehreren LDAP-Servern eine n-Way-Multimaster-Replikation.
Der Consumer baut dabei periodisch die Verbindung zum Provider auf und fragt entweder die Änderungen aktiv ab (Consumer Poll, »refreshOnly« ) oder wartet darauf, dass der Provider ihm diese sendet (Provider Push, »refreshAndPersist« , Abbildung 2). Dabei kann ein Consumer alle Provider kontaktieren, deren Zugangsdaten er kennt. Im Produktivbetrieb sollte der Admin die Verbindungen unbedingt verschlüsseln.
Bezugsquelle
Die nun gezeigten Beispiele laufen auf einem aktuellen Centos 7, lassen sich jedoch relativ einfach auf andere Distributionen übertragen [5]. Dort heißt unter Umständen das Verzeichnis für die Konfigurationsdateien anders oder die installierte Grundkonfiguration weicht etwas vom beschriebenen Schema ab.
Die Installation auf Centos 7 beziehungsweise RHEL 7 erfordert das RPM-Paket »openldap-servers« . Im Artikel konfiguriert der Admin Open LDAP ausschließlich über »slapd-config« , eine dynamische Engine zur Laufzeitkonfiguration. Sie existiert als eigene LDAP-Datenbank mit dem Index »{0}« , ihr Distinguished Name (DN) lautet »cn=config« .
Im Gegensatz zu LDAP-Datenbanken wie der Berkley DB (DBD) oder deren Weiterentwicklung HDB befinden sich die Konfigurationsdateien für »slapd-config« nicht im Datenbankverzeichnis von Open LDAP, sondern liegen im lesbaren LDAP Data Interchange Format (LDIF) im Dateisystem unter »/etc/openldap/slapd.d/cn=config« . Im Notfall kann der Admin sie also direkt verändern.
Der übliche Weg, um die LDAP-Konfiguration anzupassen, führt jedoch über die LDAP-Clients »ldapadd« , »ldapdelete« und »ldapmodify« oder einen beliebigen LDAP-Browser. Sie setzen Änderungen zur Laufzeit um und aktivieren diese unmittelbar, ohne dass der Admin den »slapd« -Daemon neu starten muss.
Er sollte also darauf achten, diese Dateien nur im Notfall direkt zu ändern. Vor dem Neustart prüft er die modifizierte Konfiguration zudem am besten mit »slaptest« auf ihre Korrektheit. Konfiguriert er LDAP hingegen im laufenden Betrieb über »slapd-config« , nimmt die Engine die Syntax- und Integritätsprüfung automatisch vor.
Overlay-Module laden
Neben den Server-Binaries (in »openldap-servers« ) braucht der Administrator zusätzlich die Clientprogramme, die unter Centos im Paket »openldap-clients« stecken.
Listing 1
syncprov.ldif
01 dn: cn=module,cn=config 02 objectclass: olcModuleList 03 cn: module 04 olcModuleLoad: syncprov.la
Listing 2
auth-hdb.ldif
01 dn: olcDatabase={2}hdb,cn=config
02 changetype: modify
03 replace: olcRootPW
04 olcRootPW: {SSHA}RE2+mfUgNjJa4iIq2Rgw+rMr1FEs1czF
05 -
06 replace: olcSuffix
07 olcSuffix: dc=example,dc=local
08 -
09 replace: olcRootDN
10 olcRootDN: cn=manager,dc=example,dc=local
Die Backend-Module der Datenbank sind gewöhnlich statisch gelinkt, Open LDAP muss sie nicht dynamisch laden. Für Overlay-Module, die sich als zusätzliche Schicht auf die Datenbank beziehungsweise die Teilbäume (DIT) legen lassen, gilt dies hingegen in der Regel nicht. Die Replikation mit Hilfe von »syncrepl« benötigt für den Provider das Modul »syncprov« (Abbildung 2).
Über den Unix-Socket (»ldapi« ) erhält »root« den Vollzugriff auf »cn=config« . Über
$ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config olcModuleLoad
erfragt er, ob Open LDAP das Modul »syncprov« bereits geladen hat. Gleiches gilt für Schemata, die sich als Kinder unterhalb von »cn=schema,cn= config« befinden:
$ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn
Muss Open LDAP das Modul noch laden, zeigt Listing 1 den erforderlichen LDIF-Code, um den der Admin die Konfiguration ergänzt. Das Kommando
$ldapadd -Q -Y EXTERNAL -H ldapi:/// -f ~/syncprov.ldifadding new entry "cn=module,cn=config"
das die Aktion zur Laufzeit umsetzt, unterstützt ihn hierbei.
Ein Schema dazu
Auch wenn der Admin keinen der in Betrieb befindlichen LDAP-Server auf Replikation umrüstet, benötigt er neben dem Core- noch das Cosine-Schema, um zumindest eine Domäne anzulegen. Bei Centos/RHEL 7 lädt er es über:
$ldapadd -Q -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldifadding new entry "cn=cosine,cn=schema,cn=config"
Die LDIF-Datei »auth-hdb.ldif« , die das DN »dc=example,dc=local« , den administrativen Account »cn=manager« sowie den Passwort-Hash beherbergt, zeigt Listing 2. Den Hash für »olcRootPW« erzeugt »slappasswd« , der im Beispiel verwendete passt zum Kennwort »secret« :
$ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f ~/auth-hdb.ldifmodifying entry "olcDatabase={2}hdb,cn=config"
Listing 3 enthält hingegen die Datei »domain.ldif« , über die der LDAP-Betreiber die Domäne »dc=example,dc=local« einrichtet:
$ldapadd -D cn=manager,dc=example,dc=local -W -f ~/domain.ldifadding new entry "dc=example,dc=local"
Listing 3
domain.ldif
01 dn: dc=example,dc=local 02 objectClass: domain
Listing 4
auth-config.ldif
01 dn: olcDatabase={0}config,cn=config
02 changetype: modify
03 replace: olcRootDN
04 olcRootDN: cn=admin,cn=config
05 -
06 add: olcRootPW
07 olcRootPW: {SSHA}RE2+mfUgNjJa4iIq2Rgw+rMr1FEs1czF
Es ergibt Sinn, auch die »slapd-config« -Konfiguration zu replizieren. Listing 4 legt dafür in der Datei »auth-config.ldif« den Account »cn=admin,cn=config« an:
$ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f ~/auth-config.ldifmodifying entry "olcDatabase={0}config,cn=config"
Listing 5 richtet in der Datei »provider.ldif« jeweils einen Provider für die »slapd-config« der »{0}config« und der Nutzdatenbank »hdb{2}« ein:
$ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f /vagrant/ldif/provider.ldifadding new entry "olcOverlay=syncprov,olcDatabase={0}config,cn=config"adding new entry "olcOverlay=syncprov,olcDatabase={2}hdb,cn=config"modifying entry "cn=config"
Weil Listing 5 die IP-Adressen im Bereich »olcServerID« auflistet, muss der Admin auf Centos/RHEL 7 diese IP auf den jeweiligen Knoten explizit in die Datei »/etc/sysconfig/slapd« (Listing 6) eintragen, samt dem zugehörigen Protokoll.
Listing 5
provider.ldif
01 dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config
02 changetype: add
03 objectClass: olcOverlayConfig
04 objectClass: olcSyncProvConfig
05 olcOverlay: syncprov
06
07 dn: olcOverlay=syncprov,olcDatabase={2}hdb,cn=config
08 changetype: add
09 objectClass: olcOverlayConfig
10 objectClass: olcSyncProvConfig
11 olcOverlay: syncprov
12
13 dn: cn=config
14 changetype: modify
15 add: olcServerID
16 olcServerID: 0x001 ldap://192.168.0.11
17 olcServerID: 0x002 ldap://192.168.0.12
Listing 6
/etc/sysconfig/slapd auf Knoten 1
01 # - default: ldapi:/// ldap:/// 02 # - example: ldapi:/// ldap://127.0.0.1/ ldap://10.0.0.1:1389/ ldaps:/// 03 SLAPD_URLS="ldapi:/// ldap://127.0.0.1 ldap://192.168.0.11"
Authentisch
Wie oben erwähnt geht der Verbindungsaufbau immer vom Consumer aus. Er erzeugt für jeden Provider ein »olcSyncRepl« -Objekt. Dessen Attribute geben das Ziel, die Authentifizierungs-Methode, den Account, den zu replizierenden DIT und den Replikationstyp an. Typen sind »refreshOnly« und »refreshAndPersist« (siehe Kasten “Verbindungstypen”).
Verbindungstypen
Beim Verbindungstyp »refreshOnly« sendet der Consumer zuerst das Sync-Cookie (Abbildung 2, rechts) mit einer Sequenznummer (Change Sequence Number, »contextCSN« ) sowie einem erforderlichen Zeitstempel des letzten erfolgreichen Abgleichs, des Checkpoints.
Der Provider durchläuft in seiner Reaktion auf die Suchanfrage, die sich auf einen DIT oder auf einzelne Attribute beziehen kann, zwei Phasen. In der »present« -Phase (Punkt 3 in Abbildung 2) enthält seine Antwort Informationen über alle im Baum existierenden Einträge. Genauer: über all jene Einträge, die sich geändert haben, den kompletten Eintrag inklusive dessen DN sowie die »entryUUID« . Für unveränderte Einträge sendet er bloß einen leeren Eintrag mit DN und »entryUUID« .
Es folgt die »delete« -Phase (Punkt 4). In ihr schickt der Provider für gelöschte Einträge ebenfalls leere Einträge mit DN und »entryUUID« an den Consumer zurück. Der Slave entfernt sie aus seinem Directory Information Tree. Am Ende der beiden Phasen sendet der Provider ein neues Sync-Cookie (Punkt 5). Beim »refreshOnly« -Ansatz beendet der Provider nun die Verbindung (Punkt 6). Der Consumer sichert das Sync-Cookie, um es bei einer künftigen Verbindung wieder an den Provider zu übertragen. Das schränkt den Suchbereich auf den Provider ein und erhöht die Geschwindigkeit der Antwort.
Beim »refreshAndPersist« -Ansatz ist der Ablauf bis Punkt 5 identisch. Danach baut der Provider die Verbindung jedoch nicht ab, sondern sie bleibt bestehen (Punkt 6). Der Provider sendet Änderungen nun unmittelbar an den Consumer und versorgt diesen jeweils mit neuen Sync-Cookies (Punkt 7).
Die LDIF-Datei »consumer.ldif« (Listing 7) aktiviert die Consumer. Der Admin integriert sie über
$ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f /vagrant/ldif/consumer.ldifmodifying entry "olcDatabase={0}config,cn=config"modifying entry "olcDatabase={2}hdb,cn=config"
in die »slapd-config« . Die fortlaufende »rid« bezieht sich nicht auf die »ServerID« des Providers. Die Option »retry« bewirkt, dass der Consumer 5 Sekunden nach einem Abbruch versucht, die Verbindung wiederherzustellen. Den »timeout« muss er, abhängig von der Entfernung der Server, womöglich heraufsetzen.
Listing 7
consumer.ldif (Auszug)
01 dn: olcDatabase={0}config,cn=config
02 changetype: modify
03 add: olcSyncRepl
04 olcSyncRepl: rid=001
05 provider=ldap://192.168.0.11
06 binddn="cn=admin,cn=config"
07 bindmethod=simple
08 credentials="secret"
09 searchbase="cn=config"
10 type=refreshAndPersist
11 retry="5 +"
12 timeout=1
13 olcSyncRepl: rid=002
14 provider=ldap://192.168.0.12
15 [...]
21 -
22 add: olcMirrorMode
23 olcMirrorMode: TRUE
24
25 dn: olcDatabase={2}hdb,cn=config
26 changetype: modify
27 add: olcSyncRepl
28 olcSyncRepl: rid=011
29 provider=ldap://192.168.0.11
30 binddn="cn=manager,dc=example,dc=local"
31 bindmethod=simple
32 credentials="secret"
33 searchbase="dc=example,dc=local"
34 type=refreshAndPersist
35 retry="5 +"
36 timeout=1
37 olcSyncRepl: rid=012
38 provider=ldap://192.168.0.12
39 [...]
46 -
47 add: olcMirrorMode
48 olcMirrorMode: TRUE
Die Suche der zu synchronisierenden Objekte im Provider berücksichtigt Zeitstempel. Es ist daher wichtig, dass die Zeit auf Consumern und Providern synchron läuft, ein NTP-Daemon ist unerlässlich. Größere Datenbestände steigern den Suchaufwand nach zu replizierenden Objekten mitunter stark. Hier verbessert es die Performance, wenn der Admin für Objekte wie »entryUUID« und »entryCSN« je einen Index setzt. Der Befehl
$ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f /vagrant/ldif/index.ldif
ergänzt die Konfiguration mit dem Index, den Listing 8 erstellt.
Doppelknoten
Damit endet die Konfiguration des ersten Knotens. Den zweiten, der schon als Provider und Consumer angelegt ist, erzeugt der Admin nun einfach aus dem ersten oder einfacher gesagt: er klont ihn. Jeden weiteren Knoten setzt er auf analoge Weise auf, muss aber Consumer und Provider jeweils in der »slapd-config« -Datenbank ergänzen.
Listing 8
index.ldif
01 dn: olcDatabase={2}hdb,cn=config
02 changetype: modify
03 add: olcDbIndex
04 olcDbIndex: entryUUID eq
05 olcDbIndex: entryCSN eq
Für den Klonprozess genügt es, mit »slapcat« eine Sicherung zu erstellen und diese auf dem zweiten Host einzuspielen. Das Beispiel berücksichtigt beim Replizieren auch die »slapd-config« , es reicht also aus, diese Datenbank zu übertragen. Damit setzt beim Start des »slapd« -Daemon die Replikation automatisch ein und synchronisiert auch die »hbd{2}« . Wäre diese jedoch schon gut gefüllt, könnte der Admin auch sie auf den zweiten Knoten übertragen.
Wie schon beim ersten Server muss der Admin nach erfolgter Installation der Pakete die Datei »/etc/sysconfig/slapd« wie in Listing 9 anpassen.
Listing 9
/etc/sysconfig/slapd auf Knoten 2
01 # - default: ldapi:/// ldap:/// 02 # - example: ldapi:/// ldap://127.0.0.1/ ldap://10.0.0.1:1389/ ldaps:/// 03 SLAPD_URLS="ldapi:/// ldap://127.0.0.1 ldap://192.168.0.12"
Der Admin kann die Sicherung erst auf dem zweiten Knoten einspielen, nachdem er den Dienst »slapd« angehalten und den kompletten Inhalt der Verzeichnisse »/etc/openldap/slapd.d/« und »/var/lib/ldap/« gelöscht hat. Die Verzeichnisse selbst benötigt er noch. Die Sicherung auf Knoten 1 erfolgt bei laufendem Dienst mit:
$slapcat -n 0 -F /etc/openldap/slapd.d -l backup.ldif
Die Sicherungsdatei »backup.ldif« kopiert er auf Knoten 2 an einen Ort, auf den der User »ldap« Zugriff hat, zum Beispiel das Verzeichnis »/tmp« . Dort spielt er die Datenbank mit Index Null ins nun leere Verzeichnis »/etc/openldap/slapd.d« :
$sudo -u ldap slapadd -n 0 -F /etc/ openldap/slapd.d -l /tmp/backup.ldif
Sollten als Untersatz RHEL oder Centos 7 zum Einsatz kommen, gilt es, den Kasten “Bug in RHEL/Centos 7” zu beachten. Startet der Admin nun den »slapd« , repliziert Open LDAP auch den Inhalt der Nutzdatenbank »hdb{2}« und »cn=manager,dc=example,dc=local« kann ab sofort über den Knoten 2 auf diese zugreifen. Ob die Instanzen synchron laufen, überprüft:
$ldapsearch -H ldap://192.168.0.11 -D cn=admin,cn=config -b cn=config -W -LLL -s base contextCSN
Die Ausgabe für den Wert »contextCSN« muss mit dem übereinstimmen, den eine Abfrage an »192.168.0.12« ergibt. Äquivalent lässt sich auch der Zustand der Replikation von »dc=example,dc=local« erfragen.
Ausblick
Im produktiven Einsatz sollte der Admin die Replikation am besten über ein dediziertes Netzwerk vornehmen oder mit einer Verschlüsselung absichern, da LDAP die Passworte im Klartext überträgt. Zum Verschlüsseln kann er SSL über »ldaps« oder auch TLS mittels »starttls« verwenden. Beides lässt sich für Consumer einrichten.
Bug in RHEL/Centos 7
Leider hat sich in die Grundkonfiguration von Open LDAP auf RHEL/Centos 7 ein Bug [6] eingeschlichen. Er macht sich bei dem Zurücksichern der »slapd-config« -Datenbank »{0}config,cn=config« mit »slapadd« bemerkbar. In der Datei »/etc/openldap/slapd.d/cn=config/olcDatabase={-1}frontend.ldif« muss der Wert für »olcDatabase« »{-1}frontend« lauten. Das kann der LDAP-Betreiber mit einem Editor korrigieren, den Service »slapd« muss er danach neu starten.
Wie bei allen High-Availability-Diensten muss er zudem die Verfügbarkeit und den Zustand der Datenreplikation überwachen. Hierfür kommen bekannte Monitoring-Lösungen wie Icinga, Shinken oder Nagios in Betracht, ein geeignetes Plugin liefert [7].
Mit der Delta-Replikation bietet Open LDAP eine noch effizientere Methode der Replikation. Deren Konfiguration ist allerdings deutlich komplexer und erfordert ein weiteres Overlay-Modul, das auf den Namen »accesslog« hört. Weiterführende Informationen zur Delta-Replikation finden Interessierte unter [8].
Infos
- Replikation in LDAP: http://www.zytrax.com/books/ldap/ch7/
- Replikation in LDAP (BSI): https://www.bsi.bund.de/DE/Themen/ITGrundschutz/ITGrundschutzKataloge/Inhalt/_content/m/m04/m04389.html
- Volker Schwaberow, “Bäumchen repliziere dich”: Linux-Magazin 08/07, S. 52, https://www.linux-magazin.de/Ausgaben/2007/08/Baeumchen-repliziere-dich/
- LDAP Sync Replication Engine: http://www.openldap.org/doc/admin23/syncrepl.html
- Open-LDAP-Server unter Ubuntu: https://help.ubuntu.com/lts/serverguide/openldap-server.html
- Centos/RHEL-7-Bug: https://bugs.centos.org/view.php?id=8631
- Open-LDAP-Monitoring: http://ltb-project.org/wiki/documentation/nagios-plugins/check_ldap_syncrepl_status
- Effizienteres »delta-syncrepl« : http://en.wikipedia.org/wiki/OpenLDAP#delta-syncrepl







