Kerberos SPN

Eine Schlüsselkomponente ist der ServicePrincipalName. Ein Client versucht eine Ressource zu erreichen und wird ohne entsprechend gültiges Ticket abgewiesen. Bei der Anfragen an den Ticketserver (KDC) muss der Client natürlich mitgeben, für welches Ziel er gerne ein Ticket hätte. Der KDC muss nun natürlich in seiner Datenbank (bei uns ist das Active Directory diese Datenquelle) ein passendes Konto finden, welches zu diesem Dienst "passt".

Der ServicePrincipalName ist der Schlüssel und der KDC muss für das angerforderte Ziel auch den SPN finden und er darf nur "einmalig" vorhanden sein. Mit ADSIEDIT können Sie sehr einfach das Feld prüfen, welches es bei Computerkonten aber auch bei Benutzern geben kann:

Sie sehen schon hier, dass mein Musterserver eine ganze Menge Rollen und dementsprechend auch SPNs. Dort steht nämlich nicht nur der Hostname, sondern eben auch der Dienst, welcher angesprochen werden kann.

ServicePrincipalName bei Exchange

Wenn Sie sich nun fragen, was das alles mit Exchange zu tun hat, dann gibt es zwei Dinge die hier aufzuführen sind:

  • SPNs werden auch von Exchange genutzt
    Wenn Sie DumpSPN ausgeführt haben dann werden Sie einige SPNs sehen, die mit  Exchange zu tun haben. Hier mal ein Auszug aus den SPNs Meiner TestUmgebung
exchangeAB/SRV01.msxfaq.local
exchangeAB/SRV01
exchangeRFR/SRV01
exchangeRFR/SRV01.msxfaq.local
exchangeMDB/SRV01
exchangeMDB/SRV01.msxfaq.local
SmtpSvc/SRV01.msxfaq.local
SmtpSvc/SRV01
SMTP/SRV01.msxfaq.local
SMTP/SRV01
POP3/SRV01.msxfaq.local
POP3/SRV01
IMAP4/SRV01.msxfaq.local
IMAP4/SRV01
IMAP/SRV01.msxfaq.local
IMAP/SRV01
  • Exchange nutzt Kerberos als Anmeldung
    So authentifizieren sich die Routinggroup Connectoren gegenseitig.
  • Active Directory
    Auch die Domain Controller nutzen natürlich Kerberos, so dass doppelte oder fehlende SPNs hier seht störend sind. Hier mal ein Auszug:
kadmin/changepw
GC/srv01.mexfaq.local/mexfaq.local
ldap/b1a33b59-f6c2-4f8e-817c-aad122b282b6._msdcs.mexfaq.local
ldap/srv01.mexfaq.local/MSXFAQ
ldap/SRV01

Und das sind bei weitem nicht alle Dienste. So werden So werden Sie Einträge vom Webservern, (HTTP), SQL-Server (MSSQL), VNC (VNC), Virtual Server (VMRC), SMTP-Server (SMTPSVC), File Replication Service (NtFrs-guid), VoIP-Software, Kerberos (kadmin), Terminal Dienste (TermSRV) und vielen anderen Diensten. Die Service Principal Names sind also weit mehr als nur ein nettes Beiwerk sondern essentiell wichtig für die Funktion von Kerberos.

Recommendation: Enabling Kerberos Authentication für MAPI Clients
http://blogs.technet.com/b/exchange/archive/2011/04/15/recommendation-enabling-kerberos-authentication-for-mapi-clients.aspx

SetSPN

Um den Service Prinzipal Name zu setzen können Sie natürlich mit ADSIEDIT direkt am entsprechenden Benutzer- oder Computerobjekt im Active Directory herum editieren. Besser und sicherer ist allerdings die Nutzung von "SetSPN". Dieses Programm sollte auf den meisten Server mittlerweile vorhanden sein oder kann von Microsoft (Windows 2000 Support Tools) herunter geladen werden. SetSPN erlaubt alle Veränderungen an den registrierten SPNs eines Systems bzw. Benutzers.

  • setspn -l srv01
    Listet alle für diesen Server oder Benutzer registrierten SPNs auf
  • setspn -r srv01
    Setzt die SPN für dieses Objekt zurück. Nach meiner Einschätzung löscht SetSPN  dabei alle SPNs und legt nur die beiden HOST-Einträge wieder an.
  • setspn -a http/srv01.msxfaq.de srv01
    Fügt dem Serverobjekt SRV01 den SPN "http/srv01.msxfaq.de" hinzu
  • setspn -d http/srv01.msxfaq.de srv01
    Entfernt den SPN von dem entsprechenden Objekt

Dieses Vorgehen ist bei weitem ungefährlicher als der direkte Einsatz von ADSIEDIT. Allerdings prüft auch SetSPN nicht,  ob der fragliche SPN bereits auf einem anderen Objekt vergeben ist. Aus diesem Grund ist auch DumpSPN entstanden. Allerdings können Sie die Folgen eines "doppelten" SPN auch im Eventlog erkennen. Der Kerberos Dienst beschwert sich, dass er natürlich kein Ticket ausstellen kann, wenn zwei Objekte den gleichen SPN haben.

SPN mit Applikations Farmen und Cluster

Interessant wird das natürlich wenn man nun eine Webserverfarm (z.B.: Exchange Frontend Server oder Provisioning Server) betreibt, die mittels "Network Load Balancing" zusammen schaltet und mit einem DNS-Alias betreibt. Wenn Sie nur einen Server haben, dann ist es relativ einfach, diesem Computerkonto mit SETSPN einfach den zusätzlichen Namen zu vergeben.

Aber wenn nun mehrere Server unter dem gleichen Namen erreichbar sein sollen, dann funktioniert das schon nicht mehr. Das gleiche Problem stellt sich, wenn Sie einem Windows Cluster installieren. Der "virtuelle Clustername" bekommt dann ebenfalls ein Computerkonto, an welches die SPNs eingetragen werden. Dazu muss das Cluster Dienstkonto oder die Knoten (bei Windows 2008 und höher) aber berechtigt werden. Der SPN für eine Clusterressource darf eben nicht auf den gerade aktiven Knoten des Clusters addiert werden, da nach einem Failover die Ressourcen auf dem anderen Knoten laufen aber die bislang ausgestellten Tickets zwar noch gültig sind, aber vom anderen Knoten nicht erkannt werden können.

Ein "Virtuelles Computerkonto " gibt es bei NLB nicht. NLB wird aber sowieso meist nur für Webseiten (IIS) genutzt und wenn es nicht nur um statische HTML-Seiten geht, dann muss man sowieso einen Appicationpool konfigurieren.

Jede Webanwendung sollte dann ihren eigenen Application-Pool und ein eigenes Dienstkonto nutzen. Auf dem Dienstkonto des Application Pools müssen die SPNs für den Namen der Webseite, also des NLB-Clusternamens, eingetragen werden.

setspn -A HOST/nlbclustername.example.com DOMAIN\Dienstkonto
setspn -A HOST/nlbclustername DOMAIN\Dienstkonto

Hinweis:
Beim Einsatz von NLB muss es eine 1: Zuordnung vom Clusterhostname zum Application Pool geben. Zwei AppPools mit unterschiedlichem Dienstkonto könne nicht den gleichen NLB-Clusternamen sharen.

Unterstützung durch Net at Work:
Wenn Sie weitergehende Unterstützung  bei der Konfiguration von NLB, Kerberos und Webanwendungen benötigen, dann helfen wir ihnen gerne.

Interessant wird es, wenn die Webapplikation ihrerseits auf Daten auf wieder anderen Servern, z.B. einem nachgelagerten SQL-Server oder Dateiserver, zugreifen muss. Das kann sie mit dem Dienstkonto selbst machen, was aber nicht gerade "sicher" angesehen wird. Das Backend kann dann nicht die Zulässigkeit des Zugriffs durch den Benutzer überprüfen.

Als Alternative ist hier der Weg zu nennen, dass die Webapplikation sich "im Auftrag des Benutzers" ein Ticket für den nachfolgenden Zugriff besorgt. Das ist auf der Seite "Kerberos Constraint Delegation" beschrieben.

Doppelte SPNs

Mit der Verständnis ist nun auch klar dass es in einem Forest die SPN-Namen immer eindeutig sein müssen. Wenn ein SPN bei mehreren Konten erscheint, dann kann der KDC nicht das passende Konto bestimmen und stellt kein Ticket aus. Wer sein Eventlog "korrekt" überwacht, kann auch die entsprechenden Meldungen (Source:KDC EventID:11) dort auf dem Domain Controller sehen:

Event Type:   Error
Event Source: KDC
Event Category:    None
Event ID: 11 User:         N/A
Computer: SRV01
Description:
There are multiple accounts with name HTTP/intranet.msxfaq.local 
of type DS_SERVICE_PRINCIPAL_NAME.

Das Skript DumpSPN ist hierzu mir immer eine Hilfe, da es einfach alle Objekte mit einem SPN einsammelt und Dubletten ausfindig macht. Als Aufgabe ergibt sich sowohl eine XML als auch eine CSV-Datei.

SPN und DNS mit CNAME

Der echte Namen eines Servers unterscheidet sich oft von dem Namen, denn die Anwender kennen und nutzen. Es gibt vermutlich wenig Server, die "intranet.<firma.tld>", "OWA.<firma.tld>" oder "webmail.<firma.tld>" heißen. In der Regel wurden die Server nach einem internen Namensschema benannt während die Dienste mit einem anderen Namen erreichbar sind. Das ist insbesondere dann der Fall, wenn mehrere Server zwecks Lastverteilung und Verfügbarkeit die Dienste anbieten und ein Loadbalancing, z.B. per Hardware Load-Balancer oder DNS Round Robin. Die Clients nutzen natürlich weiterhin DNS, um den Server zu finden und hier gibt es zwei Möglichkeiten den Client zur richtigen Gegenstelle zu leiten:

Kriterium

A-Record

CNAME

Kerberos-Suche

Der Client kennt nur den Namen und nicht den realen Server. Der Client kann also den KDC nur nach dem Namen suchen.

Der Client kennt den "realen Namen" und sucht auch für ein Kerberos-Ticket zu dem echten Namen.

Loadbalancing

Mehrere A-Records erlauben eine Verteilung der Zugriffe auf mehrere Systeme per DNS Round Robin. Hardware Load-Balancer sind möglich.

Der SPN muss einem Dienstkonto zugewiesen werden, den alle Server nutzen.

Es kann immer nur genau einen CNAME-Eintrag geben. Das Beschränkt die Möglichkeiten der Lastverteilung. DNS Round Robin ist nicht möglich und bei einem Hardware Load-Balancer würde ich eher einen A-Eintrag setzen. Ein CNAME ist aber möglich.

Der SPN muss einem Dienstkonto zugewiesen werden, den alle Server nutzen.

SPN-Eintrag

Der Name muss bei einem Computer oder Dienstkonto als SPN hinterlegt sein

Der Name selbst muss nicht bei einem Dienst eingetragen sein, da der Client den echten Namen nutzt, auf den der CNAME verweist

Eignung

Denken Sie daran, dass die den Hostnamen beim Zielcomputer als zusätzlicher SPN hinterlegt werden muss.

Nur in Verbindung mit aktiven DNS-Loadbalancern, die den "richtigen" CNAME ausliefern, wenn das Ziel anderweitig gepflegt wird.

Mein Rat: Verzichten Sie auf CNAME in Verbindung mit Kerberos, wenn mehrere Server z.B. durch einen Loadbalancer unter einem Namen erreichbar sind und nutzen Sie einen A-Record, der auch so im SPN erscheint.
Ein CNAME ist dann besser, wenn ein Server unter einem anderen (virtuellen) Namen erreicht werden soll und Kerberos erwünscht ist.

Weitere Links