17    LDAP

Verzeichnisdienste wie »OpenLDAP« ermöglichen es Ihnen, die Verwaltung der Ressourcen zentral zu steuern und an mehrere Stellen zu replizieren. Je größer Ihr Netzwerk wird, umso wichtiger werden die effiziente Verwaltung und Kontrolle aller Ressourcen. Mit OpenLDAP haben Sie einen Dienst, der Ihnen die tägliche Arbeit sehr stark erleichtern kann, da alle Ressourcen in einer hierarchischen Struktur abgelegt werden, die der Struktur Ihres Unternehmens entspricht. In diesem Kapitel lernen Sie OpenLDAP intensiv kennen.

In Zeiten, in denen die Netzwerkinfrastrukturen in Unternehmen immer heterogener werden, ist es besonders wichtig, dass Sie eine zentrale Verwaltung der Ressourcen im Netzwerk realisieren können. Unterschiedliche Netzwerkdienste, die den Benutzern zur Verfügung gestellt werden, verlangen oftmals eine eigene Benutzerverwaltung. Auf die Dauer kann es für Sie sehr schwierig und unübersichtlich werden, die verschiedenen Accounts zu verwalten. Das gilt nicht nur für Sie als Administrator, sondern auch für die Benutzer, die diese verschiedenen Dienste nutzen möchten. Durch den Einsatz von LDAP können Sie die Benutzer und Ressourcen zentral verwalten. Für jeden Benutzer existiert anschließend nur noch ein Konto. Mit diesem Konto kann sich der Benutzer an den verschiedensten Diensten anmelden. Ändert ein Benutzer sein Passwort, gilt das neue Passwort sofort für alle Dienste. Zusammen mit Kerberos können Sie auch noch einSingle Sign-on realisieren. Um diese zentrale Verwaltung der Ressourcen realisieren zu können, wurde das Lightweight Directory Access Protocol (LDAP) entwickelt.

Bei LDAP handelt es sich ursprünglich um ein Protokoll, das als »Proxy« für den Zugriff auf eine DAP-Datenbank diente. Später wurde daraus ein eigenständiger Verzeichnisdienst.

LDAP ist ein Verzeichnisdienst, der hierarchisch gegliedert wird. Dadurch können Sie Ihre Unternehmensstruktur direkt im LDAP abbilden. Sie können aber genauso eine Struktur erstellen, die verschiedene Ressourcen zusammenfasst – eine allgemeingültige Struktur für einen LDAP-Baum gibt es nicht. Sie müssen immer Ihre Struktur genau an Ihre Gegebenheiten anpassen. Eine umfangreiche und ausführliche Planung kann Ihnen später eine Menge Arbeit ersparen.

In diesem Kapitel wird ein OpenLDAP-Server konfiguriert werden, und wir zeigen Ihnen am Beispiel einiger Dienste, wie Sie OpenLDAP für eine zentrale Verwaltung Ihrer Ressourcen verwenden können. Zusätzlich wird hier auch die Einrichtung einer verschlüsselten Verbindung mit TLS implementiert. Ein weiteres wichtiges Thema, das hier angesprochen wird, ist die Realisierung der Ausfallsicherheit durch einen zweiten OpenLDAP-Server in Ihrem Netzwerk.

17.1    Einige Grundlagen zu LDAP

Das Lightweight Directory Access Protocol (LDAP) wurde im Jahre 1993 entwickelt, um den Zugriff auf DAP-Datenbanken über TCP/IP zu erleichtern. Der ursprüngliche X.500-Standard, der für DAP-Datenbanken verwendet wurde, umfasst alle sieben Ebenen des OSI-Referenzmodells, wodurch eine Implementation über verschiedene Systeme hinweg recht aufwendig war. Deshalb wurde im Jahre 1993 das Protokoll LDAP entwickelt. Zunächst wurde es nur dazu verwendet, um auf DAP-Server zugreifen zu können. LDAP diente dabei mehr oder weniger als Proxy, um zwischen X.500 und den verschiedenen Systemen zu vermitteln. Der große Vorteil von LDAP gegenüber einer reinen DAP-Umgebung ist der, dass für LDAP nur ein funktionsfähiger TCP/IP-Protokollstack benötigt wird. Später wurde zu LDAP ein eigenes Datenbank-Backend hinzugefügt, um unabhängig von den DAP-Servern zu werden.

17.1.1     Was ist ein Verzeichnisdienst?

In einem Verzeichnisdienst werden Informationen in einer hierarchischen Struktur abgelegt, die auch als baumartige Struktur bezeichnet wird. Die Vorteile einer solchen Struktur sind:

Für Verzeichnisdienste existiert eine Reihe von X.500-Standards. Diese Standards beschreiben, wie Verzeichnisdaten zur Verfügung gestellt und abgerufen werden und wie die Verschlüsselung, Authentifizierung, Replikation und Verwaltung der Verzeichnisdaten gehandhabt werden. Die X.500-Standards liefern die Funktionsmodelle und Begriffsbestimmungen für die Verzeichnisdienste, die nicht voll auf dem X.500-Standard basieren, was bei LDAP der Fall ist. Die aktuelle Version von LDAP ist die Version 3. Diese bietet gegenüber der alten LDAP-Version 2 einige Vorteile:

[+]  LDAPv3 ist nicht abwärtskompatibel und sollte nicht mit LDAPv2-Servern in einer Umgebung betrieben werden.

17.1.2    Der Einsatz von LDAP im Netzwerk

Sie können LDAP auf verschiedene Arten und Weisen in Ihrem Netzwerk für die Verwaltung einsetzen. Auch ist LDAP die Grundlage anderer Verzeichnisdienste, wie zum Beispiel das Novell eDirectory (früher Novell NDS) oder des Microsoft Active Directorys. Mithilfe von LDAP können Sie in Netzwerken die Verwaltung der Ressourcen vereinfachen. Zusammen mit Kerberos ist es auch möglich, ein Single Sign-on im Netzwerk zu realisieren.

LDAP lässt sich für eine Vielzahl von Diensten zur Authentifizierung und zur Bereitstellung von Ressourcen nutzen. Nach der Konfiguration des LDAP-Servers soll die Anbindung der folgenden Dienste realisiert werden, wobei es hier nicht um die vollständige Konfiguration der einzelnen Dienste geht, sondern nur um die Anbindung an LDAP:

17.1.3    Aufbau des LDAP-Datenmodells

Wie schon in der Einleitung angesprochen wurde, ist das Datenmodell von LDAP objektorientiert. Bei LDAP gelten fast die gleichen Regeln wie bei der objektorientierten Programmierung. Auch im LDAP-Baum gibt es Objekte, Klassen, Vererbung und Polymorphie.

Die Aufgabe von LDAP ist es, die Objekte abzubilden und miteinander in Beziehung zu bringen. Ein Objekt wird im LDAP-Baum als Verzeichniseintrag bezeichnet. Jedes Objekt wird über seinen eindeutigen Namen, den Distinguished Name (dn), im Directory Information Tree (DIT) angelegt, der ähnlich wie der Name einer Datei im Dateisystem behandelt wird. Durch die verschiedenen Objekte entsteht so nach und nach eine Baumstruktur.

Im LDAP-Baum wird zwischen zwei verschiedenen Objektarten unterschieden. Zunächst gibt es die Organisational Unit (OU), bei der es sich um ein Containerobjekt handelt. In diesen Organisational Units können weitere Objekte erzeugt werden. Die OUs werden zum Aufbau der Struktur verwendet.

Die andere Objektart sind die Blattobjekte, die zum Beispiel mit der Kennzeichnung Common Name (CN) und Users ID (UID) im DIT Verwendung finden. Diese Objekte dienen zur Verwaltung der Ressourcen. Die Bezeichnungen werden aus den Objektklassen und Schemata abgeleitet, auf die im Verlauf dieses Kapitels noch weiter eingegangen wird.

[+]  OpenLDAP weist eine Besonderheit gegenüber den NDS oder dem ADS auf. Im OpenLDAP-Baum können Sie unterhalb des Blattobjekts weitere Objekte erzeugen. So ist es möglich, unterhalb eines Benutzers eine weitere OU zu erzeugen, in der dann zum Beispiel das persönliche Adressbuch des Benutzers gespeichert werden kann.

17.1.4    Objekte

Ein Objekt im LDAP-Baum ist eine zu verwaltende Ressource, die die unterschiedlichsten Typen von Ressourcen widerspiegelt. Ein Objekt kann sowohl ein Container sein, in dem weitere Objekte verwaltet werden, als auch ein Benutzer oder eine Gruppe sein. Eines ist bei allen Objekten aber immer gleich: Alle Objekte haben Eigenschaften, die Attribute. Die Attribute unterscheiden sich je nachdem, um welche Art von Objekt es sich handelt. Das Attribut, an dem ein Objekt erkannt wird, ist der common name eines Objekts. Über dieses Attribut wird das Objekt im DIT verwaltet.

Ein Objekt kann für die Verwaltung der unterschiedlichsten Aufgaben verwendet werden. Für jede Aufgabe benötigt ein Objekt unterschiedliche Attribute, deshalb werden Attribute zu Objektklassen zusammengefasst. Wenn zum Beispiel für einen Benutzer ein Objekt erstellt werden soll, das für die Anmeldung an einem UNIX-System benötigt wird, muss dem Objekt die Objektklasse posixAccount zugeordnet werden, da diese die Attribute für eine erfolgreiche Anmeldung enthält. Listing 17.1 zeigt ein Beispiel für eine objectclass. Hier wird auch deutlich, dass bestimmte Attribute vergeben werden müssen, während andere vergeben werden können.

objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY
DESC 'Abstraction of an account with POSIX attributes'
MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
MAY ( userPassword $ loginShell $ gecos $ description ) )

Listing 17.1    Beispiel für eine Objektklasse

Alle Attribute, die hier hinter MUST stehen, müssen zwingend vergeben werden, wenn einem Objekt die Objektklasse posixAccount zugeordnet wird. Die Attribute, die in der Zeile MAY stehen, können zusätzlich vergeben werden.

17.1.5    Attribute

Attribute sind die Eigenschaften von Objekten. Ein Attribut besteht aus einem Namen, mit dem das Attribut innerhalb eines Objekts eindeutig referenziert werden kann. Attribute können eine unterschiedliche Anzahl von Werten besitzen. Es gibt Attribute, die nur genau einen Wert haben dürfen, und es gibt Attribute, die mehrere Werte haben können. Um die Wiederverwendbarkeit von Attributen in verschiedenen Objektklassen zu ermöglichen, werden Attribute getrennt von Objekten verwaltet, und zwar in Form von Attributtypen. Der attributetype enthält die Komponenten wie in Listing 17.2:

attributetype ( 1.3.6.1.1.1.1.4 NAME 'loginShell'
DESC 'The path to the login shell'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )

Listing 17.2    Beispiel für ein Attribut

In der ersten Zeile werden der Object Identifier (OID) und der Name des Attributs angegeben. Beide Werte müssen im gesamten DIT eindeutig sein.

[+]  Eine Beschreibung aller OIDs können Sie unter www.alvestrand.no nachlesen.

Im Anschluss folgt eine Beschreibung, die frei formuliert werden kann. Danach gibt es die Möglichkeit, die Gleichheit EQUALITY für die Suche nach Attributen festzulegen. Ein Objekt mit dem Attribut loginShell würde nur angezeigt, wenn der Suchbegriff exakt, inklusive der Groß- und Kleinschreibung, übereinstimmt. Im Anschluss folgt noch eine Syntaxbeschreibung in Form eines OID. Alle möglichen OIDs können Sie im RFC 2252 nachlesen. Durch den OID wird festgelegt, um was für eine Art von Objekt es sich hier handelt, zum Beispiel um eine Zahl, eine Zeichenkette oder ein anderes Objekt.

17.1.6    Schema

Die Objektklassen werden jetzt nicht einzeln dem LDAP-Server zugeordnet, sondern in Gruppen zu einem Schema zusammengefasst. Für Schemata gilt das Gleiche wie für Objektklassen: Die Standardschemata sollten nicht erweitert werden, da es sonst bei einer eventuellen Zusammenführung zweier Bäume zu Konflikten kommt. Wenn Sie eigene Attribute benötigen, sollten Sie immer eine eigene Objektklasse in einem eigenen Schema erzeugen. Ein eigenes Schema können Sie auch gut in einen beliebigen LDAP-Baum integrieren. Ein wichtiger Punkt bei der Erstellung eines eigenen Schemas ist der OID für die Attribute und Objektklassen. Natürlich können Sie den OID selbst wählen. Was tun Sie, wenn der selbst gewählte OID schon vergeben ist und später eine Zusammenführung gerade mit diesem Baum stattfinden soll? Deshalb sollten Sie Ihren OID immer registrieren. Den eigenen OID können Sie kostenlos unter der URL http://pen.iana.org/pen/PenApplication.page registrieren. Mit diesem Formular erhalten Sie einen OID vom Typ 1.3.6.1.4.1.*. Darunter können Sie nun die eigenen Attribute erstellen und nummerieren.

Neben einem eigenen OID sollten Sie für die Namen ein Präfix festlegen, mit dem alle Attributnamen im eigenen Schema beginnen. Wollen Sie zum Beispiel ein Schema für die Verwaltung von Tauchgebieten erstellen, kann jedes Attribut mit dem Präfix »DivingPlace« beginnen. Beispiele für Attributnamen wären »NAME DivingPlaceName«. Listing 17.3 zeigt ein Beispiel für ein eigenes Schema:

# Schema for Adminbuch about Divesites
#
# Last change: March 15, 2017
#
# Created by: Stefan Kania <stefan@example.net>
#
# General guideline:
# 1. The language in this file is english
# 2. Every OID in this file must look like this: ns.a.b.c., where
# ns - the official namespace of the DiveSite schema:
# 1.3.6.1.4.1.12345
# a - Reserved, must always be 1 for the DiveSite schema.
# b - Entry type (1:attribute, 2:object)
# c - Serial number (increased with every new entry)
# 3. Every entry in this file MUST have a "DESC" field, containing a
# suitable description!
# 4. Attributes are listed in front of objects. All entries must be
# ordered by their serial number.
# 5. All attributenames must start with 'DivingPlace'
#
# This schema is not depending on other schemas


# Attribute type definitions
attributetype (1.3.6.1.4.1.12345.1.1.1
NAME 'DivingPlaceName'
DESC 'Name of the diveplace'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{100}
SINGLE-VALUE)

attributetype (1.3.6.1.4.1.12345.1.1.2
NAME 'DivingPlacePhoto'
DESC 'JPEG photo of the diveplace'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.28
SINGLE-VALUE)

attributetype (1.3.6.1.4.1.12345.1.1.3
NAME 'DivingPlaceStreetName'
DESC 'streetname of the diveplace'
EQUALITY caseIgnoreListMatch
SUBSTR caseIgnoreListSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
SINGLE-VALUE)

attributetype (1.3.6.1.4.1.12345.1.1.4
NAME 'DivingPlaceZipCode'
DESC 'Zipcode of diveplace'
EQUALITY caseIgnoreListMatch
SUBSTR caseIgnoreListSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
SINGLE-VALUE)

attributetype (1.3.6.1.4.1.12345.1.1.5
NAME 'DivingPlaceCity'
DESC 'Cityname of the diveplace'
EQUALITY caseIgnoreListMatch
SUBSTR caseIgnoreListSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
SINGLE-VALUE)

attributetype (1.3.6.1.4.1.12345.1.1.6
NAME 'DivingPlaceCountry'
DESC 'Countryname of the DivingPlace'
EQUALITY caseIgnoreListMatch
SUBSTR caseIgnoreListSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.41
SINGLE-VALUE)

attributetype (1.3.6.1.4.1.12345.1.1.7
NAME 'DivingPlacePhonenumber'
DESC 'Official phonenumber of the diveplace'
EQUALITY telephoneNumberMatch
SUBSTR telephoneNumberSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.50)

attributetype (1.3.6.1.4.1.12345.1.1.8
NAME 'DivingPlaceHomepage'
DESC 'Official homepage of the diveplace'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{255})

attributetype (1.3.6.1.4.1.12345.1.1.9
NAME 'DivingPlaceMail'
DESC 'Mailaddress of the diveplace'
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{256} )

attributetype ( 1.3.6.1.4.1.12345.1.1.10
NAME 'DivingPlaceOK'
DESC 'If set to true then the diveplace is ok'
EQUALITY booleanMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
SINGLE-VALUE )

# Objectclass definitions
objectclass ( 1.3.6.1.4.1.12345.1.2.1
NAME 'DiveSite'
DESC 'Objectclass to manage all divesites'
SUP top STRUCTURAL
MUST (DivingPlaceName $ DivingPlaceCity)
MAY (DivingPlacePhoto $ DivingPlaceStreetName $ DivingPlaceZipCode
$ DivingPlaceCity $ DivingPlaceCountry $ DivingPlacePhonenumber
$ DivingPlaceHomepage $ DivingPlaceMail $ DivingPlaceOK))

Listing 17.3    Beispiel eines eigenen Schemas

[+]  Achten Sie darauf, dass die Zeilen nach attributetype und objectclass eingerückt sind, sonst kommt es beim Start des LDAP-Servers zu Fehlern.

Jedes der hier verwendeten Attribute kann sowohl über den OID als auch über den Namen eindeutig referenziert werden. Durch die Verwendung eines eigenen Suffixes kann es auch nicht zu Verwechslungen mit Standardattributen kommen. Durch die Verwendung von SUP top STRUCTURAL als Typ ist die Objektklasse von keiner anderen Objektklasse abhängig, und somit kann ein Objekt erstellt werden, das nur aus dieser Objektklasse besteht. Die komplette Beschreibung, wie Sie ein eigenes Schema aufbauen können, inklusive aller Syntaxbeschreibungen, finden Sie im RFC 2252.

17.1.7    Das LDIF-Format

Damit Sie nach der Konfiguration des LDAP-Servers die ersten Objekte in dem Baum erstellen können, benötigen Sie Dateien im Lightweight Database Interchange Format (LDIF).

In diesen Dateien werden die Objektklassen und Attribute mit ihren Werten für das zu erstellende Objekt angelegt und anschließend mit dem Kommando ldapadd in den Verzeichnisbaum eingetragen. Listing 17.4 zeigt zwei Beispiele für LDIF-Einträge:

dn: ou=users,dc=example,dc=net
ou: users
objectClass: organizationalUnit

dn: uid=skania,ou=users,dc=example,dc=net
uid: skania
cn: Stefan
sn: Kania
userPassword: {crypt}wUnJ/MvLSCoPQ
loginShell: /bin/bash
uidNumber: 501
gidNumber: 100
homeDirectory: /home/skania
shadowMin: -1
shadowMax: 999999
shadowWarning: 7
shadowInactive: -1
shadowExpire: -1
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount

Listing 17.4    Beispiel für eine LDIF-Datei

Im ersten Teil wird eine neue organisatorische Einheit (OU) erzeugt, in der später die Benutzer erstellt werden sollen. Als erste Zeile muss immer der DN des Objekts stehen. Das Objekt gehört zu den Objektklassen top und organizationalUnit. Nach dem letzten Attribut folgt eine Leerzeile. Diese Leerzeile dient als Trennung zwischen zwei Objekten und ist immer dann erforderlich, wenn mit einer LDIF-Datei mehrere Objekte erzeugt werden sollen.

Bei dem zweiten Objekt handelt es sich um einen Benutzer. Hier sehen Sie, wie das Objekt aus mehreren Objektklassen zusammengesetzt wird, aber auch, dass nicht alle Attribute aus den Objektklassen Verwendung finden.

Mithilfe der LDIF-Dateien können Sie beliebig viele Objekte auf einmal erstellen oder verändern. Zusammen mit einem Shell-Skript wäre es auch möglich, die entsprechenden Werte für die Attribute aus einer anderen Datei auszulesen und damit komplexe Änderungen an vielen Objekten innerhalb des gesamten DITs durchzuführen.