Interop 6: Apache mit Kerberos an AD

Nachdem ich immer mal wieder von Problemen gehört habe, die mit Apache2 und Windows Servern zu tun hatten, hab ich das heute mal nachgestellt und, siehe da, es klappt. Angemeldet an einem Windows Client, der Mitglied in einer native 2008 R2 Domäne ist, konnte ich mich auf einen geschützten Bereich eines Apache-Webservers verbinden, der unter Debian/Ubuntu lief. Wie das ging? Na, eigentlich ganz einfach.

Die Konstellation ist die gleiche wie in den vorangegangenen Kapiteln, für Quereinsteiger hier kurz wiederholt:

  • Windows Server 2008 R2 (Core, ist aber egal) als DC
  • Linux Client (Debian Lenny, 2.6.26) mit NSS per LDAP an AD
  • Kerberos eingerichtet und authentifiziert an AD

Zuerst muss man sein Linux so konfigurieren, dass es Benutzerinformationen nicht mehr lokal aus seiner passwd holt, sondern vom Active Directory. Wie das geht, hab ich schon in den vorangegangenen Interop-Kapiteln beschrieben. Klappt schließlich ein

getent passwd harryp

dann klappt schon mal das Wichtigste. Jetzt nur noch Kerberos testen mit:

kinit harryp@CONTOSO.COM

Passwort eingeben und dann sollte ein

klist

ein „TGT“-Ticket anzeigen (krbtgt).

Dann kann es mit dem Apache weitergehen. Bei Debian/Ubuntu findet man ein Package libapache2-auth-kerb. Mag sein, dass es noch weitere gibt (siehe ganz unten am Ende des Artikels), aber mit dem hab ich es mal testweise probiert. der Apache meldet sich dann mit sowas wie:

Apache/2.2.9 und mod_auth_kerb/5.3

Hier mal ein Beispiel-Konfigfile, das hab ich so im entsprechenden Verzeichnis als .htaccess abgelegt. Natürlich kann man das auch in eine der zentralen Konfig-Dateien reinschreiben.

AuthType Kerberos
KrbMethodNegotiate on
KrbAuthoritative on
KrbAuthRealms CONTOSO.COM
KrbVerifyKDC on
KrbServiceName HTTP
Krb5Keytab /etc/krb5_http.keytab
require user harryp@CONTOSO.COM

Hier wird zuerst einmal der Typ definiert (Kerberos) und nur mittels Negotiate handeln Client und Server automatisch die Authentifizierung aus. Authoritative kann variieren, legt im Prinzip fest, ob es noch weitere Authentifizierungsmethoden geben kann (hier: nein). Realm definiert den Geltungsbereich, grob gesagt muss man sich pro Realm nur einmal authentifizieren. Es folgt die Angabe, dass gefälligst der KDC überprüft werden soll, ob sich nicht ein schlimmer Junge zwischengemogelt hat. Der Servicename steht im Ticket drin und ist normalerweise HTTP, leider sind meine Versuche gescheitert, dem Modul einen normalen HOST-Servicenamen mitzugeben, das wäre zu schön gewesen. So macht uns das Ganze etwas Probleme. Warum? Nun, es gilt das alte Highlander-Prinzip: „Es kann nur einen geben!“. Was das bedeutet: Nun, zu jedem Objekt im AD kann es nur eine keytab geben. wenn ich also schon eine Keytab erzeugt habe, sagen wir für HOST (zum Beispiel für Samba oder für Login), und wir erzeugen eine weitere für HTTP (und wie gesagt leider besteht das Apache-Modul darauf), dann ist die erste wieder weg. Also was tun? Eigentlich ganz einfach: Wir legen ein weiteres Objekt im AD an, wieder ein Computer-Objekt, nennen wir es einfach mal client1a (a wie apache). Jetzt geben wir folgende Zeile ein:

ktpass -princ HTTP/client1.contoso.com@CONTOSO.COM -mapuser contoso\client1a$ -pass geheim -ptype KRB5_NT_PRINCIPAL -out client1a.keytab

Achtung: Hier ist einmal von client1 die Rede (beim HTTP-Dienstnamen) und einmal ist der client1a gemeint (beim Mapping auf ein Objekt). Warum? Nun, wir haben ein Objekt, an dem eine Keytab hängt, und in dieser Keytab finden wir den Dienst HTTP (für den Namen, auf den der Webserver hört. Ich gebe zu, nicht schön, aber es funktioniert. Vielleicht geht’s auch anders, ich hab’s noch nicht hinbekommen. Diese Keytab kopieren wir noch (per winscp) auf den client1 und teilen dem Apache-Modul noch mit, welche wir meinen (Krb5Keytab in der Config oben).

Das abschließende require user definiert „harryp“ als alleinigen Zugangsberechtigten, ein „require valid-user“ würde auch gehen, dann dürften alle Benutzer, die Apache irgendwo im AD findet.

Damit wir alle verstehen, was da abgeht: Der Apache Server holt sich seine Benutzerinfos vom lokalen System, das wiederum holt sich (für den Apache unsichtbar) aus dem AD die Infos per LDAP. Kontaktiert ein Client den Server und wird eine Kerberos-Authentifizierung ausgehandelt, dann holt sich der Benutzer beim DC ein Service-Ticket für HTTP und authentifiziert sich damit am Apache. Der wiederum vertraut darauf, dass sein lokales System das richtig verifiziert.

Alles, was wir gebraucht haben, ist das Kerberos-Modul für den Apache. Wer prüfen möchte, ob das auch wirklich geklappt hat (ich hab mich mal so gefreut, als ich endlich Zugang hatte, dass ich total übersehen hatte, dass die .htaccess im Verzeichnis gefehlt hat und alle Zugang hatten – meine Konfig war nach wie vor falsch.): „kerbtray“ ist ein kleines Tool, welches mal im Ressource Kit dabei war, das zeigt die Tickets, die man so gesammelt hat, und unter Windows Server 2008 und Windows 7 ist ein „klist“ dabei, das ist zwar nur Kommandozeile, aber wen stört das schon?

Noch ein paar Tipps, über die ich schon mal gestolpert bin:

  • Manchmal komm eine Fehlermeldung im error.log mit „No principal in keytab matches desired name“. Dann bitte mal die Computernamen prüfen – bei mir lag es mal an einem falschen Eintrag in der /etc/hosts.
  • Nach wie vor gilt bei Kerberos: Zeitabweichungen müssen unter 5 Minuten sein zwischen Server und Client
  • Auch DNS muss stimmen, von beiden Seiten!

Zum Testen der Kerberos-Funktionalität packe ich die .htaccess in ein cgi-Verzeichnis, in dem ein Mini-Script liegt. Der muss als Ausgabe dann „AUTH_TYPE“ „Negotiate“ zeigen und unter „REMOTE_USER“ „harryp@CONTOSO.COM“

#!/bin/sh
echo Content-type: text/plain
echo
set

Noch ein paar allgemeine Bemerkungen, denn die Apache-Modul-Entwicklung geht doch recht schnell voran:

Modulnamen:
Es gibt mehrere Varianten der auth-Module, authn, authz oder auch authnz. Wofür stehen diese Kürzel? Nun, genau genommen unterscheidet man zwischen Authentifizierung und Autorisierung. Ersteres prüft die Identität, Letzteres vergibt Rechte. Diese getrennten Verfahren machen durchaus Sinn, denn nicht jeden, der mir an meiner Haustüre den Perso zeigen kann, der darf auch in meine Wohnung rein… Aber zurück zu den Modulen: AUTHN stellt Direktiven zur Authentifizierung bereit, AUTHZ welche für die Autorisierung, und AUTHNZ für beides.

require mit Gruppen:
Man kann als zulässige Benutzer auch Gruppen angeben. Das bringt nur ein Problem: Einige Apache-Module überprüfen das „member“-Feld des Benutzers auf Übereinstimmungen mit der in der Direktive angegebenen Gruppe. Dabei wird aber nicht weiter geprüft, ob es sich um verschachtelte Gruppen handelt. Beispiel: Benutzer ist in der Gruppe Karlsruhe, die Gruppe Karlsruhe ist selbst in der Gruppe BaWue. Erlaubt man per Direktive allen Mitgliedern der Gruppe BaWue den Zugriff, so darf der Benutzer nicht zugreifen – er ist in der Gruppe Karlsruhe und nicht in der Gruppe BaWue. Auch funktioniert die Abfrage nach Mitgliedschaft in der primären Gruppe nicht (jeder Benutzer unter Windows ist in einer primären Gruppe, meist „Domänen-Benutzer“). Der Grund dafür ist, dass diese Gruppe nicht in der member-Liste auftaucht (siehe diesen Beitrag dazu).

Advertisements

Über Ralf Wigand

...arbeitet für Microsoft und war von 2008-2015 MVP für Directory Services.
Dieser Beitrag wurde unter Active Directory, Kerberos, LDAP, Linux, Windows Server veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s