Authentifizierung über LDAP
From NJH-Wiki
- Autoren
- Frank Prößdorf, Volker Grabsch
Contents |
Voraussetzungen
Diese Howto geht von folgenden Gegebenheiten aus:
- Installiert ist ein SuSE Linux
Das meiste gilt aber für andere Distributionen genauso.
Schritt für Schritt
Installation
Zuerst installieren wir alle benötigten Pakete:
yast -i openldap2 nss_ldap pam_ldap openssl openssl-devel
Konfiguration
Nachdem wir über
slappasswd
ein Passwort erstellt haben tragen wir folgendes in die Konfigurationsdatei des LDAP Servers (/etc/openldap/slapd.conf) ein:
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/inetorgperson.schema
schemacheck on
pidfile /var/run/slapd/slapd.pid
argsfile /var/run/slapd/slapd.args
modulepath /usr/lib/openldap/modules
loglevel 256
database ldbm
cachesize 10000
suffix "o=organisation,c=de"
rootdn "cn=admin,o=organisation,c=de"
rootpw {SSHA}xxxxxxxxxxxxxxxxxxxxxx
directory /var/lib/ldap
access to attrs=userPassword
by self write
by * auth
access to *
by * read
Sind wir hiermit fertig, können wir den Server schonmal starten. Wenn der Server läuft und wir ihn in der Prozessliste sehen, fügen wir nun in die LDAP Konfigurationsdatei des Clients (/etc/openldap/ldap.conf) die entsprechende URI und Base ein:
URI ldap://127.0.0.1:389/ ldap://server2:389/ BASE o=organisation,c=de ldap_version 3 scope sub #ssl start_tls #TLS_REQCERT allow
Dabei müssen wir darauf achten das die Zeilen in denen es um SSL/TLS geht auskommentiert werden. Es ist möglich bei der URI mehrere Server anzugeben. Fällt der erste Server aus springt dann der zweite ein.
scope sub bedeutet dabei, dass immer der gesamte Unterbaum durchsucht wird. Ist scope hingegen base wird nur in der aktuellen Ebene gesucht und bei one genau eine Ebene tiefer. Eine veranschaulichende Grafik findet sich in der Microsoft LDAP Dokumentation.
Daten einfügen
Der Rest dieser Konfigurationsdatei braucht uns zunächst nicht zu interessieren. Nun wollen wir eine erste kleine Struktur entwerfen um sie in die LDAP Datenbank einzufügen. Die hier erstelle Struktur ist minimal und wird individuell verändert werden müssen. Um diese also nun zu kreieren, erstellen wir eine Datei basis.ldif:
dn: o=organisation,c=de objectclass: organization objectclass: top o: organisation dn: ou=users,o=organisation,c=de objectclass: organizationalunit ou: users dn: uid=frank,ou=users,o=organisation,c=de objectclass: posixAccount objectclass: shadowAccount objectclass: inetOrgPerson sn: frank cn: frank uid: frank uidNumber: 1000 gidNumber: 100 homeDirectory: /home/frank loginShell: /bin/bash userPassword: test gecos: Frank Proessdorf dn: ou=groups,o=organisation,c=de objectclass: organizationalunit ou: groups dn: cn=mygroup,ou=groups,o=ibb,c=de objectclass: posixGroup cn: mygroup gidNumber: 200 memberuid: frank
Nachdem wir die Datei nun gespeichert haben, gliedern wir sie in den LDAP ein:
ldapadd -x -D "cn=admin,o=organisation,c=de" -W -f basis.ldif
Erklärung:
- -x
- einfache Authentifizierung
- -D
- BindDN des Nutzers, mit dessen Autorisation man die Daten hinzufügt (hier: der RootDN)
- -W
- frage nach dem Passwort an der Kommandozeile
- -f
- die LDIF-Datei mit den Daten, die man in den LDAP hinzufügen möchte
Wurde dieses Kommando fehlerfrei ausgeführt, sind wir ein gutes Stück weiter und können uns die Datensätze über
ldapsearch -x
anzeigen lassen. Wird dieses Kommando nicht fehlerfrei ausgeführt, liegt es unter Umständen daran, dass die BaseDN (BASE) in der /etc/ldap.conf nicht richtig gesetzt wurde, oder dass /etc/ldap.conf und /etc/openldap/ldap.conf nicht übereinstimmen. Erstere der beiden wird von pam und nss genutzt, und letztere wird von den OpenLDAP utilities verwendet. Hier hilft am besten ein Softlink:
rm /etc/ldap.conf ln -s /etc/openldap/ldap.conf /etc/ldap.conf
Haben wir schon Daten im LDAP Baum und wollen diese lediglich verändern so hilft uns ein
ldapmodify -x -D "cn=admin,o=ibb,c=de" -W -f basis.ldif
Übrigens können wir später folgendermaßen das Passwort eines Benutzers (hier: frank) ändern:
ldappasswd -D "cn=admin,o=organisation,c=de" -x -W -S cn=frank,ou=users,o=organisation,c=de
PAM & NSS
Nun folgt das Einstellen von NSS und PAM (Pluggable Authentication Module), welche es erlauben, die Quelle zur Authentifizierung für System und verschiedene Dienste zu ändern. Der Login-Vorgang auf einem Linux-System gestaltet sich demzufolge in etwa folgendermaßen: Der Benutzer gibt seine Login-Kennung und sein persönliches Paßwort auf der Konsole ein. Daraufhin überprüft das System über die im "Name Service Switch" konfigurierten Methoden, ob die Kennung dem System bekannt ist, zu welcher Gruppe sie gegebenenfalls gehört, usw. Anschließend wird der Anwender entsprechend der PAM-Konfiguration authentifiziert In der /etc/nsswitch.conf sollte der LDAP als Quelle hinzugefügt werden:
passwd: files ldap group: files ldap shadow: files ldap
Im Verzeichnis /etc/pam.d liegen nun Dateien, die den einzelnen Services Module zuordnen, die verschiedene Loginmöglichkeiten erlauben. Für den sshd könnte die PAM Konfigurationsdatei zum Beispiel folgendermassen aussehen:
auth sufficient pam_ldap.so auth sufficient pam_unix2.so auth required pam_nologin.so auth required pam_env.so account sufficient pam_ldap.so account sufficient pam_unix2.so account required pam_nologin.so password sufficient pam_unix2.so use_authtok password sufficient pam_ldap.so use_first_pass password required pam_pwcheck.so session required pam_unix2.so session required pam_limits.so
Sollte hierbei ein "required" fehlschlagen, so werden die folgenden Module zwar getestet, aber ultimativ resultiert ein Fehler am Ende. Schlägt ein "sufficient" fehl, ein darauffolgendes "sufficient" ist jedoch erfolgreich, so wird die Aktion am Ende als erfolgreich gewertet. Die Änderungen werden unmittelbar übernommen und wir können uns nun erfolgreich über ssh einloggen. (Nach Entfernen dieser Änderungen, versucht das System sich dennoch über LDAP einzuloggen.. unload von Bibliotheken?)
Homeverzeichnis
Um nun bei erster Authentifizierung eines eingerichteten LDAP Benutzers an einem neuen Rechner das Homeverzeichnis automatisch erstellen zu lassen muss folgende Zeile in der /etc/pam.d/sshd hinzugefügt werden:
session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
sudo
Zunächst sollten wir das SuSE sudo Paket löschen und den Sourcecode von Sudo von herunterladen und kompilieren. Dies ist nötig, da das Programmpaket von SuSE nicht mit LDAP-Unterstützung (--with-ldap) kompiliert wurde.
Nach dem Herunterladen wird das Archiv zunächst entpackt:
tar xvfz sudo-1.6.8p9.tar.gz
War dies erfolgreich, wechseln wir in das entsprechende Verzeichnis und kompilieren es mit den richtigen Optionen:
cd sudo-1.6.8p9 ./configure --prefix=/usr/packages/sudo --with-ldap --with-pam make make install ln -s /usr/packages/sudo/bin/sudo /usr/bin/ ln -s /usr/packages/sudo/bin/sudoedit /usr/bin/
Dies sollte ohne Probleme funktionieren, da die LDAP Bibliotheken im Standardpfad hinterlegt sind. Ist dies nicht der Fall müssen noch folgende Pakete per yast hinzugefügt werden
openldap2-devel pam-devel
Nun kopieren wir noch die entsprechende PAM-Konfigurationsdatei:
cp sample.pam /etc/pam.d/sudo
Und wir legen das folgende Schema in /etc/openldap/schema/sudo.schema an:
#
# schema file for sudo
#
attributetype ( 1.3.6.1.4.1.15953.9.1.1
NAME 'sudoUser'
DESC 'User(s) who may run sudo'
EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
attributetype ( 1.3.6.1.4.1.15953.9.1.2
NAME 'sudoHost'
DESC 'Host(s) who may run sudo'
EQUALITY caseExactIA5Match
SUBSTR caseExactIA5SubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
attributetype ( 1.3.6.1.4.1.15953.9.1.3
NAME 'sudoCommand'
DESC 'Command(s) to be executed by sudo'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
attributetype ( 1.3.6.1.4.1.15953.9.1.4
NAME 'sudoRunAs'
DESC 'User(s) impersonated by sudo'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
attributetype ( 1.3.6.1.4.1.15953.9.1.5
NAME 'sudoOption'
DESC 'Options(s) followed by sudo'
EQUALITY caseExactIA5Match
SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL
DESC 'Sudoer Entries'
MUST ( cn )
MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoOption $
description )
)
Nun fügen wir das Schema noch in der /etc/openldap/slapd.conf hinzu:
include /etc/openldap/schema/sudo.schema
... und starten den LDAP-Server neu:
rcldap restart
Schon können wir entsprechende Benutzer in den LDAP Verzeichnisbaum hinzufügen. Dies tun wir, indem wir vorher einen sudoers-Knoten erstellen und dann die Benutzer an diesen Knoten anhängen:
dn: ou=sudoers,o=organisation,c=de objectclass: organizationalUnit ou: sudoers dn: cn=frank,ou=sudoers,o=organisation,c=de objectClass: top objectClass: sudoRole cn: frank sudoUser: frank sudoHost: ALL sudoCommand: ALL
Oder wir transformieren einfach gleich die vorher angelegte sudoers-Datei.
Damit sudo mit den im LDAP angelegten Benutzern funktioniert, müssen wir folgende Zeile in die /etc/openldap/ldap.conf eintragen:
sudoers_base ou=sudoers,o=organisation,c=de
TODO: Aufgefallen ist mir, dass als sudoHost anscheinend nur ALL funktioniert. Jegliche Versuche, die ich unternommen habe mit IP, Host, localhost und dergleichen, liefen schief. Sudo hatte dann gesagt, dass der Benutzer in diesen Fällen nicht zu den sudoers gehört.
Replikation
Um auf den Clients für eine gewisse Redundanz zu sorgen, kann man in der ldap.conf mehrere LDAP Server angeben, sodass der Zugriff auch funktioniert, wenn einer der Server ausgefallen sein sollte:
URI ldap://server1:389 ldap://server2:389
Hierfür ist die Grundvorraussetzung, dass wir den ersten erstellten LDAP Server schon kopiert haben, d.h. auch alle Konfigurationsdateien und den Inhalt.
slapcat > ldap_inhalt.txt tar cvfz ldap_copy.tgz /etc/openldap/slapd.conf /etc/openldap/ldap.conf /etc/pam.d/sshd ldap_inhalt.txt scp ldap_copy.tgz server2:ldap_copy.tgz
Haben wir den zweiten Server nun fehlerfrei laufen können wir mit der Einrichtung der Replikation beginnen.
Wir konfigurieren zunächst den Master und fügen in dessen /etc/openldap/slapd.conf folgende Einträge hinzu.
replogfile /var/lib/slurpd/replica/slurpd.replog
replica uri=ldap://server2:389
binddn="cn=admin,o=organisation,c=de"
bindmethod=simple
credentials=secret
Hierbei ist wichtig, dass die binddn und die credentials eigentlich nicht mit der rootdn übereinstimmen sollen. Dies ist hier nur zu Testzwecken. Eigentlich sollte ein Zugang genommen werden, der Nur-Lese-Rechte auf den gesamten LDAP hat.
Weiterhin müssen wir beachten, dass das slurpd.replog dem Benutzer ldap gehört und dieser auf die Rechte hat, in das Verzeichnis /var/lib/slurpd/replica/ zu wechseln.
Sollte der LDAP Replikationsdaemon slurpd noch nicht laufen, starten wir diesen. Vorher starten wir den slapd neu.
rcldap restart rcslurpd start
Nun kommt der Slave dran. Auf diesem erweitern wir ebenfalls nur die /etc/openldap/slapd.conf um folgende Einträge:
updatedn "cn=admin,o=organisation,c=de" updateref server1:389
Wir dürfen nicht vergessen, den slapd wiederum neuzustarten:
rcldap restart
Nun sollten sich die beim Master vollzogenen Änderungen auf den Slave automatisch replizieren.
Achtung: Wollen wir phpldapadmin verwenden, so muss in der Konfigurationsdatei der Master angegeben werden. Änderungen beim Slave produzieren beim PHPLdapAdmin folgende Fehlermeldung:
LDAP meldet: Internal (implementation specific) error Fehlernummer: 0x50 (LDAP_OTHER) Beschreibung:
und in /var/log/messages
Sep 22 12:14:06 test22 slapd[24419]: No structuralObjectClass for entry (uid=test,ou=users,o=organisation,c=de) Sep 22 12:14:06 test22 slapd[24419]: conn=79 op=1 RESULT tag=105 err=80 text=no structuralObjectClass operational attribute
LDAP-Dump sichern
Um nun als root per cron daemon einen LDAP-Dump zu sichern, können wir folgendes Script benutzen, in dem wir lediglich den von uns gewünschten Pfad angeben müssen. Niemand außer root hat dann Zugriff auf die Dateien und das Verzeichnis.
ldap_dump.sh
#!/bin/bash
######
# ldap_dump.sh
# - create an LDAP dump and save it into a "secure" directory
#
# Autor: Frank Proessdorf
######
PFAD=/root/save
DATE=`date +%Y%m%d`
DUMPFILE=ldap_dump_$DATE.ldif
# create secure folder if it doesn't exist
if [ ! -d $PFAD ]
then
echo "Sicherer Pfad wird angelegt.."
mkdir $PFAD
chmod 700 $PFAD
fi
cd $PFAD
# dump LDAP
slapcat -l $DUMPFILE
# gzip the dump
gzip $DUMPFILE
# set correct mode
chmod 600 $DUMPFILE.gz
echo "LDAP-Dump wurde gesichert."
#####
# The LDIF generated by this tool is suitable for use with slapadd(8).
# As the entries are in database order, not superior first order, they cannot
# be loaded with ldapadd(1) without first being reordered.
#####
Beim Wiederherstellen ist zu beachten, dass die Daten per slapadd und nicht per ldapadd hinzugefügt werden müssen, da sie nicht in der Baumstrukturreihenfolge gedumpt wurden.
Verschlüsselung
Nun werden wir die Kommunikation zwischen LDAP Client und Server noch verschlüsseln, um den Authentifizierungsprozess abzusichern.
Bisherige Beobachtungen hierzu:
CA, Client und Serverzertifikate wurden erstellt. Nach Kopieren der Zertifikate ins /etc/openldap Verzeichnis wurden die Konfigurationsdateien wie folgt geändert:
Auf dem Server: slapd.conf
TLSCACertificateFile /etc/openldap/cacert.pem TLSCertificateFile /etc/openldap/servercert.pem TLSCertificateKeyFile /etc/openldap/serverkey.pem TLSVerifyClient allow
Auf dem Client: ldap.conf
tls_cacert /etc/openldap/cacert.pem tls_reqcert demand
Wird TLS genutzt kann über
ldapsearch -x -ZZ
getestet werden ob die verschlüsselte Kommunikation funktioniert.
Wird SSL genutzt, so muss die URI in der ldap.conf mit ldaps:// statt ldap:// beginnen und es kann eine ganz normale Abfrage über
ldapsearch -x
vorgenommen werden.
Sollten Fehler auftreten, kann folgender Befehl helfen, diesen auf die Spur zu kommen. SSL Test
openssl s_client -connect server01.notjusthosting.com:636 -state -CAfile cacert.pem -debug
Solaris als Client
Vorraussetzungen
- Installiert ist ein Solaris10
Vorgehen sollte für andere Solaris Versionen ebenfalls funktionieren.
Vorgehen in Kurzfassung
Es gibt für allgemeine LDAP Anfragen zwei Dateien die zu erstellen sind: /var/ldap/ldap_client_cred und /var/ldap/ldap_client_file. In erstere kommen die Authentifizierungsdaten des ProxyBenutzers, in letztere die Zugriffskonfiguration.
- ldap_client_cred:
NS_LDAP_BINDDN= cn=admin,o=organisation,c=de
NS_LDAP_BINDPASSWD= {NS1}xyz123
- ldap_client_file:
NS_LDAP_FILE_VERSION= 2.0 NS_LDAP_SERVERS= server1 NS_LDAP_SEARCH_BASEDN= o=organisation,c=de NS_LDAP_AUTH= simple NS_LDAP_CACHETTL= 3600 NS_LDAP_CREDENTIAL_LEVEL= proxy NS_LDAP_SERVICE_SEARCH_DESC= passwd:ou=users,o=organisation,c=de?sub NS_LDAP_SERVICE_SEARCH_DESC= group:ou=groups,o=organisation,c=de?sub
Es bleibt wie üblich PAM und NSS zu konfigurieren. Fangen wir mit NSS an und bearbeiten in der Datei /etc/nsswitch.conf drei Zeilen, so das sie LDAP berücksichtigen. Alle anderen Zeilen berücksichtigen LDAP nicht.
passwd: files ldap group: files ldap
Nun folgt die PAM Konfiguration. Hierzu muss die Datei /etc/pam.conf geändert werden. Hierbei kann other natürlich auch gegen login, oder sonstige Dienste ersetzt werden.
other auth requisite pam_authtok_get.so.1 other auth required pam_dhkeys.so.1 other auth required pam_unix_cred.so.1 other auth binding pam_unix_auth.so.1 server_policy other auth required pam_ldap.so.1 passwd auth binding pam_passwd_auth.so.1 server_policy passwd auth required pam_ldap.so.1 other account requisite pam_roles.so.1 other account binding pam_unix_account.so.1 server_policy other account required pam_ldap.so.1
Die Option other password brauchen wir bei Solaris10 nicht, weil das Passwortmanagement über pam_authtok_store.so.1 läuft.
Nach den Änderungen müssen der //nscd// und der //ldap_cachemgr// neu gestartet werden.
Um mitzuloggen was der LDAP Caching Manager ausführt können wir das Debugging erhöhen:
/usr/lib/ldap/ldap_cachemgr -l /var/adm/messages -d 6
Siehe auch
Dies sind Quellen und weiterführende Artikel für dieses Howto.
- Wiki-Artikel
- Weblinks
- OpenLDAP Project (englisch)
- Veranschaulichung zur Suchbasis (scope) (englisch)
- Configuring LDAP Authentication (englisch)
- Zentrale Anmeldung via LDAP und Samba
- Kurze Übersicht über Objektklassen (englisch)
- LDAP Client Howto
- LDAP Server Howto
- Ausführliches OpenLDAP Howto
- Kurzes Authentifizierungs Howto über LDAP (englisch)
- LDAP Mailingliste (englisch)
- Linux LDAP Howto (englisch)
- Komplexes OpenLDAP Howto (englisch)
- OpenLDAP SSL/TLS Wrapper (englisch)
- OpenLDAP SSL/TLS Howto (englisch)
- Ausführliches PDF über OpenLDAP, Authentifizierung, Samba und SSL
- Auführliches PAM/LDAP Howto (englisch)
- PAM, NSS und MySQL Howto
- Kurze beschreibung zur PAM_access Benutzung (englisch)
- Informationen zu einem Replikationsversuch
- Solaris Forum: OpenLDAP und Solaris10 (englisch)
- Installieren und Konfigurieren von OpenLDAP für Solaris9 (englisch)
- LDAP Zukunftsaussichten (PDF) (englisch)

