Ich war bei meinem Institut an der Uni unter anderem für die Kerberos-Administration verantwortlich und habe mich in dem Zuge ein wenig in das Thema eingearbeitet. Durch meinen Weggang ist da wohl etwas Wissen verloren gegangen teilweise hat sich Halbwissen breit gemacht. Daher wollte ich hier mal ein paar Grundbegriffe dokumentieren.
Vorneweg: Das ist kein „Kerberos-Tutorial“, sondern ich möchte hier die Grundkonzepte vermitteln, sodass man andere Tutorial (die es reichlich gibt) besser verstehen kann. Das Thema Kerberos hat die Ruf sehr kompliziert zu sein. Das ist sicher nicht ganz falsch und hat verschiedene Gründe: Zum einen ist die Materie (Authentifizierung) nicht ganz einfach, und Kerberos löst mehrere Probleme gleichzeitig. Weiterhin ist es schon recht alt und kommt aus einer Zeit in der man zu überkomplexen Lösungen neigte. Außerdem nutzt es nur symmetrische Kryptographie, mit moderner, asymmetrische Kryptographie wäre das eine oder andere Problem vielleicht leichter zu lösen. Zusätzlich ist das Debugging nicht einfach und Debugausgaben sind eher rar gesät. Schlussendlich neigen aber viele Tutorials zu einfachen Lösungen: „Mach dies, und dann läuft alles“. Wenn es dann nicht funktioniert steht man schnell vor einer undurchsichtigen und schwer nachvollziehbaren Blackbox. Wenn man die Konzepte von Kerberos aber erst mal verstanden hat ergibt alles viel mehr Sinn. Das versuche ich mit diesem Post zu erreichen 🙂
Aufgaben von Kerberos
Was genug leistet Kerberos denn nun eigentlich? Es löst (vor allem) ein Problem: Die Authentifizierung von Benutzern gegenüber Diensten. Es bestätigt also z.B. meinem Dateiserver, dass eine Anfrage wirklich vom Benutzer „rother“ kam und der mir Zugriff auf meine Dateien geben darf. Gleichzeitig stellt Kerberos dem Benutzer und dem Dienst ein geteiltes Geheimnis zur Verfügung, was zur Verschlüsselung benutzt werden kann. (Ja, das würde heute dank asymmetrischer Kryptografie einfacher gehen.)
In diesem Zuge löst Kerberos noch zwei Nebenprobleme: Nicht nur der Benutzer wird gegenüber dem Dienst authentifiziert, sondern auch der Dienst gegenüber dem Benutzer. Das verhindert Man-in-the-Middle-Angriffe. Schlussendlich wird „Single-Sign-On“ ermöglicht: Ich muss nur ein Mal am Anfang mein Passwort eingeben und nicht bei jedem Zugriff, und dass ohne dass mein Passwort irgendwo im Klartext zwischengespeichert werden müsste.
Principals, Realms und das KDC
Kerberos macht intern keinen wirklich Unterschied zwischen Benutzern und Diensten, es kennt nur „Principals“. Das ist eine Kombination aus Name und Passwort, die in der zentralen Datenbank gespeichert wird. Für Benutzer verwendet man normalerweise den Benutzernamen, also z.B. „rother“. Für Dienste benutzt man „dienstname/servername“, also z.B. „http/davinci“ für einen Webserver auf dem Host „davinci“. Schlussendlich sind das aber alles nur Namen. Es kann sich grundsätzlich also auch ein Benutzer gegenüber einem anderen Benutzter authentifizieren oder zwei Dienste gegeneinander, es sind alles nur Principals.
Alle Principals gehören zur einem sogenannten „Realm“. Das ist eine Art Gruppe oder Container. Principal-Namen müssen innerhalb eines Realms eindeutig sein, darüber hinaus nicht. In vielen Fällen wird eine Organisation nur einen Realm benutzen, grundsätzlich kann Kerberos aber mit mehreren Realms umgehen und auch Vertrauenstellungen zu anderen Realms abbilden. Das ist sehr cool, geht aber über das Thema hier hinaus 🙂 Als Namen des Realms verwenden man oft eine Domain in Großbuchstaben. Bei der Angabe eines Principals werden Principal-Name und Realm mit einem „@“ getrennt, so dass der vollständige Name eines Principals z.B. „rother@EXAMPLE.COM“ oder „http/davinci@EXAMPLE.COM“ sein könnte.
Und was ist jetzt das KDC? Die Abkürzung steht für „Key Distribution Center“ und meint einfach nur den zentralen Kerberos-Server der alle Principals verwaltet.
Kerberos-Tickets und Keytabs
Wenn ich mich nun als Benutzer gegenüber einem Dienst authentifizieren möchte muss ich mir bei dem Kerberos-Server (KDC) ein sogenanntes „Ticket“ ausstellen lassen. Dafür benötige ich das Passwort meines Principals und den Namen des Principals für das das Ticket gelten soll (z.B. nfs/davinci). Das erhaltene Ticket kann ich nun (auf irgendeinem Weg) an den Dienst schicken. Dieser (und nur dieser) kann dann mit dem Passwort seines Principals überprüfen ob mein Ticket echt ist und dem Ticket das geteilte Geheimnis entnehmen. Die Tickets sind mit einer Laufzeit versehen, nach Ablauf dieser wird das Ticket ungültig und ich muss mir ein neues ausstellen lassen (oder das alte verlängern).
So richtig praktisch ist das aber noch nicht: Jedes Mal, wenn ich auf einem neuen Dienst zugreife brauche ich ein Ticket, und dafür ist mein Passwort nötig. Das ist ja noch kein echtes Single-Sign-On. Dafür gibt es das „Ticket-granting Ticket“, kurz „tgt“. Das ist erst mal nur ein Ticket für für das (immer vorhandene) Principal „krbtgt/Realmname“, also z.B. „krbtgt/EXAMPLE.COM“ (im vollständigen Namen kommt der Realm zweimal vor: „krbtgt/EXAMPLE.COM@EXAMPLE.COM“). Es in sofern besonders, dass man mit diesem Ticket beim KDC Tickets für andere Principals bekommen kann, ohne erneut sein Passwort angeben zu müssen. Üblicherweise wird beim Login des Benutzers nur dieses eine Ticket ausgestellt und alle anderen Tickets darüber besorgt.
Das TGT ist aber ansonsten nicht wirklich besonders: Es ist einfach nur ein Ticket für einen bestimmten Dienst. Dieser Dienst wird vom Kerberos-Server selbst angeboten und liefert auf Anfrage weitere Tickets. Es handelt sich aber technisch um einen normalen, mit Kerberos abgesicherten Dienst.
Ein Problem bleibt: Um die Tickets der Benutzer zu überprüfen benötigt auch der Server auf dem ein Dienst läuft das Passwort zu seinem Principal. Das kann dort aber niemand eingeben. Daher ist es möglich das Passwort (oder genauer, den daraus abgeleiteten Schlüssel) zu einem Principal in einem „Keytab“ zu speichern. Mit diesem Keytab kann man sich dann gegenüber dem KDC authentifizieren ohne das Passwort eingeben zu müssen. Auf Servern wird der Keytab für Principals wie „nfs/servername“ oft unter /etc/krb5.keytab
abgelegt. Andere Dienste (z.B. Apache für das „http/servername“-Principal) erwarten die Datei aber an anderer Stelle. Man kann auch einen Keytab für sein eigenes (Benutzer-)Principal erstellen und sich dann ohne Passwort ein TGT (oder ein anderes Ticket) erstellen lassen. Damit hängt die Sicherheit des Accounts dann aber an der Sicherheit der Keytab-Datei.
Ein häufiges Missverständnis: Die Datei /etc/krb5.keytab
ist nicht grundsätzlich nötig um am Kerberos-System teilzunehmen. Auch ohne diese Datei können sich Benutzer auf einem Rechner TGTs ausstellen lassen und Kerberos ganz normal verwenden. Die Datei ist nur nötig, wenn der Rechner Server-Dienste anbieten soll, dann müssen dort die entsprechenden Principals hinterlegt werden. Was leider zur Verwirrung beiträgt: OpenSSH verwendet als Principal-Name „host“ und nicht etwas „ssh“. Wenn auf einem Rechner ein SSH-Login per Kerberos möglich sein soll muss also im Keytab das Principal „host/servername“ hinterlegt sein. Dieses Principal ist aber nur für SSH nötig und nicht etwas generell um „den Host zu verifizieren“ oder ähnliches. Ausnahme: NFS, siehe unten.
Kerberos und NFS
Grundsätzlich kann man mit Kerberos viele Dienste absichern und SSO-fähig machen (auch Websites!), genutzt wird es aber vor allem im Kontext von Dateifreigaben mit NFS, denn dort ist es die einzige verfügbare sichere Methode. Daher hier ein paar Wort zu Kerberos und NFS.
Grundsätzlich funktioniert alles wie oben beschrieben: NFS benutzt auf Serverseite das Principal „nfs/servername“. Ein Benutzer lässt sich also vom KDC z.B. ein Ticket für „nfs/davinci“ ausstellen. Dieses Ticket verschickt er an den NFS-Server. Dieser findet in der Datei /etc/krb5.keytab
den Schlüssel für „nfs/davinci“ und kann damit das Ticket des Benutzer validieren. Der Server kennt jetzt die bestätigte Identität des Benutzers und kann anhand er Dateirechte prüfen ob der Benutzter z.B. eine Datei lesen darf.
Es gibt aber eine Komplexität: Bestimmte Client-Operationen von NFS, z.B. das Einhängen (mounten) eines Dateisystems werden nicht im Kontext eines Benutzers ausgeführt. Welches Ticket soll nun dafür verwendet werden? Hierfür kennt NFS das Konzept der „Machine Credentials“. Das ist das Principal der Form „nfs/clientname“ (also die gleiche Form, die auch für einen NFS-Server benutzt wird!). Der Schlüssel zu diesem Principal muss in der /etc/krb5.keytab
abgelegt sein. Für alle Operationen die nicht im Kontext eines Benutzers stattfinden wird nun dieses Principal verwenden.
In diesem Sinne muss (für NFS!) also tatsächlich der Clientrechner authentifiziert werden. Etwas verwirrend ist, dass das dafür verwendete Principal die gleiche Form hat wie das, welches ein NFS-Server verwendet. Um die Verwirrung zu maximieren kann der Client, falls er das „nfs/clientname“ Principal nicht findet, alternativ auch „host/clientname“ verwenden, also das gleiche Principal was auf einem SSH-Server benötigt wird. Keberos ist das alles egal, das sieht nur Principals, die gegeneinander authentifiziert werden.
Forwardable Tickets
Eine weitere Besonderheit ergibt sich beim Einsatz von SSH zusammen mit Kerberos. Grundsätzlich unterstützt OpenSSH Kerberos als eine Methode, Benutzer zu authentifizieren, neben SSH-Keys oder Passwörtern. Gegenüber SSH-Keys gibt es aber einen Vorteil: Das Ticket des Benuters mit dem er sich authentifiziert hat, kann an den Remote-Host weitergeleitet werden, und so kann der Benutzer dann auf auf dem Remote-Host Kerberos-gesicherte Dienste nutzen, ohne sein Passwort erneut eingeben zu müssen. Echtes Single-Sign-On!
Tickets sind immer an die IP-Adresse gebunden, daher kann nicht wirklich das bestehende Ticket weitergeleitet werden. Stattdessen wird vom Client ein neues TGT angefragt, das auf die IP-Adresse des Remote-Hosts ausgestellt ist. Damit das funktioniert, muss das bestehende TGT als forwardable markiert sein. Das ist aber üblicherweise der Fall.
Verwandte Dienste
Es gibt noch drei Begriffe, die oft im Kerberos-Umfeld herumschwirren. Die möchte ich hier noch mal kurz abgrenzen und einordnen.
LDAP
LDAP ist (grob gesagt) eine Datenbank in der man Objekte (z.B. Benutzer) und ihre Beziehungen speichern kann. LDAP wird oft zusätzlich zu Kerberos benutzt, denn Kerberos kann nur authentifizieren, aber z.B. nicht abbilden welcher Benutzer in einer Gruppe ist. Diese Informationen stammen dann aus LDAP.
LDAP selber kann auch Passwörter speichern und dadurch zur Authentifizierung diesen. Allerdings ist kein Single-Sign-On möglich, da sowas wie das TGT nicht möglich ist. Man muss dann also bei jedem Dienst wieder das Passwort eingeben. Schlussendlich ist es auch möglich, LDAP als Speicher-Backend für den KDC zu benutzen. Statt in einer Datei speichert der KDC dann also alle Principals und ihre Schlüssel in einem LDAP.
GSS
Der „Generic Security Service“ ist eine Programmbibliothek mit der Programme Funktionen zur Authentifizierung implementieren können. Grundsätzlich unterstützt GSS verschiedene Protokolle. De-facto wird aber nur Kerberos genutzt. Statt Kerberos direkt zu implementieren benutzen viele Programme also GSS als Zwischenschicht. In der Praxis steht GSS aber immer für Kerberos-Unterstützung.
ActiveDirectory
ActiveDirectory ist Microsofts Lösung für eine zentrale Verwaltung von Benutzern und Single-Sign-On und dem Höhrensagen nach der Grund warum Microsoft im Unternehmensumfeld so bliebt ist. Und was steckt unter der Haube? Kerberos und LDAP 😉 Ein ActiveDirectory wenig anderes als ein Keberos- und LDAP-Server mit einer netten Oberfläche und vielen Vorgaben hinsichtlich der Struktur (und ein paar nützlichen technischen Erweiterungen).
Aus diesem Grund ist es durchaus möglich einen Linux-Client oder -Server an ein ActiveDirectory anzubinden. Schlussendlich muss man vor allem ein paar Namen anders konfigurieren, weil das Feld für den Benutzernamen beispielsweise „sAMAccountName“ und nicht „username“ heißt.
Fazit
Es ist jetzt doch ein recht langer Text geworden. Ich hoffe, ich konnte damit ein wenig Licht in das Kerberos-Dunkel bringen. Es hilft meiner Erfahrung nach sehr, sich ein bisschen in die Konzepte einzulesen, dann ist das alles gar nicht mehr so verwirrend 🙂 Als weiterführende Lektüre kann ich das Kerberos-Buch von Marc Pröhl und Daniel Kobras empfehlen, welches das Thema umfassend behandeln.