Kerberos and Load Balancing

Hi guys, Joji Oshima here again. Today I want to talk about configuring Kerberos authentication to work in a load-balanced environment. This is a more advanced topic that requires a basic understanding of how Kerberos works. If you want an overview of Kerberos, I would suggest Rob’s excellent post, Kerberos for the Busy Admin. In this post, I will be using a load balanced IIS web farm as the example, but the principal applies for other applications.

The Basics:

As you may know, Kerberos relies on Service Principal Names (SPNs). SPNs are associated with objects in Active Directory and registered under the servicePrincipalName attribute.

If you are using 2008 Server or higher, you can view this attribute using Active Directory Users and Computers (ADUC) with Advanced Features enabled and going to the Attribute Editor tab. Click the View menu and then select Advanced Features

image

You can also view attributes using ADSI Edit (adsiedit.msc) or the Setspn command line tool.

When an application makes a request for a Kerberos ticket, it makes that request for a specific SPN (like http/server01.contoso.com). The Key Distribution Center (KDC) will search Active Directory for the object that has that principal name registered to it, and encrypt the ticket with that object’s password. The object that is running the service has the same password, so when the ticket arrives, it can decrypt it.

The Problem:

If you have a single IIS server, the service is typically running under Local System. The standard SPNs are registered to the computer account (like host/server01 & host/server01.contoso.com)* so when a request for http/server01 comes in, the ticket will be encrypted using the computer account’s password. This configuration works well for a single server environment.

*The host SPN works for many services including http. If there is a specific entry for http, it will use that, otherwise it will fallback and use host.

In a load-balanced environment, users will access the service using a unified name instead of the individual servers. Therefore, instead of accessing server01.contoso.com or server02.contoso.com, they will access myapplication.contoso.com. In this scenario, there are two computer accounts, so where do you register the Service Principal Name? One idea would be to register the principal name to both computer accounts. The problem with this idea is that Service Principal Names must be unique. When the request comes in for http/myapplication.contoso.com, the KDC would not know which object’s password to encrypt the ticket with, so it will return an error. You will also see Event ID 11 populating your event logs if you have any duplicate SPNs in your directory.

The Solution:

Instead of running the service under Local System, have each server run the application using a specific service account. In IIS, you can accomplish this by having the application pool run under the service account. Here is how you would set it in IIS7. You could also follow the instructions in this TechNet article.

1. Open Internet Information Services (IIS Manager) and browse to the Application Pools page

image

2. Right click the application pool that is running your site, and choose Advanced Settings

image

3. Under Process Model, look for Identity and click the button to the right

image

4. This will bring up a dialog box where you can choose what credentials to use for the application pool. Choose Custom account and click the set button.

image

5. Enter the credentials for your service account and click ok

6. If you are using IIS7 and have Kernel Mode Authentication set, you will need to do one additional step. Open the ApplicationHost.config file and enable the useAppPoolCredentials setting. IIS7 added the option to authenticate users in Kernel mode to speed up the authentication process. By default, it will use the computer account for authentication requests even if the application pool is set to a service account. By changing this setting, you get the benefits of Kernel Mode Authentication, but still authenticate with the service account.

Sample ApplicationHost.config change:

<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true" useAppPoolCredentials="true" />
</authentication>
</security>
</system.webServer>

After you have the services running under the same service account, register the unified name, http/myapplication.contoso.com, to that service account. No matter which server the client is routed to, the service will be able to decrypt the ticket using its password. You can register SPNs using the command line tool Setspn.

image

Extra Credit:

Suppose you want the ability to use Kerberos authentication accessing the servers individually and using the unified name. Currently, if you request a ticket for http/server01.contoso.com, the KDC will encrypt the ticket using server01’s computer object password. The service is not running under local system, so it will not be able to decrypt that ticket. However, you can register additional SPNs to the service account. In this scenario, you could register the following SPNs to the service account.

You can also view the attributes currently registered to an account using the Setspn command line tool.
Syntax: Setspn –l accountname

image

This will not interfere with the host SPNs registered to the computer account. When an incoming request comes for http/server01, it will check for the exact string first. If it cannot find it, it will look for host/server01.

Problems:

Remember that a Service Principal Name can only be registered on one account at a time. If you are using 2008 Server or higher, you can search for duplicate SPNs in your environment by using the command: Setxpn -f -q http/myapplication*

image

You can also use the command line tool LDIFDE to find duplicate SPNs. The command below will output a text file called SPN.txt that contains all objects with a service principal name that starts with http/myapplication. This file will be located in the same directory you run the command in unless you specify a path in the –f switch.

LDIFDE -f spn.txt -r (serviceprincipalname=http/myapplication*) -l serviceprincipalname

  • The –f switch determines the output file
  • The –r switch determines the search criteria, and the * at the end is a wildcard
  • The –l switch chooses which attributes will be listed in the output file

Final Thoughts:

There are many benefits to using Kerberos authentication but configuring it properly may feel like a daunting task, especially in a more complex environment. I hope this post makes configuring this a bit easier.

- Joji “adult swim in the app pool” Oshima