Wednesday, February 3, 2010

Another Kerberos Battle

Having just done a couple of day's battle with a Keberos setup, I came away with one of those rare moments when the fog lifts and things become clear. I'm sure the fog will descent again soon, so I figured I'd better write this down before that happens.

Here are the bits of truth that made things work for me:
  1. In Windows, Kerberos Service Principle Names (SPNs) are stored in the Active Directory. They are not stored on the server. You don't need to be on the DC to run the setspn utility. In fact, you can enter the values directly using any AD editor.
  2. SPNs might be associated with a machine, but more often they're associated with a domain user account.
  3. An SPN must be unique across the domain (including both machine and user accounts).
  4. Active Directory happily stores duplicates. Duplicate SPNs always break Kerberos.
  5. Keberos errors are not added to the Event Log by default. You need to modify the registry if you want to see them in the event viewer.
  6. Make all your computers agree about the current time. Kerberos tickets don't work if client and server disagree about the current time by more than a few minutes.

Here's my attempt at de-mystifying a Kerboros exchange. I'm omitting details in favor of what I hope is a clearer explanation. This is strictly Windows, IIS and IE. Imagine that a user has just entered the URL of a web server on the local network and pressed the enter key.

  1. IE searches the AD for an SPN with the same name as the URL. There must be one and only one match. If there are no matches, you'll get kdc_err_s_principal_unknown and IE will fall back to NTLM. If there are multiple matches, the results are unpredictable.
  2. Active Directory uses the account where the SPN was found to encrypt a ticket and returns that ticket to IE.
  3. IE presents the encrypted ticket to the web server. If the application pool is running as a local machine account, the machine's domain account is used to decrypt the ticket. If the app pool is running as a domain user, that user's account is used instead.
  4. If the decryption is successful, you're in. If not, IIS falls back to NTLM.

Decryption can only succeed if the same account that was used to encrypt the ticket is used for decryption. If they don't match, you get krb_ap_err_modified.

Knowing this tells you where to register SPNs. If the app pool is a domain account, register the SPN in that user's AD object.

SPNs are automatically registered for machines, so you usually don't need to do them.