Kerberos is a network authentication protocol based on tickets. It is developed by Massachusetts Institute of Technology and used across different platforms. I have recently faced the need to use Kerberos on Windows and experienced some frustrations that I want to share in this post.
Kerberos has been integrated in Windows as a default authentication protocol since Windows 2000. It is particularly useful when you want to perform single sign-on (SSO) between applications that live in the same domain. In contrast, NTLM is a challenge-based authentication protocol that works with both local and domain accounts. However, you cannot perform a SSO using NTLM.
How does it work?
The name of the protocol comes from the Greek mythology after a three-headed guard dog. The three heads of Kerberos are:
- Key Distribution Center (KDC) installed as a part of the domain controller and providing two services:
- Authentication Service (AS)
- Ticket Granting Service (TGS)
- the client user
- the application or service requested by the user
The following diagram illustrates the basics of Kerberos.
- A user makes a request to an application or service on another server. In the example above it is a HTTP resource, but it could be any kind of resource in practice.
- The application returns 401 and lists the possible ways of authentication. For an IIS server the default Windows configuration includes two types of authentication – Negotiate and NTLM. Negotiate is a special handler that first tries to authenticate the user with Kerberos and if this fails, it switches to NTLM.
- The browser reads the response and tries to authenticate with Kerberos by requesting a Ticket to Get Tickets (TGT) from the authentication service (AS).
- The AS creates a TGT that has two parts – a client part, encrypted with the user’s password hash, and a TGS part, encrypted with TGS’ key. A TGT is cached on the client machine and is used to request sessions to other applications and services.
- The client sends a request to the Ticket Granting Service (TGS) to acquire a service ticket for a desired application or service. The request passes the TGS part of the already obtained TGT,
- The TGS verifies the request and creates a service ticket with two parts: one for the client and one for the target application or service.
- The client tries to get the desired resource again by providing the obtained service ticket.
- The server verifies that encrypted part and permits access to the resource.
Microsoft has a great article providing more details about the process. It is interesting though, how the SSO is achieved with this authentication process. If we wish to authenticate a user to another server, Server Y, then we have to mark the service ticket with a special flag which denotes that ticket can be transferred to other servers. This happens in the domain controller where you can enable delegation for a certain domain user or machine.
Service principle names
In order to determine who should be able to decrypt the service ticket obtained from the TGS, Kerberos uses service principle names (SPNs). This is a string with a special format that can be added to either a domain machine or a domain user. The format of the SPN identifies the desired service you want to reach at the remote server. The format you are going to use mostly is the following:
The service class describes the type of the service that is exposed – SqlServer, HTTP, LDAP or others. There is one special service class, HOST, which is automatically created for every domain machine and it will be used for any service on that machine unless a more specific service class is defined for that service. If your service provides a resource through a standard port (for example 80 for HTTP), you don’t need to specify the port in the SPN. A typical mistake is when working with web services to add a SPN for the HTTPS service class, but such a class doesn’t exist. The HTTP service class covers both HTTP and HTTPS. You could also create your custom service class, but then you have to make sure your client constructs the SPN correctly. Some examples of SPNs are:
If your service runs under a local account – Local Service, Local System, Network Service, Application Pool Identity (in IIS), or other, you have to add SPNs to the domain machine, i.e. it will be the computer account who is going to decrypt the service ticket. If your service runs under a domain account – then you should the SPNs to that account.
If you expose an IIS-hosted web service and your application pool runs under a domain user, you have to set useAppPoolCredentials to true for your IIS site. This can be done via the Configuration Editor on that site (no GUI exists for this configuration) under system.webServer/security/authentication/windowsAuthentication.
SetSPN is a tool built in Windows that helps you perform different activities regarding SPNs. If you want to see all SPNs registered for a computer, you could execute the following command:
setspn -L local-domain.com\user
setspn -L computername
If you want to add a SPN, you use the following:
setspn -S HTTP/myserver computername
setspn -S HTTP/myserver.local-domain.com computername
setspn -S MyService/myserver:5542 local-domain.com\user
setspn -S MyService/myserver.local-domain.com:5542 local-domain\user
You may have noted that I add two SPNs for a service – one with the server name and one with the fully qualified domain name. This is best practice in order to eliminate issues with your clients constructing a wrong SPN. One important requirement for Kerberos to work is there must not be duplicate SPNs, i.e. SPNs that point to two different users or servers. This leads to errors in the Kerberos authentication process and is one of the most common fail scenarios. You can check if duplicate SPNs exist with the following command:
Frequently fail situations
Kerberos is a very sensitive protocol, i.e. you may easily get into a fail situation. That’s why you should be familiar with some of the most common issues that can occur.
- Using an IP address instead of a name – Kerberos uses only names
- Having duplicate SPNs or no SPNs
- SPNs are registered for a wrong account, i.e. not the one your service is running under
- Issues with your DNS will affect the authentication
- You cannot use Kerberos between two services running on the same computer – it defaults to NTLM. I have had a lot of head-bangs with this scenario and although some mention you could solve is by solving the loopback issue in Windows, I haven’t managed to get around it.
- Chrome (at least version 47) does not support delegation by design, i.e. the Kerberos tickets it requests cannot be delegated, so a double-hop won’t work. You have to manually enable this by modifying your Windows registry (regedit.exe). Add a new string value with key AuthNegotiateDelegateWhitelist and data * (the star symbol) or a comma-separated list with allowed domain names to the following two:
In case you realize there is a problem with Kerberos, you should go deeper and see the exact communication. I use Network Monitor to inspect the traffic going in and out my computer (you can use any other network traffic sniffing tool for this). You can apply filters in order to focus on the Kerberos traffic and ignore the rest. There are many errors that could possibly happen, so you have to inspect each error well in order to solve the problem.
I have collected some useful references that contain more details about Kerberos and these little things that can make your life a nightmare if you don’t know them.