13.6 LDAP
In modernen Rechnernetzen und vor allem in heterogenen Umgebungen wird auch oft das Lightweight Directory Access Protocol (LDAP) eingesetzt. LDAP ist wie NIS ein Verzeichnisdienst, der jedoch nicht auf RPC basiert. Im Vergleich zu einer normalen relationalen SQL-Datenbank hat LDAP folgende Vorteile:
- Optimiert auf Lesen
LDAP ist für den lesenden Zugriff optimiert. Mit anderen Worten: Das Schreiben von Daten kann relativ lange dauern. - Erweiterte Suchfunktionen
Um den lesenden Zugriff auf die Daten weiter zu optimieren, stellt LDAP verschiedene, sehr flexible Suchfunktionen zur Verfügung. - Erweiterbare Datenstrukturen
LDAP erlaubt es, seine zugrunde liegenden Datenstrukturen – sogenannte Schemata – zu erweitern und so den Bedürfnissen des Dienstbetreibers gerecht zu werden. - Standardkompatibilität
LDAP ist ein in verschiedenen RFCs spezifiziertes Protokoll, wodurch die Interoperabilität zwischen verschiedenen Implementierungen gewährleistet wird. [Fn. Hierin besteht auch ein Gegensatz zu SQL: Zwar ist die SQL-Syntax auf verschiedenen Datenbanken fast gleich, jedoch gibt es Unterschiede bei komplexen Details wie Stored Procedures etc.] - Verteilte Daten
Die Daten eines LDAP-Baums können im Netzwerk verteilt gespeichert werden. LDAP nutzt außerdem verschiedenste Replizierungstechniken, um die Daten im Netzwerk zu verteilen und vor allem konsistent zu halten. Außerdem ist LDAP so sehr gut skalierbar.
Flexible Datenbank
LDAP eignet sich nun aber nicht nur zur Speicherung von Benutzerdaten. Aufgrund der flexiblen Struktur und der Ausrichtung auf statische, selten veränderte Daten können fast beliebige Informationen in einem LDAP-Baum [Fn. Ein LDAP-Verzeichnisdienst ist hierarchisch aufgebaut und besitzt somit eine Baumstruktur: Er besteht aus einer Wurzel, einigen Verzweigungen und vielen Blättern.] gespeichert werden.
Eine häufige Anwendung sind zum Beispiel Telefonlisten – es bietet sich an, auch weitere benutzerdefinierte Informationen in einer LDAP-Datenbank zu speichern, wenn man sie schon zur Benutzerverwaltung nutzt – oder auch eine Übersicht über verschiedene Rechner.
Ein paar Beispiele für häufig in LDAP-Datenbanken gespeicherte Daten sind:
- Benutzer und Gruppen
- IP-Dienste und -Protokolle
- NIS-Netzwerkgruppen
- Boot-Informationen
- Mountpunkte für Dateisysteme
- IP-Hosts und -Netzwerke
- RFC-822-konforme Mail-Aliase
13.6.1 So funktioniert es
Bevor wir eine Beispielkonfiguration zur Benutzerverwaltung betrachten, wollen wir zuerst die Funktionsweise von LDAP anhand der OpenLDAP-Implementierung erläutern. OpenLDAP ist auf Linux und BSD standardmäßig verfügbar und kann auch auf anderen Unix-Systemen eingerichtet werden.
Ein eindeutiger Name
Ein Eintrag (engl. entry) in einem LDAP-Verzeichnis besteht aus Attributen (engl. attributes) und wird durch einen eindeutigen Namen (engl. distinguished name, dn) identifiziert.
Listing 13.32 Beispiel für den distinguished name (dn) eines Eintrags
cn=Sebastian,ou=members,dc=doomed-reality,dc=org
Welche Attribute ein Eintrag haben kann, wird von dessen Objektklasse(n) bestimmt. Diese Objektklassen sind wiederum in Schemata definiert. Dort ist festgelegt, wie die Attribute einer Objektklasse heißen, welche Werte zulässig sind und ob ein Attribut jeweils notwendig oder optional ist. Jeder Eintrag in der Datenbank enthält dann die Attribute der Klassen dieses Eintrags.
Die Attribute eines Eintrags besitzen einen bestimmten Namen und entsprechend einen oder mehrere Werte. So steht zum Beispiel der Attributname cn als Abkürzung für common name und erlaubt als Argument eine normale Zeichenkette – im Regelfall den Namen einer Person. Im Gegensatz dazu steht mail für email address und erlaubt eine Mail-Adresse der Form johannes.ploetner@gmx.de. Aber auch binäre Daten wie ein Bild eines Benutzers im Feld jpegPhoto sind möglich.
13.6.2 Einen LDAP-Server konfigurieren
Die Konfiguration eines LDAP-Servers beginnt mit der Definition der Wurzel des Verzeichnisbaums. Diese base dn wird als dc (engl. domain component) bezeichnet und setzt sich im Normalfall aus den Komponenten der Domain des zu verwaltenden Rechnernetzes zusammen. In der Konfigurationsdatei des OpenLDAP-Servers, der /etc/ldap/slapd.conf, sieht die Angabe dieses Suffixes wie folgt aus:
Listing 13.33 Konfiguration der Wurzel des LDAP-Verzeichnisbaums
...
# Beispiel für die Domain doomed-reality.org
suffix "dc=doomed-reality,dc=org"
...
Attribute definieren
Außerdem wichtig für die Konfiguration eines LDAP-Servers sind die verwendeten Schemata. In den Schemadateien sind schließlich die möglichen und notwendigen Attribute für eine Objektklasse definiert. Sie Schemata bindet man über eine include-Anweisung in der Konfigurationsdatei ein:
Listing 13.34 Einbinden von Schemata
...
# Schema and objectClass definitions
include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema
include /etc/ldap/schema/misc.schema
...
Schemata kann man nun beliebig erweitern und auch eigene Definitionen einbinden. Wir werden später ein Beispiel betrachten, bei dem wir eine Datei samba.schema einbinden, um so einem Samba-Server zu erlauben, Benutzerdaten auf unserem LDAP-Server zu speichern. Mit diesen Benutzerdaten können sich dann Anwender auf Windows-PCs einloggen und sich über Samba an einer NT-Domäne anmelden. Samba selbst prüft dann die Gültigkeit des Benutzername-/Passwort-Paares über LDAP.
Man darf dabei jedoch nicht vergessen, dass ein LDAP-Server in erster Linie eine Datenbank ist. Daher bietet der Server nur ein Interface – eben das Lightweight Directory Access Protocol – zum Zugriff auf die Daten. Zugreifen müssen entsprechende Programme nun jedoch selbst: Ein E-Mail-Client könnte zum Beispiel ein Adressbuch auf LDAP-Basis bereitstellen. Dazu bräuchte er nur die Attribute von Einträgen der Objektklasse inetOrgPerson (wie zum Beispiel das Attribut mail und das Attribut cn, das bei Personen den vollen Namen beinhaltet) auszulesen und über ein komfortables Interface bereitzustellen.
Dagegen könnte ein Login-Dienst wie SSH oder das normale Unix-Login das vom Benutzer eingegebene Passwort mit dem im userPassword gespeicherten Hashwert vergleichen und so entscheiden, ob das Passwort richtig und das Login damit erfolgreich war.
Zugriffsrechte definieren
Um entsprechende Zugriffe zu kontrollieren, braucht man natürlich noch ein Rechtesystem, das Zugriffe auf Datensätze zulässt oder verweigert. Die Zugriffsrechte auf einzelne Datensätze und Funktionen werden ebenfalls in der /etc/ldap/slapd.conf konfiguriert:
Listing 13.35 Beispiel für die Zugriffskontrolle
access to attrs=userPassword
by dn="cn=admin,dc=doomed-reality,dc=org" write
by anonymous auth
by self write
by * none
access to *
by dn="cn=admin,dc=doomed-reality,dc=org" write
by * read
Der erste Block definiert hier den Zugriff auf das Attribut userPassword: Der Benutzer cn=admin,dc=doomed-reality,dc=org hat als Administrator Schreibrechte auf dieses Attribut. Im Gegensatz dazu hat ein anonymer, also noch nicht authentifizierter Nutzer das Recht, sich anzumelden. Ein User (self) darf sein eigenes Passwort noch ändern, alle anderen Zugriffe sind jedoch verboten. Als Nächstes wird der Zugriff auf alle anderen Elemente definiert: Wieder darf admin schreiben und der Rest der Welt nur lesen.
Natürlich gibt es zur Konfiguration eines LDAP-Servers noch viel mehr zu sagen. Gerade in größeren Netzwerken möchte man die anfallende Last vielleicht auf mehrere Server verteilen und daher den Datenbestand entweder replizieren oder erst zer- und dann verteilen. Prinzipiell kann man mit OpenLDAP und anderen LDAP-Implementierungen noch viel mehr tun, jedoch gehen diese Features deutlich über den Umfang dieses Linux-Buches hinaus. Für ein kleines Setup sollten die hier vermittelten Informationen jedoch ausreichen.
13.6.3 Einträge hinzufügen, verändern und löschen
Für LDAP gibt es die verschiedensten Benutzerschnittstellen – vorstellen wollen wir Ihnen zwei: die Schnittstelle ldap-utils für die Kommandozeile und das Webinterface phpldapadmin. Das Webinterface ist dabei die intuitivere Variante der Bedienung: An der linken Seite kann man den Verzeichnisbaum durchsuchen und in jeder Ebene neue Elemente hinzufügen oder vorhandene Elemente zum Editieren oder Löschen aufrufen.
LDAP-Verzeichnis organisieren
Die Bedienung ist dabei selbsterklärend, sofern man das Prinzip von LDAP halbwegs verstanden hat. Möchte man einen neuen Eintrag in den Verzeichnisbaum einfügen, so wird man zuerst nach der Objektklasse des neuen Objekts gefragt. Möchte man seine Daten dabei in verschiedene Verzeichnisse gliedern, so wird man auf der ersten Ebene meist eine organisational unit (ou) anlegen wollen. Als Nächstes wird man nach den für die Objektklasse unbedingt notwendigen Attributen gefragt. Bei einer ou ist dies nur deren Name, bei der Objektklasse posixAccount sind dies jedoch die wichtigen bekannten Daten wie der Benutzername, die UID/GID, das Home-Verzeichnis und die Shell.
Abbildung 13.2 Das Webinterface phpldapadmin
Das LDAP- Datenformat
Kommandozeilentools wie ldapmodify oder ldapadd bieten diesen Komfort nicht. Dort gibt man die Daten eines neuen Datensatzes im LDIF-Format (LDAP Data Interchange Format) an, einem einfachen, für Menschen lesbaren Textformat. Vergisst man ein notwendiges Attribut für einen neuen Eintrag, so kann dieser eben nicht eingefügt werden.
Listing 13.36 Ein vollständiges LDIF-Beispiel für einen Benutzereintrag
dn: uid=cdp_xe,ou=Mitglieder,dc=doomed-reality,dc=org
uid: cdp_xe
givenName: Steffen
sn: Wendzel
cn: Steffen Wendzel
userPassword: {SHA}s3SUjNlV4lEhEY4W4Uya7ut0sxE=
loginShell: /bin/bash
uidNumber: 2001
gidNumber: 100
homeDirectory: /home/cdp_xe
shadowMin: –1
shadowMax: 999999
shadowWarning: 7
shadowInactive: –1
shadowExpire: –1
shadowFlag: 0
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
Bekannte Eigenschaften
Im obigen Beispiel kann man sehr gut sehen, dass für einen Eintrag der eindeutige Name (dn) gleichzeitig seinen Platz im Netz festlegt: Auf dem Server dc=doomed-reality,dc=org ist der Benutzer uid=cdp_xe unterhalb des Knotens ou=Mitglieder platziert. Des Weiteren ist ebenfalls zu erkennen, dass der Eintrag mehreren Objektklassen angehört, deren Attribute allesamt mit sinnvollen Werten [Fn. Im Falle eines Benutzereintrags kennen Sie diese Felder natürlich bereits aus den Dateien /etc/passwd und /etc/shadow. Dabei wird auch bei LDAP das Passwort nicht im Klartext, sondern verschlüsselt abgespeichert.] belegt sind.
Speichert man diesen Datensatz in einer Datei, so kann man ihn mittels des Programms ldapadd folgendermaßen auf den Server laden:
Listing 13.37 Mit ldapadd einen Benutzer hinzufügen
# ldapadd -x -w pass -D "cn=admin,dc=..." -f new.ldif
adding new entry "uid=cdp_xe,ou=Mitglieder, dc=...org"
Dieser Aufruf loggt sich mit der Benutzerkennung cn=admin,dc=doomed-reality, dc=org und dem Passwort pass auf dem lokalen Server ohne eine geschützte Verbindung ein (-x, kann, falls keine Verschlüsselung verwendet wird, auch weggelassen werden). Die einzufügenden Daten finden sich dabei in der Datei new.ldif.
Einträge verändern
Möchte man nun bestehende Einträge verändern, so nutzt man das Programm ldapmodify. Intern ist ldapadd im Übrigen auch nur ein Frontend für ldapmodify mit dem Parameter -a. Zu unserem bekannten und einfachen LDIF-Format kommt nun noch die Aktion hinzu, die durch das Attribut changetype: definiert wird. Es gibt an, ob man Einträge hinzufügen [Fn. Diese Aktion wird beim Aufruf des Programms über ldapadd automatisch angenommen.] (add), sie verändern (modify) oder sie löschen (delete) will.
Beim Ändern muss man zusätzlich über das Schlüsselwort replace: das betroffene Attribut angeben:
Listing 13.38 Änderungen an einem Eintrag
dn: uid=doomed,dc=doomed-reality,dc=org
changetype: modify
replace: uidNumber
uidNumber: 1000
-
add: mail
mail: johannes.ploetner@gmx.de
-
delete: jpegPhoto
-
In diesem Beispiel wird, wie unschwer zu erkennen ist, das Attribut uidNumber in den Wert »1000« geändert, das Attribut mail mit dem entsprechenden Wert hinzugefügt und das Attribut jpegPhoto gelöscht. Die Änderung macht man nun ganz analog zu ldapadd wirksam:
Listing 13.39 Die Änderungen durchführen
# ldapmodify -x -w pass -D "cn=admin,dc=...,dc=org" -f test.ldif
modifying entry "uid=doomed,ou=Mitglieder,dc=...=org"
Man muss sich also wieder auf dem Server einloggen und die Datei mit den Änderungen aufspielen. Als eine kurze Einführung in die Administration eines LDAP-Servers soll dies zunächst genügen. Schließlich wollen wir in diesem Kapitel den Fokus auf die Benutzerverwaltung legen.
13.6.4 Die Benutzerverwaltung mit LDAP
Sie wissen nun, was ein LDAP-Server ist, wie die Grundlagen seiner Konfiguration aussehen, und Sie haben zwei Beispiele für seine Administration kennengelernt. Ein wichtiger Punkt fehlt in unserer Betrachtung jedoch noch: Wie konfiguriert man einen Client so, dass er zur Authentifizierung nicht nur die lokalen /etc/passwd- und /etc/shadow-Dateien, sondern auch einen LDAP-Server nutzt?
PAM
Die Antwort hierauf ist PAM (Pluggable Authentication Module). Eigentlich alle neueren Login-Dienste setzen auf PAM als Interface zur Verifikation von Benutzerauthentifizierungen auf. Vereinfacht gesagt nimmt PAM das eingegebene Passwort und nutzt intern verschiedene Datenbanken und Dienste, um den Login zu bestätigen. Mit pam_ldap.so steht auch ein Plugin für den Support von LDAP bereit, so dass ein Login über diesen Dienst einfach zu konfigurieren ist.
Die Datei /etc/nsswitch.conf
Als Erstes müssen Sie hierzu die unterschiedlichen Varianten an Authentifizierungsmöglichkeiten festlegen und schließlich differenzieren, in welcher Reihenfolge diese abgearbeitet werden sollen. Diesen Zweck erfüllt die /etc/nsswitch.conf, die nicht nur den Zugriff auf bestimmte Daten für die Benutzerverwaltung über traditionelle Unix-Dateien, sondern auch verschiedene Netzwerkdienste koordiniert.
Möchte man bei einem Login zuerst die Unix-Dateien und dann erst den LDAP-Server fragen, so sollte man die Datei wie folgt ändern:
Listing 13.40 Die angepasste /etc/nsswitch.conf-Datei
passwd: files ldap
group: files ldap
shadow: files ldap
...
Mit dieser Änderung fügen Sie Support für LDAP hinzu, der aktiv wird, wenn ein Benutzername nicht in einer der normalen Dateien gefunden wurde. Oft findet man in der /etc/nsswitch.conf anstelle des files-Schlüsselworts das Wort compat: Dieses dient dazu, nur wie fr"uher üblich, Benutzernamen, die mit einem + beginnen, über NIS zu überprüfen – jedoch wird man in einem Netzwerk kaum LDAP und NIS parallel einsetzen, weshalb man ruhig auch files statt compat schreiben kann.
Diese Konfiguration regelt jedoch nur den Zugriff auf die Benutzerdaten über die Standardbibliothek glibc:
Listing 13.41 Alle bekannten Benutzer mit getent ausgeben
# getent passwd
root:x:0:0:root:/root:/bin/bash
...
cdp:x:2001:100:Steffen Wendzel:/home/cdp:/bin/bash
... und die glibc
So kann man sich zum Beispiel mit dem Befehl getent alle bekannten Benutzer anzeigen lassen. Nach der Änderung an der /etc/nsswitch.conf zeigt das Programm nicht nur alle Benutzer aus der /etc/passwd, sondern zusätzlich auch noch die auf dem LDAP-Server eingetragenen an. PAM-Login-Dienste müssen jedoch gesondert konfiguriert werden.
Die Konfiguration von PAM
Für jeden Dienst, der die PAM-Funktionalität in Anspruch nimmt, gibt es in der Regel eine eigene Konfigurationsdatei mit dem Namen des Dienstes im Verzeichnis /etc/pam.d angelegt. Dort kann man dann verschiedene Einstellungen zu den unterschiedlichen Aktionen auth, account, password und session vornehmen.
Verschiedene Dienstklassen
Die Unterschiede sind dabei nicht besonders relevant: auth beschreibt zum Beispiel die Funktion, die Identität bestimmter Benutzer sicherzustellen, und ist damit sehr eng mit dem passwort-Dienst verbunden. Über account-Dienste kann überprüft werden, ob zum Beispiel das Passwort eines Benutzers abgelaufen ist oder ob dieser Berechtigungen für einen bestimmten Dienst hat. Analog umfasst der ses- sion-Dienst bestimmte Sitzungsdienste wie das Mounten des Home-Verzeichnisses.
Natürlich muss man nicht jede Datei editieren, die sich in diesem Verzeichnis befindet. Die meisten Anwender binden nur die Standard-Konfigurationsdateien ein, die wie folgt zu editieren sind:
- common-auth
Listing 13.42 Die Datei /etc/pam.d/common-auth
auth sufficient pam_ldap.so
auth required pam_unix.so nullok use_first_pass
- common-account
Listing 13.43 Die Datei /etc/pam.d/common-account
account sufficient pam_ldap.so
account required pam_unix.so use_first_pass
- common-session
Listing 13.44 Die Datei /etc/pam.d/common-session
session sufficient pam_ldap.so
session required pam_unix.so use_first_pass
- common-password
Listing 13.45 Die Datei /etc/pam.d/common-password
password sufficient pam_ldap.so
password required pam_unix.so use_first_pass
Automatisches Home-Verzeichnis
Das Problem bei neuen LDAP-Benutzern ist meist, dass sie auf den einzelnen Maschinen noch kein Home-Verzeichnis haben. Jedoch hilft PAM auch in diesem Fall, da über eine entsprechende session-Direktive automatisch ein Home-Verzeichnis angelegt wird, wenn sich ein »wohnungsloser« Benutzer einloggt:
Listing 13.46 Automatisch ein Home-Verzeichnis anlegen
session required pam_mkhomedir.so skel=/etc/skel umask=0022
Mit diesen Änderungen ist unser einfaches LDAP-Setup schon komplett. Für weitere und ausführlichere Informationen sei an dieser Stelle auf das Internet (zum Beispiel die Webseite www.openldap.org) und auf die Vielzahl der Bücher verwiesen, die über LDAP geschrieben wurden.
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.