js-home.org, 18.05.2012
 
 

mehr mit LDAP: Apache
2004-07-11Jürgen Schmitz
Nachdem LDAP nun schonmal läuft, bietet es sich doch an, da gleich noch mehr mit anzufangen: Zugangsberechtigungen Nein, nicht gleich den Hammer, Unix-Login, sondern harmloses mit Apache.
1Voraussetzungen
2Apache + LDAP
3Setup
 3.1 httpd.conf
 3.2 .htaccess
4Täglicher Betrieb
 4.1 Benutzer anlegen
 4.2 Gruppe anlegen
 4.3 Benutzer in Gruppe
5Kleiner Bonus
6Nachwort und Impressum
 
1 Voraussetzungen
Nachdem unser LDAP-Server aus dem ersten LDAP-Kurs (1 Vorwort) laufen sollte, werden wir im 2. Teil damit weiter arbeiten und den Zugang zu einigen Resourcen regeln.

Wir brauchen dazu einen laufenden Apache, dazu das LDAP Modul auth_ldap. Dieses sollte in modernen Distributionen in ausreichend aktueller Version drin sein (bei Debian Woody ist das libapache-auth-ldap). Läßt sich aber ansonsten auch leicht selbst compilieren.

 
2 Apache + LDAP
Wozu soll das gut sein?

Wer die Möglichkeiten des htpasswd und htaccess kennt, wird das schnell einsehen: statt einer Passwort-Datei ein Passwort-Server.

Für alle anderen: Man kann Web-Seiten mit einem Passwortschutz versehen. Die zugelassenen Kennungen (mit Passwort) müssen dann in einer Datei abgelegt werden.

Möchte man Nutzern Zugang zu verschiedenen Bereichen geben (also nicht jeder Nutzer darf überall rein, aber schon in mehrere Bereiche), ist das immer recht umständlich. Das wird durch LDAP nicht unbedingt weniger - der Mechanismus an sich ist ja der gleiche -, aber überschaubarer und wartungsfreundlicher (Nutzer könnten sogar ihr Passwort selbst ändern).

Als Besonderheit werden wir einen Weg finden, wie man ganz einfach Benutzern Zugriff auf bestimmte Bereiche gibt, auf andere jedoch nicht.
 
3 Setup
Das Setup ist relativ einfach und teilt sich in 2 Bereiche:
  • den globalen Teil in der httpd.conf
  • den intividuellen Teil pro zu schützendem Verzeichnis in den .htaccess Dateien

 
3.1 httpd.conf
Fangen wir global an:

Irgendwo stehen die LoadModule Anweisungen, dort wenns nicht schon drin ist die Zeile
LoadModule auth_ldap_module /usr/lib/apache/1.3/auth_ldap.so

oder ähnlich (je nach Pfad vom auth_ldap.so) eintragen.

Apache neu starten, feddisch mit der ersten Teil.
 
3.2 .htaccess
Jetzt wird interessant. Anhängig von unserer LDAP-Struktur muß man nun die .htaccess in die zu schützenden Verzeichnisse legen. Außerdem wollen wir unsere Besonderheit des differenzierten Zugriffs gleich mit einbauen. Das sieht z.B. so aus:
.htaccess
AuthName "Mein privater Bereich"
AuthType Basic
AuthLDAPURL ldap://ldapserver/o=js-home.org?uid
AuthLDAPGroupAttribute memberUid
AuthLDAPGroupAttributeIsDN off
require group cn=privat,ou=gruppen,o=js-home.org

Das war alles...

Sehen wir uns das ganze im Detail an!
  • AuthName ist der Name, kennen wir von früher.
  • AuthType Basic muß auch so sein, wie früher.
  • AuthLDAPURL ldap://ldapserver1/o=js-home.org?uid gibt den Hostnamen des ldapserver an (hier ldapserver1) und dann den bekannten Ursprung im LDAP-Baum (o=.....), wie immer hier js-home.org. Dann noch das Feld, mit dem der Benutzername, der in der Eingabebox im Browser eingegeben wird, verglichen werden soll - typischerweise in LDAP "uid" (jedenfalls geben das diverse LDAP-Editoren so immer wieder vor).
  • AuthLDAPGroupAttribute memberUid besagt, daß der Benutzer - oder besser dessen uid im Feld "memberUid" einer Gruppe stehen muß. Genau genommen muß er nur im Feld "memberUid" irgend eines LDAP-Objekttypes stehen.
  • AuthLDAPGroupAttributeIsDN off muß so sein, sonst geht es nicht (wer es genau wissen will, soll es mal on schalten und dann seine Logfiles auf dem LDAP-Server beobachten und sehen, wie dann die Anfragen aussehen).
  • require group cn=privat,ou=gruppen,o=js-home.org ist einfacher als es aussieht! Oben wurde bereits von einem Feld "memberUid" gesprochen. Und hier sagen wir nun, in welchem Objekt dieses Feld liegen muß. Konkret heißt das hier, daß in der Gruppe "privat" in der Organisationseinheit "gruppen" in der Wurzel "js-home.org" im Feld "memberUid" die "uid" der Benutzers stehen muß, der sich anmeldet. Noch da? Also einfach gesagt: nur wer in der Gruppe "privat" ist, darf sich anmelden. Wie dieser "Pfad" aussieht, ist völlig egal, sofern er existiert. Man kann also beliebige Hierarchien aufbauen.

War doch nicht schwer.

Kurz zusammengefaßt:

AuthName sollte man ändern, AuthLDAPURL muß man auf seinen Server und seine LDAP-Wurzel ändern und require group auf eine passende Gruppe setzen.

Dann kann man dieses .htaccess File einfach in jedes zu schützende Verzeichnis kopieren, dann ändert man den "require group" Eintrag auf eine andere Gruppe und schon dürfen nur noch die Mitglieder dieser Gruppe dort hinein.
 
4 Täglicher Betrieb
Nun möchte man den Leuten recht einfach den Zugang zu Bereichen der Webseite gestatten bzw. es ihnen nicht gestatten. Das geht, wie wir eben gelernt haben, über die Gruppenangabe in der .htaccess.

Aber die Daten müssen auch ins LDAP.

Ich benutze dazu den phpLDAPadmin. Der ist recht robust und reicht für die Zwecke mehr als aus und ist fexibel genug. Andere Tools sind da oft sehr eigen und wollen nur ihre eigene Struktur. Aber darauf bin ich ja schon im 1. LDAP-Kurz eingegangen.

 
4.1 Benutzer anlegen
Einfache Sache mit phpLDAPadmin:

Hat man noch gar nichts gemacht, sollte man erstmal etwas Ordnung einführen, also eine "ou" (Organizational Unit) in der Wurzel anlegen. Nennen wir sie "benutzer" (heute mal alles auf Deutsch).

In dem Ding drin legen wir dann einen Benutzer an, oder neudeutsch "User Account". Im phpLDAPadmin wird damit ein Posix-Account erzeugt, zur Info, falls man das nicht damit machen will.

Der "User name" wird später das LDAP-Feld "uid", also hier was sinnvolles eintragen. Achja, und ein Passwort ist imme gut, welche Encryption ist eigentlich völlig egal, natürlich ist Klartext (also clear) nicht so der Hit, aber wer weiß, ob es nicht manchmal hilfreich ist.

Die "UID Number" hat übrigens nichts mit der "uid" zu tun, sondern ist eine Zahl (uid ist ja der Loginname), wie sie z.B. im /etc/passwd steht. Da aber phpLDAPadmin nur mit Zahl glücklich ist, muß man irgendeine eingeben.

Das gleich gilt für die Gruppe, der Wert ist auch "total egal" für unsere Zwecke. Für die anderen Feld gilt das gleiche.

Klick, fertig.
 
4.2 Gruppe anlegen
Eigentlich unterscheiden sich "Gruppe anlegen" und "Benutzer anlegen" nur gering. Ich kopier deshalb mal einige Absätze und passe sie an:

Hat man noch gar nichts gemacht, sollte man erstmal etwas Ordnung einführen, also eine "ou" (Organizational Unit) in der Wurzel anlegen. Nennen wir sie "gruppen" (auch hier deutsch, wenn, dann konsequent).

In dem Ding drin legen wir dann eine Gruppe an (überraschend, oder?), im phpLDAPadmin heißt das "Posix Group".

Der geben wir einen Name, z.B. "privat". Auch hier will LDAP eine Nummer, also "GID Number" mit irgendwas numerischem volltippen. Außerdem könnten wir hier schon Benutzer in die Gruppe aufnehmen - machen wir nicht, wollen wir ja später auch nicht auf dem Weg machen, wenn wir neue Benutzer in eine Gruppe packen.

Klick, und auch fertig.

 
4.3 Benutzer in Gruppe
Noch einfacher:

Eine Gruppe (cn=....) auswählen (z.B. cn=privat). Möglicherweise gibt es schon ein Feld "memberUid", beim ersten Besuch aber eher nicht.

Also in der Box hinter "Neues Attribut hinzufügen" (so nennt es mein deutscher phpLDAPadmin) "memberUid" auswählen, dann dahinter die "uid" eines Benutzers eintippen, der in die Gruppe soll. "Speicher" und gut.

Ist nun ein "memberUid" schon da, ist es fast aufwändiger, man muß mehr klicken. Einfach unter der "memberUid" rechts auf "(Wert hinzufügen)" klicken. Dann dort die weitere Uid aufnehmen. Gut.

Löschen geht so:
Einfach Uid aus den memberUid Zeilen löschen und speichern.

Es ist doch irre, was Computer heute alles können.
 
5 Kleiner Bonus
Nach einigen Minuten suche im Web hab ich dann auch etwas gefunden, wie jeder Benutzer sein Passwort selbst im LDAP ändern kann - über ein Web-Frontend.

Zuerst brauchen wir dazu einen mit .htaccess geschützten Bereich. Und in desser Gruppe sollten alle Leute sein, die ihr Passwort ändern dürfen.

Dann brauchen wir PHP mit LDAP-Unterstützung.

Und dann folgende Seite in dem Verzeichnis:

index.php
<?php
require("ldap.php");
?>
<html>
<head>
<title>Passwort ändern</title>
</head>
<body>
<?php
if (isset($change) && isset($oldpw) && isset($newpw1) && $newpw1==$newpw2)
{
    if (ldap_chancePasswort($PHP_AUTH_USER,$newpw1,$oldpw))
        echo "Passwort wurde geändert!<p>\n";
    else
        echo "Passwort wurde <b>nicht</b> geändert!!<p>\n";
}
else if (isset($change))
{
    echo "Passwort wurde <b>nicht</b> geändert!!<p>\n";
}
?>

<form method=post>
<table>
<tr><td>Login</td><td>
<?php
echo $PHP_AUTH_USER;
?>
</td></tr>
<tr><td>altes Passwort</td><td><input type=password name=oldpw></td></tr>
<tr><td>neues Passwort</td><td><input type=password name=newpw1></td></tr>
<tr><td>neues Passwort</td><td><input type=password name=newpw2></td></tr>
<tr><td></td><td><input type=submit name=change value='ändern'></td></tr></table>
</form>
</body>
</html>


Wer PHP kann, sieht, daß noch eine "ldap.php" genötigt wird, die packen gleich mit ins Verzeichnis:

ldap.php
<?php

define(LDAP_SERVER,"ldapserver1");
define(LDAP_BASE,"o=js-home.org");
define(LDAP_GROUPBASE,"ou=gruppen,o=js-home.org");
define(LDAP_USERBASE,"ou=benutzer,o=js-home.org");

function ldap_chancePasswort($username,$newpass,$oldpass)
{
    $ret=0;
    if (isset($username) and isset($newpass) and isset($oldpass))
    {
        $ldapconn = ldap_connect(LDAP_SERVER);
        $ldapbind = @ldap_bind($ldapconn,"uid=".$username.",".LDAP_USERBASE,$oldpass);

        if($ldapbind)
        {
            if (ldap_mod_replace ($ldapconn, "uid=".$username.",".LDAP_USERBASE, array('userpassword' => $newpass)))
            { 
                $ret=1;
            }
        }
    }
}
?>


Über die DEFINES am Anfang wird die Sachen eingerichtet, kennen wir ja inzwischen schon, oder?
 
6 Nachwort und Impressum
So, ich hoffe, das hat etwas geholfen. Im Forum gibts Raum für Fragen und Diskussionen - bitte nur dort. eMails sind natürlich willkommen, bei Fragen werde ich jedoch jeden bitten, diese im Forum zu stellen, damit auch andere Leute, die auf das Stoßen, schnell zur Lösung finden.

© 2004 js-home.org, alle Rechte liegen beim Autor; Kopien, auch auszugsweise, nur mit Genehmigung; Verlinkung bitte immer nur auf das Inhaltsverzeichnis.

Achja, wer mag, darf mal auf einiger der Banner klicken - am besten mal jedes ;-) und wer weiß, vielleicht kauft man ja dort dann was...




All actions are logged, copyright © JS