Ich entwickle für meinen Arbeitsplatz am URZ ein kleines HTML-Interface für die Domain-Administration. Wir verwenden für die Authentifizierung LDAP/Kerberos, was prinzipiell mal toll ist. Da ich zuvor immer nur Name/Passwort Login gemacht habe, ist das ganze erstmals etwas neues, und ich stolpere immer wieder über neue Problemchen. Um anderen die Arbeit zu ersparen, schreibe ich hier ein paar Details aus, die ich dabei gefunden habe.

Dank mod_authnz_ldap ist ein einfaches Login problemlos möglich. Damit kann man einfach alle Domain-User einloggen lassen (require valid-user) oder ldap-typisch spezifische Gruppen.

Damit starten die Probleme aber erst. Die WebApp soll ja mit den User-Credentials auf andere Ressourcen zugreifen können (in meinem Falle den LDAP-Server). Dazu ist etwas Arbeit nötig. Erstmals müssen wir dem Apache erlauben, die User-Credentials für die dauer des Requests zwischenzuspeichern, was mit “KrbSaveCredentials on” in der Apache-Konfig gelingt. Der Apache speichert dann eine Kopie des Tickets in einer temporären Datei , und löscht diese am Ende des Requests wieder. Der Name dieser Datei wird einem Skript als CGI-Parameter KRB5CCNAME mitgegeben. Hier muss man sich darüber klar sein, dass diese Cache-Datei in /tmp steht, und für Server-Admins ziemlich einfach auslesbar sind. Also nur auf vertrauenswürdigen Hosts machen (die genauen Sicherheitsimplikationen werde ich später noch beschreiben)!

Damit kann man jetzt auf dem Hosts Kerberos-Programme wie klist aufrufen muss aber immer die Cache-Datei mit angeben. Vor allem GSSAPI-Zugriffe sind damit noch nicht möglich, da GSSAPI auf die Umgebungsvariablen guckt um den Ticket-Cache zu finden. Daher ist es Notwendig, vor einem GSSAPI-Zugriff die Environment-Variable KRB5CCNAME auf die CGI-Variable KRB5CCNAME zu setzen. Dann klappt es auch mit GSSAPI.

Hier ein kleines Beispielskript um sich mit einem LDAP-Server mit den UserCredentials zu verbinden:


import os
import ldap
import ldap.sasl
from mod_python import apache

#index file
def index(req):
    #we need load the cgi-vars first
    req.add_common_vars()

    req.write("<h1>LDAP-GSSAPI</h1>")
    req.write("<p>kerberos username is %s<br/>kerberos-ticket cache file is %s</p>" % (req.subprocess_env['REMOTE_USER'],req.subprocess_env['KRB5CCNAME']))

    #set environment so gssapi finds our ticket cache.
    os.environ['KRB5CCNAME'] = req.subprocess_env['KRB5CCNAME']

    try:
        conn = ldap.initialize('ldaps://ldap.example.org')
        # only works if environment is set correctly.
        auth_tokens=ldap.sasl.gssapi()
        if conn.sasl_interactive_bind_s('',auth_tokens) == 0:
            req.write( "<p>Successfully connected</p>")
        else:
            req.write("<p>Oopsy, somethign went wrong.</p>")
    except ldap.SERVER_DOWN:
        req.write(print "<p>ldap-server is sleeping. Dont disturb.</p>")
    return apache.OK

Flattr this!

Comments are closed.