Kapitel 15
IN DIESEM KAPITEL
Ein LDAP-Server liefert Daten und ist insofern vergleichbar mit einer Datenbank. Während relationale Datenbanken ihre Daten in Tabellen ablegen und sie so untereinander vernetzen, sind die Daten von LDAP hierarchisch geordnet, darum spricht man von einem Verzeichnisdienst.
Die Struktur der Datenbankeinträge sind durch die Tabelle geprägt, in der sie abgelegt sind. Die Einträge in einem Verzeichnisdienst können dagegen durch eine oder mehrere Klassen festgelegt werden. Sie können Klassen kombinieren und um eigene Elemente erweitern. Einige Klassen sind vorgefertigt und können für eigene Zwecke verwendet werden. Beispielsweise gibt es für den POSIX-Benutzer die Objektklasse posixAccount
. Sie enthält die Felder uid
, uidNumber
und gidNumber
und bildet so die Systemdatei /etc/passwd nach.
Solche Accounts sind für eine zentrale Verwaltung von Benutzern wertvoll. Darum findet man einen LDAP-Server in fast allen Netzwerken, in denen eine einheitliche Benutzerkennung erforderlich ist. Entsprechend verwenden viele Server und Anmelde-Clients die Option LDAP, um die lokale Anmeldung auszulagern.
Von allen LDAP-Implementationen dürfte OpenLDAP am weitesten verbreitet sein. Bevor Sie sich auf die Installation stürzen, sollten Sie noch ein paar grundlegende Erläuterungen ertragen.
LDAP steht für Lightweight Directory Access Protocol und ist also ein Protokoll. Ein LDAP-Server ist also ein Server, der dieses Protokoll bedient.
Die Daten dieses Verzeichnisses (Directory) werden baumartig angelegt. Dabei können die Blätter eines solchen Baumes frei strukturiert werden. Die Informationen werden Attributen zugeordnet. Im Beispiel wird dem Attribut sn (surname) der Nachname und dem Attribut cn (common name) der vollständige Name zugeordnet. Der Vorname steht hinter dem Attribut givenName.
givenName:Arnold
sn: Willemer
cn: Arnold Willemer
Es würde schnell kompliziert, wenn die Attributnamen bei jedem Objekt völlig frei definiert würden. Darum verwendet man Klassen, die bestimmte Attribute definieren, die Objektklassen (objectClass
) genannt werden.
Die Objektklassen definieren einen Satz von Attributen und geben damit den Objekten Struktur. Beispielsweise enthält die Klasse posixAccount
unter anderem die Attribute uid
und gidNumber
. Eine Objektklasse wird selbst wieder im LDIF-Format aufgeschrieben.
objectclass ( 2.5.6.6 NAME 'person' SUP top STRUCTURAL
MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
Diese Objektklasse person
basiert auf der SUPerior Class top
. Die Klasse top
ist die Mutter aller Klassen. Mit STRUCTURAL wird beschrieben, dass sie eine Struktur von Attributen vorgibt. Dabei wird unter MUST
festgelegt, dass jedes Objekt, dass eine ordentliche person
sein will, auf jeden Fall das Attribut sn
(surname, also Nachname) und das Attribut cn
(common name) definieren muss. Erlaubt sind auch die Attribute userPassword
, telephoneNumber
, seeAlso
und description
, also alles was eine Person so gebrauchen könnte.
Mit diesen Grundlagen lassen sich eigene Datenobjekte definieren, die gemeinsamen Objektklassen angehören. Dadurch sind die Attribute definiert, nach denen man suchen oder die man auswerten kann.
Alle diese Datenobjekte bevölkern einen Baum (DIT, Directory Inormation Tree), in dem diese eindeutig bestimmbar sein müssen. Als Identifikation wird ein Attribut dn
(Distinguished Name) verwendet. Dieser wird zumeist aus mehreren Elementen zusammengesetzt. Im folgenden Beispiel beginnt mit dem eindeutige Schlüssel aus dem Attribut uid
mit dem Wert paul
. Dieser ist eindeutig im Raum dc=willemer
, der wiederum eindeutig im Raum dc=edu
ist. Davon ausgehend, dass es keine URL willemer.edu gibt, ist paul
weltweit eindeutig und wir können diesen Baum in jeden beliebigen anderen Baum widerspruchsfrei integrieren.
dn: uid=paul,dc=willemer,dc=edu
objectClass: inetOrgPerson
objectClass: posixAccount
uid: paul
cn: Paul
sn: Willemer
uidNumber: 2002
gidNumber: 100
userPassword: {SSHA}fL402skgIMWc45mGL4PNq5LyJ1Waqqso
homeDirectory: /home/paul
Man sieht hier, dass paul
die Attribute zweier Objektklassen, inetOrgPerson
und posixAccount
enthält. So muss auch uid
noch einmal mit paul
besetzt werden, obwohl es auf den ersten Blick wie eine Dopplung der dn
wirkt.
Dieses Element beschreibt also das Datenobjekt paul
in seiner Umgebung, mit den Objektklassen, auf denen es beruht und den Attributen, die für paul
belegt werden. Diese textuelle Struktur nennt man LDAP Data Interchange Format (LDIF). In diesem Format werden Daten über das Lightweight Directory Access Protocol (LDAP) ausgetauscht.
Wir werden auf dieses Beispiel mit paul
noch zurückkommen.
Um einen LDAP-Server zu installieren, benötigen Sie das Paket slapd
. Vorher ist es immer wieder klug, die Paketlisten aktuell zu halten.
# apt update
# apt install slapd
Der Installationsassistenz wird Sie auffordern, das Administratorpasswort einzugeben und auf dem nächsten Dialog zu bestätigen. Dieses Passwort werden Sie wieder benötigen und es ist eine gute Idee, sich dieses zu merken.
OPENLDAP erstellt eine Standardkonfiguration, die Sie über Konfigurationsdateien anpassen können. Etwas einfacher wird es, wenn Sie eine Paket-Rekonfiguration durchführen:
# dpkg-reconfigure slapd
Dieser Befehl spornt den Assistenten dazu an, ein paar detailliertere Fragen zu stellen.
willemer.edu
. Daraus wird LDAP dann dc=willemer,dc=edu
generieren. Sie können und werden vermutlich eine eigene Domain verwenden wollen.Nun kann man den LDAP-Server starten und schauen, ob dieser auch tadellos läuft.
# systemctl restart slapd
# systemctl status slapd
Und schon kann man die erste Abfrage stellen. Dazu gibt es den Befehl ldapsearch
, der durch die Installation schon zur Verfügung stehen sollte. Im Zweifelsfall müssten Sie das Paket ldap-utils nachinstallieren. Der Befehl testet zunächst, ob eine saubere Installation vorliegt.
# ldapsearch -x
# extended LDIF
#
# LDAPv3
# base <> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#
# search result
search: 2
result: 32 No such object
# numResponses: 1
Um LDAP besser verstehen zu können, ist ein konkretes Beispiel wichtig. Durch die Flexibilität des Konzepts verliert man sonst leicht den Überblick. Da LDAP allgemein gern für die Authentifizierung verwendet wird, soll ein Verzeichnis für Linux-Benutzer erstellt werden. Da ein Linux-Benutzer immer auch zu einer Gruppe gehört, sollte man die Gruppen gleich in das Konzept mit aufnehmen.
Um POSIX-User verwalten zu können, drängt es sich auf, Benutzer und Gruppen zu unterscheiden. Beide haben einen ordnenden Charakter und darum definieren wir sie als organizationalUnit
.
Definitionen werden als LDIF an den Server übertragen und im Verzeichnis abgelegt. Es hat sich bewährt, diese Definition erst einmal in einer Datei niederzuschreiben und diese dann zu verschicken. So können Tippfehler in Ruhe beseitigt werden, bevor Sie im Server landen.
Wir erstellen eine Datei namens base-ou.ldif. Der Name ist natürlich beliebig. Unsere Datei base-ou.ldif enthält gleich zwei Einträge, einen Eintrag für Benutzer und einen für Gruppen. Beide müssen durch mindestens eine Leerzeile voneinander getrennt sein.
dn: ou=Benutzer,dc=willemer,dc=edu
objectClass: organizationalUnit
ou: Benutzer
dn: ou=Gruppen,dc=willemer,dc=edu
objectClass: organizationalUnit
ou: Gruppen
Diese Datei kann durch den Befehl ldapadd
eingefügt werden. Die Option -D
gibt an, unter welchem Account dieser Eintrag erfolgt. Wir tragen ihn als Administrator des LDAP-Servers ein. Der Administrator wird durch die Kombination cn=admin,dc=willemer,dc=edu
eindeutig beschrieben. Es ist wichtig, dass dazwischen kein Leerzeichen gesetzt wird. Die Option -W
bewirkt, dass das Passwort für den Administrator direkt in der Konsole eingetippt werden muss.
# ldapadd -x -D cn=admin,dc=willemer,dc=edu -W -f base-ou.ldif
Enter LDAP Password:
adding new entry “ou=Benutzer,dc=willemer,dc=edu”
adding new entry “ou=Gruppen,dc=willemer,dc=edu”
Wir legen nun eine Gruppe users
an. Unter Linux benötigt ja jeder Benutzer eine Gruppe. Heute ist es üblich, jedem Benutzer eine eigene Gruppe zuzuordnen. In den guten alten Zeiten gab es einfach die Gruppe users
für alle. Um uns das Leben etwas einfacher zu machen, reden wir uns auf diese Tradition heraus. Die Gruppe users
gibt es noch heute. Sie ist in der Datei /etc/group unter der gid 100 zu finden. LDAP kennt für POSIX-Gruppen die Objektklasse posixGroup
Den Eintrag der Gruppe users
erledigen wir in einer Datei oc-users.ldif.
dn: cn=users,dc=willemer,dc=edu
objectClass: posixGroup
cn: users
gidNumber: 100
Auch diese Datei wird per ldapadd
hinzugefügt.
# ldapadd -x -D cn=admin,dc=willemer,dc=edu -W -f oc-users.ldif
Enter LDAP Password:
adding new entry “cn=users,dc=willemer,dc=edu”
Jeder Benutzer wird ein Passwort benötigen. Da Administratoren spontan heftige Zahnschmerzen bekommen, wenn sie Passwörter im Klartext speichern oder über die Leitung senden sollen, müssen wir das Passwort vor dem Senden verschlüsseln. Dazu verwenden wir eine sichere Hash-Funktion, englisch als Secure Hash Algorithm (SHA) bekannt ist. Um ein so verschlüsseltes Passwort zu erzeugen, gibt es den Befehl slappasswd
.
linux@mintmate:˜$ slappasswd
New password:
Re-enter new password:
{SSHA}fL402skgIMWc45mGL4PNq5LyJ1Waqqso
Nun ist alles bereit, um den Benutzer paul
einzutragen. Wir erzeugen eine LDIF-Datei user-paul.ldif. Dort kopieren wir das erzeugte Passwort unter dem Attribut userPassword
.
dn: uid=paul,dc=willemer,dc=edu
objectClass: inetOrgPerson
objectClass: posixAccount
uid: paul
cn: Paul
sn: Willemer
uidNumber: 2002
gidNumber: 100
userPassword: {SSHA}fL402skgIMWc45mGL4PNq5LyJ1Waqqso
homeDirectory: /home/paul
Nun wird der Benutzer paul mit dem Befehl ldapadd
eingetragen.
# ldapadd -x -D cn=admin,dc=willemer,dc=edu -W -f user-paul.ldif
Enter LDAP Password:
adding new entry “uid=paul,dc=willemer,dc=edu”
Damit haben wir einen LDAP-Server erstellt, der sich für das Login eines Linux-Clients eignet. Durch den Einsatz verschiedener Objektklassen lassen sich die Daten nicht nur um Attribute erweitern, sondern auch völlig andere Informationen speichern.
Ein LDAP-Server kann für das Login eines Arbeitsplatzrechners verwendet werden. Damit reicht es, einen Benutzer einmal im Netzwerk zu definieren und er kann sich mit demselben Passwort an allen Arbeitsplätzen anmelden, ohne dass es einen Account für ihn auf diesem Rechner gibt. Als Beispiel wird Linux Mint mit der grafischen Oberfläche MATE verwendet. Es würde aber grundsätzlich mit allen POSIX-Systemen funktionieren.
Um das Einloggen im Netzwerk zu zentralisieren, bietet Linux zwei Mechanismen.
Um den Login mit LDAP zu ermöglichen, müssen die Libraries installiert werden, die dafür sorgen, dass NSS und PAM mit LDAP zusammenarbeiten können.
# apt update
# apt install libnss-ldapd libpam-ldapd
Die Installation fragt nach der URL des LDAP-Servers. Für den LDAP-Server, den wir im vorigen Abschnitt installiert haben, kann man einfach dessen IP-Nummer verwenden. Der LDAP-Server, mit dem ich getestet habe, hatte die IP-Adresse 192.168.109.199. Wenn Sie auf einen fremden LDAP-Server zugreifen wollen, müssen Sie dessen Adrese hier angeben.
ldap://192.168.109.199
Dann fordert die Installation den »Distinguished name of the search base«. Hier wird der DN des LDAP-Baums eingetragen, in dem die POSIX-Accounts gespeichert werden.
dc=willemer,dc=edu
Im nächsten Schritt wird gefragt, welche Namensdienste durch den NSS per LDAP zugegriffen werden soll. Für das Login werden auf jeden Fall passwd, group und shadow benötigt. Damit schließt die Installation.
Sie können sicherheitshalber noch einmal prüfen, ob die richtigen Einträge in der Datei /etc/nslcd.conf stehen. Das kann in besonderen Konstruktionen schon einmal schiefgehen.
# The location at which the LDAP server(s) should be reachable.
uri ldap://192.168.109.199
# The search base that will be used for all queries.
base dc=willemer,dc=edu
Wenn Sie weitere Basen benötigen, können diese einfach untereinander geschrieben werden. Beispielsweise könnte es verschiedene Basen für Angestellte, Freiberufler und Kunden geben.
Der Blick in die Datei /etc/nsswitch.conf ist sehr aufschlussreich. Dort sind passwd, group und shadow um den Eintrag ldap
ergänzt worden.
# /etc/nsswitch.conf
passwd: files systemd ldap
group: files systemd ldap
shadow: files ldap
gshadow: files
hosts: files mdns4_minimal [NOTFOUND=return] dns myhostname
networks: files
Es wird auch die Reihenfolge festgelegt. Bei shadow
wird zunächst in die lokale Datei geschaut und erst, wenn dort nichts steht LDAP gerufen.
Wenn alles klappt, wird LDAP melden, dass sich der Benutzer paul gern auf diesem System anmelden kann. Wenn aber paul dort kein Verzeichnis /home/paul vorfindet, wird die Anmeldung nicht glücken. Für dieses Problem gibt es zwei sehr unterschiedliche Lösungsansätze:
Das Verzeichnis wird bei jeder Anmeldung von einem zentralen Server hinter dem lokalen Verzeichnis /home eingehängt. Das Handwerkzeug dafür heißt NFS und Automount. Beides wird im Kapitel 13 beschrieben.
Dieser Ansatz hat den Charme, dass der Benutzer beliebig den Arbeitsplatz wechseln kann und überall die gleiche Arbeitsumgebung vorfindet.
Das Verzeichnis wird bei der ersten Anmeldung erstellt und bleibt erhalten, wenn sich der Anwender ein weiteres Mal anmeldet.
Dieser Ansatz hat den Vorteil, dass der Zugriff auf lokale Festplatten in der Regel schneller abläuft. In manchen Fällen ist ein Auslagern auch schwierig bis unmöglich.
Den ersten Ansatz können Sie in Kapitel 13 sehen, den zweiten werden wir gleich hier umsetzen.
Um das PAM dazu zu bringen, ein Verzeichnis für den angemeldeten Benutzer anzulegen, können Sie den Befehl pam-auth-update
aufrufen. Nach dem Starten erscheint ein Dialog, in dem PAM-Profile freigeschaltet werden können. Eines davon lautet Create home directory on login
. Dieses tut genau das Gewünschte und hat darum einen Haken verdient.
Als Konsequenz wird beim ersten erfolgreichen Login ein lokales Home-Verzeichnis angelegt. Bei späteren Logins findet der Anwender den letzten Stand vor.
Wie fast immer bleibt noch etwas Handarbeit an unerwarteter Stelle. Der aktuelle Anmeldebildschirm von MATE zeigt für das Login alle Benutzer, die in der lokalen Datei /etc/passwd eingetragen sind. Damit stehen Benutzer, die nur im LDAP bekannt sind, vor verschlossener Tür, einfach weil man keinen unbekannten Benutzernamen eintippen kann.
Unter MATE finden Sie dem Menü SYSTEMVERWALTUNG den Punkt ANMELDEFENSTER. Ähnliche Konfigurationsmöglichkeiten gibt es auch bei anderen grafischen Desktops. Für eine Änderung benötigen Sie das Administrator-Passwort. Unter der Lasche BENUTZER gibt es einen Schalter »Manuelles Anmelden erlauben«. Dieser muss gesetzt sein. Leider ist das einer der wenigen Situationen, in denen Sie auch einen Linux-Rechner neustarten müssen, damit die Konfigurationsänderung wirksam wird.
Beim nächsten Anmelden erscheint ein zusätzliches Feld namens ANMELDEN. Wenn Sie dieses anklicken, erscheint ein Eingabefeld für einen beliebigen Benutzernamen und dann auch für das Passwort.
Der Benutzer kann auf der Konsole sein Passwort sogar selbst ändern. Dazu ruft er einfach den gewohnten Befehl passwd
auf:
$ passwd
(current) LDAP Password:
Geben Sie ein neues Passwort ein:
Geben Sie das neue Passwort erneut ein:
passwd: Passwort erfolgreich geändert
Leider funktioniert die Passwortänderung nicht über die grafische Oberfläche von MATE. Aber irgendetwas ist ja immer…