Linux NetMag
Titel: Authentifizierung an einem LDAP-Server
URL: http://www.linuxnetmag.com/de/issue7/m7authldap1.html
Artikel vom: 15.12.2001
Autor: Marcel Alburg


Warum eine Anmeldung an einem LDAP Server.

Angenommen man möchte einen Web Server aufstellen, wo sich ein Kunde anmelden und danach über das Internet E-Mails abfragen und/oder versenden kann u.a. (siehe www.gmx.de, www.web.de oder http://linuxali.dyndns.org:4141 ).

Dazu muss der Kunde aber als User auf dem Web Server eingerichtet werden. Was wiederum bedeutet, dass man entweder den Web Server als root laufen lässt (Nicht zu empfehlen), um dann das Kommando useradd und groupadd ausführen zu können. Oder man legt alle User in einer Datenbank ab, wo das System bei einem Login nachschaut, ob der User existiert.

Diese zweite Möglichkeit ist zu einem sicherer und zum anderen hat man einen einzigen Punkt im Netzwerk, wo sich alle User anmelden (ähnlich der NDS von Novell) und man kann diese auch zentral verwalten (Single Point of Administration).

Benötigte Software

OpenLDAP 2.x.x (http://www.openldap.org/software/download/) (In diesem Tutorial wurde die OpenLDAP Version 2.0.12 verwendet)

Nss_ldap (http://www.padl.com/nss_ldap.html)

Pam_ldap (http://www.padl.com/pam_ldap.html)

Pam-devel (http://www.tuxfinder.com) (Wird nur benötigt, wenn PAM nicht selber kompiliert wurde)

Debian User brauchen nur das Paket libpam0g-dev ("apt-get install libpam0g-dev")

Openldap sollte schon fertig konfiguriert sein, falls dies noch nicht der Fall ist und man Schwierigkeiten bei der Einrichtung hat, dann könnte die Anleitung von Thomas Kroll (http://www.linuxnetmag.com/de/issue6/m6ldap1.html) weiterhelfen.

Installation der Software

Nach dem Entpacken der Pakete nss_ldap und pam_ldap mit:

  >> tar xvfz nss_ldap....tar.gz
  >> tar xvfz pam_ldap....tar.gz
  
müssen diese beiden noch kompiliert und installiert werden.

Dieses erfolgt durch:

  >> ./configure
  >> make
  >> make install
  

in den jeweiligen Verzeichnissen der Pakete.

Je nach Ausstattung des Rechners, kann die Installation einige Zeit in Anspruch nehmen.

Konfiguration der Software

Um die nachfolgenden Objekte - für die LDAP Anmeldung - in die Datenbank des LDAP Servers speichern zu können, muss man die Datei slapd.conf (liegt in dem Konfigurationsordner von OpenLDAP) anpassen.

Dies sollte wie folgt aussehen:

Slapd.conf
			
   include		/etc/openldap/schema/core.schema
   include		/etc/openldap/schema/cosine.schema
   include		/etc/openldap/schema/nis.schema
   include		/etc/openldap/schema/inetorgperson.schema
  
   # Das sind die Dateien, welche die Objekte definieren,
   # diese werden vor Start des Server mit eingebunden
   # Diese Einträge müssen geändert werden
  
   # Die folgenden Daten sollten schon vorhanden
   # sein, da sonst der LDAP Server nicht korrekt funktionieren würde
  
   pidfile		/usr/local/var/slapd.pid
   argsfile	        /usr/local/var/slapd.args
  			
   # Das sind Daten, die für den Start des LDAP Servers notwendig sind
  			
   database		ldbm
   suffix			"dc=alkronet,dc=de"
  
   # Dieser Eintrag bestimmt Ihr höchstes Objekt in Ihrer LDAP Datenbank
   # Dieser Wert muss angepasst werden
  
   rootdn			"cn=Manager,dc=alkronet,dc=de"
   # Dieser Eintrag bestimmt eine Person, welche alle Rechte auf die
   # darauffolgenden Objekte in der LDAP Datenbank hat
   # Dieser Wert muss angepasst werden
  
   rootpw		        test
   
   # Das root Passwort
  		        
   directory	        /usr/local/var/openldap-ldbm
  			
   # Ordner in dem sich die LDAP Datenbank befindet 
          		
   defaultaccess          write
   
   # Standardrechte für jeden User
   # Indices to maintain
   index	objectClass eq
  


Da die Programme nss_ldap und pam_ldap auf die Datei /etc/ldap.conf zugreifen, muss diese ebenfalls angepasst werden. (Achtung nicht /etc/openldap/ldap.conf) (es kann aber auch sein, dass sich die Dateien ganz woanders befinden, wenn man bei dem Configure Script die Option -sysconfdir= ... angegeben hat. Dann befinden sich die Dateien in dem mit angegeben Ordner).

Ldap.conf
   		
   host 127.0.0.1
   # Ort, wo man den LDAP Server erreichen kann
   			
   base dc=alkronet,dc=de
   # Die Basis des LDAP Servers
   
   pam_filter objectclass=posixAccount
   # Bei Anmeldung werden alle Objekte, welche in der ObjektClass 
   # posixAccount enthalten sind, nach dem User durchsucht
   
   pam_login_attribute uid
   # sowie auch welche, die das Attribut uid enthalten
   
   nss_base_passwd	o=auth_user,dc=alkronet,dc=de?one
   nss_base_shadow	o=auth_user,dc=alkronet,dc=de?one
   nss_base_group	o=auth_group,dc=alkronet,dc=de?one
   
   # gibt den LDAP Ort an, wo sich die Anmeldedaten befinden müssen
  
   sslno 
   # ssl verbindungen = nein
  


Danach sollte eine Datei angelegt werden, wo ein Organisations Container Objekt erstellt wird.

Diese Datei könnte z.B. folgendermaßen aussehen:

User.ldif
   dn: o=auth_user, dc=alkronet, dc=de
   o: auth_user
   objectclass: organization
   
   # diese Zeilen erstellen ein Organisations Objekt, welches 
   # "auth_user" heißt. in diesem Objekt sollten im 
   # späteren Verlauf die User eingetragen werden
   
   
   		       
   dn: o=auth_group, dc=alkronet, dc=de
   o: auth_group 
   objectclass: organization
   
   # diese Zeilen erstellen ein Organisations Objekt, welches 
   # "auth_group" heißt. in diesem Objekt sollten im späteren 
   # Verlauf die Gruppen eingetragen werden
   
   
   
   dn: cn=user, o=auth_group, dc=alkronet, dc=de
   objectClass: posixGroup
   objectClass: top
   cn: user
   userPassword: {crypt}x
   gidNumber: 10
   
   # hier wird die Gruppe "user" angelegt mit der Gruppen Nummer 10
   		          
   
   dn: uid=tester, o=auth_user, dc=alkronet, dc=de
   uid: tester
   cn: Test Tester
   objectclass: account
   objectclass: posixAccount
   objectclass: top
   objectclass: shadowAccount
   userPassword: test
   shadowLastChange: 11472
   shadowMax: 99999
   shadowWarning: 7
   uidNumber: 1000
   gidNumber: 10
   homeDirectory: /home/tester
   loginShell: /bin/bash
   		         
   # uid = User- und Loginname
   # cn = Vorname, Nachname wäre sn
   # danach werden die Objektklassen definiert
   # für die etwas kniffligen Werte mit shadow* sollten ggf. die 
   # Manpages zu passwd, useradd und shadow konsultiert werden
   # uidNumber = Usernummer oder User ID
   # gidNumber = Gruppennummer oder ID, wo der User Mitglied ist
   # homeDirectory = Heimatverzeichnis 
   # loginShell = Shell nach dem Login
  


Nachdem diese Datei angelegt wurde, kann sie zum LDAP Server hinzugefügt werden.

Dieses geschieht mit dem Befehl ldapadd.

  >> ldapadd -x -D "cn=manager, dc=alkronet, dc=de" -W -f User.ldif
  

Danach sollte der User in die LDAP Datenbank eingetragen sein.

Jetzt ist der User zwar in der LDAP Datenbank enthalten, aber bei einer Anmeldung wird auf diese noch nicht zugegriffen.

Deshalb muss der PAM Dienst noch an den LDAP Server angepasst werden.

Das System für die Anmeldung an einem LDAP Server vorbereiten

Als erstes muss in der Datei /etc/nsswitch.conf eingetragen werden, das die Gruppen-, Benutzer- und Passwortinformationen nicht mehr nur in Dateien (files) sondern auch auf einem LDAP Server liegen können.

Das könnte folgendermaßen aussehen.


/etc/nsswitch.conf
   passwd:	ldap files
   group:		ldap files
   shadow:	ldap files
   
   # Hier wurde jetzt ldap hinzugefügt
   			
   hosts:		files dns
   networks:      files   
   protocols:	db files
   services:	db files
   ethers:	db files
   rpc:		db files
   netgroup:	nis
  


Wurden die Pakete nss-ldap und pam-ldap selber kompiliert worden sein, dann sollte es eine Datei namens ldap.conf im Ordner /usr/local/etc geben. Falls dies nicht der Fall ist, wurde wahrscheinlich beim Kompilieren die Option -sysconfdir mit angegeben. In dem mit angegebenen Ordner befindet sich dann auch die Datei ldap.conf.

Debian User die mit apt-get gearbeitet haben, verfügen über die beiden Dateien pam-ldap.conf und libnss-ldap.conf. Diese beiden Dateien sind die gleichen, und man könnte demzufolge auch einen link erstellen (z.B.: ln -snf /etc/pam-ldap.conf /etc/libnss-ldap.conf).

Der Inhalt dieser Datei bestimmt, an welchen LDAP Server sich angemeldet werden soll und in welchem Objekten sich die User-/Passwortangaben befinden.

Diese könnte folgendermaßen aussehen.

Ldap.conf oder ldap-pam.conf
			
   host 127.0.0.1
   # IP des LDAP Servers
   
   base dc=alkronet,dc=de
   # Basis-Object des Servers
   
   # binddn cn=proxyuser,dc=padl,dc=com
   # bindpw secret
   # rootbinddn cn=manager,dc=padl,dc=com
   # port 389
   			
   # Falls man sich an dem LDAP Server anmelden muss um Daten
   # durchsuchen zu können, muss der User und dass Passwort hier
   # mit angegeben werden
   		        
   # timelimit 30
   # Gibt die Zeit an, wie lange ein User maximal in dem LDAP Server
   # etwas suchen darf     
   
   # bind_timelimit 30
   # Gibt die Zeit, an wie lange ein User maximal mit dem LDAP Server
   # verbunden sein darf
   		        
   # idle_timelimit 3600
   # Gibt die Zeit an, nach der die Verbindung gelöscht wird, wenn
   # nichts mehr nachgefragt wird
   
   pam_filter objectclass=posixAccount
   # Durchsuchen aller Einträge, wo die ObjectClass=PosixAccount ist
   			
   pam_login_attribute uid
   # der Username ist im Attribut uid gespeichert
   
   nss_base_passwd	o=auth_user, dc=alkronet,dc=de?one
   nss_base_shadow        o=auth_user, dc=alkronet,dc=de?one
   nss_base_group		o=auth_group, dc=alkronet,dc=de?one
   			
   # Gibt den Path zu den Passwörtern, den Shadow-Einträgen
   # und den Gruppen Informationen an
   # das ?one bedeutet, dass nur ein Eintrag genutzt werden darf
   # und dementsprechend sollte auch nur vorhanden sein.
   # Falls dies nicht der Fall ist, nimmt er das erste Passwort, das bei
   # der Suche gefunden wird.
  			
   Sslno
   # SSL Verbindungen wird nicht unterstützt
  


Des weiteren müssen jetzt für jeden Dienst, der auf dem System läuft und sich gegen einen LDAP Server authentisieren soll, die Konfigurationsdateien angepasst werden.

Die Konfigurationsdateien befinden sich im Ordner /etc/pam.d. Einige Beispiele werden von der Pam Software aber schon mitgebracht, welche sich im example Ordner befinden.

Hat man Pam nicht selber kompiliert, dann sollten sie sich in /usr/share/doc/pam, /usr/share/doc/packages/pam oder in /usr/share/doc/libpam befinden.

Die Datei, in welcher bei einem Login nachgeschaut wird, heißt login und könnte folgendermaßen aussehen.


/etc/pam.d/login
   auth		required	/lib/security/pam_securetty.so
   auth		required	/lib/security/pam_nologin.so
   auth		sufficient	/lib/security/pam_ldap.so use_first_pass
   auth		required	/lib/security/pam_unix_auth.so try_first_pass
   account	sufficient	/lib/security/pam_ldap.so
   account	required	/lib/security/pam_unix_acct.so
   password       required	/lib/security/pam_cracklib.so
   password       required	/lib/security/pam_ldap.so
   password       required	/lib/security/pam_pwdb.so use_first_pass
   session	required	/lib/security/pam_unix_session.so
   
   # für jede Sektion (auth, account, password) sollte jetzt
   # /lib/security/pam_ldap.so vorhanden sein.
   
   # use_first_pass bedeutet, dass das erste eingegebene Passwort
   # genutzt wird und nicht mehr in den files (shadow und passwd) nachgeschaut wird.
  


Die anderen Dateien in diesem Ordner können ebenfalls so angepasst werden, oder man nimmt die Dateien, welche von Pam als Beispiele mitgeliefert wurden.


Jetzt sollte die Anmeldung schon funktionieren. Bei mir war aber ein Neustart vonnöten. (Vielleicht muss irgendein Dienst doch noch neu gestartet werden).

PHP Script um einem User hinzuzufügen

add_user.php
   $username = testuser;
   $password = testuser;
   $user_id  = 1005;
   	        	
   $ldap_server = "127.0.0.1";
   $ldap_base   = "dc=alkronet,dc=de";
   
   # Achtung, es kann zu Anmeldefehlern führen, wenn mehrere 
   # User die gleiche ID haben
   
   $entries["uid"]=strtolower($username);
   $entries["cn"]=$username;
   $entries["objectclass"][0]="account";
   $entries["objectclass"][1]="posixAccount";
   $entries["objectclass"][2]="top";
   $entries["objectclass"][3]="shadowAccount";
   $entries["userPassword"]=$password;
   $entries["shadowLastChange"]="11472";
   $entries["shadowMax"]="99999";
   $entries["shadowWarning"]="7";
   $entries["uidNumber"]=$user_id;
   $entries["gidNumber"]="10";
   $entries["homeDirectory"]="/home/".$username;
   $entries["loginShell"]="/bin/false";
   
   $connect  = ldap_connect($ldap_server);
   $bind     = ldap_bind($connect, "cn=manager, ".$ldap_base, "test");
      
   if (!$bind || !$connect) {
      echo "Die Verbindung zum Anmelde-Server konnte nicht hergestellt werden.";
      exit;
   }
   
   ldap_add($connect, "uid=".strtolower($username).", o=auth_user, ".$ldap_base, $entries);

if (ldap_error($connect) != "Success") { echo "<p>".ldap_error($connect)."</p>"; }