Kerberos authentication and delegation: ServicePrincipalNames

NOTE: while I’m still keeping the current posts live as they still seem to help, currently my focus has changed and new activity moved to the new site iternia.be

SPN’s

One of the errors that often reoccur when deploying a service is the Kerberos authentication failing for some reason when another system depends on your service. Depending users or services try to log on to your service but are not allowed to access it. This is not a problem with the enduser but with the rights of the service account on which the service itself is running. The service account doesn’t have the right to delegate access or impersonate the enduser. About 9 times out of 10 this is caused by inproper Kerberos rights due to a faulty SPN (or ServicePrincipalName) configuration and sometimes due to the delegation settings on the service account.

First lets take a look at how SPNs work in theory. An SPN consists of 2 parts

  • Service type
  • Service name [:service port]

The service type is an indicator of what kind of service is actually offered. Examples are HTTP or MSSQLSvc.

The service name or host name is the location of the service. This could be a netbiso name (myserver1), FQDN (myserver1.mydomain.local) or in some particular cases an actual url although most of the times you’re going to use the NETBIOS name or the FQDN. Optionally a port number might be added at the end of the service name.

So the actual SPN service indicator looks like <service type>/<service name>[:<portnumber>]. F.e. HTTP/myserver1:81

Alright, but why would we need it?

An SPN tells the Kerberos system that a certain AD service account may access the service itself. In essence to elevate its rights from a dumb service account to an account with actual rights inside the service. Sounds weird but I’ll try to give an example:

A user logs on to a webservice. The webservice itself connects to a SQL service. If I were to use standard behaviour then the user would access the webservice but when the webservice goes to the SQL, it has to do this with its own service account name. This means I have to implement the security inside the webservice whilest I might want to delegate that to SQL (f.e. user 1 has dataset 1 and user 2 has a completely different dataset 2). The SQL sees the webservice service account logging on and can’t see which enduser is in fact the requestor. If however the webservice can log on to SQL using the enduser credentials then the problem is solved. This is called impersonation. The webservice creates a new connection to the SQL but impersonates the enduser. Of course you can see the security risk involved so therefor this kind of behaviour is blocked by default. By using SPNs and setting the delegation settings in AD, you can create an explicit “allow” for this app to behave that way. Impersonation is not the only reason to use SPNs but it is a common one.

An SPN can be used on a user account (service account) but also on a computer account (host).

So how do we actually do this?

It’s quite easy:

  • Connect to a domain controller
  • Open a command prompt or powershell window
  • Use the setspn command to add the correct SPN to a service account

setspn -S <service type>/<service name>[:<portnumber>] <domain>/<accountname>

setspn -S <service type>/<service name>[:<portnumber>] <accountname>@<domain.tld>

  • (The -S-option will check that there is no duplicate SPN before adding it to AD. Replaces the -A option used in the past).
SetSPN command

SetSPN command

Other common options:

  • -D
    • Removes a previously set SPN
  • -L
    • List the SPNs for a certain account
  • -A
    • Add an SPN => similar to -S but -A does not verify if there is already a duplicate SPN
    • Warning: to avoid problems later on it is better to use -S; unless if you’re using an older version of Windows (2003 f.e.) as the -S option is not available there

For a full list run setspn /?

Some typical services:

  • HOST/ (set automatically when adding a server to AD)
  • HTTP/ (see below)
  • MSSQLSvc/ (see below)

Not so typical:

  • LDAP/ (no need to tamper with this, ADDS will automatically set the correct ones)
  • DNS/ (idem if DNS is AD integrated)
  • GC/ (idem)

Alternatively you can use the ADDS-users and computers mmc to add an SPN (or ADSIedit.msc provides exactly the same dialog):

  • Open a service account
  • Go to the attribute editor tab
  • Browse to the servicePrincipalName
  • Edit
  • Add or remove a value
SetSPN via ADDS GUI

SetSPN via ADDS GUI

Practical use (1) SQL

Applications depending on SQL often need an SPN as follows:

setspn -S MSSQLSvc/SQLinstance1.mydomain.local:1433 mydomain\SQLserviceaccount1

Often applications also need SQL to perform impersonation of the enduser. You can use the delegation tab (see below – delegation)

Practical use (2) IIS

I’m not really a developer, but because SPN’s are often important for webapps I’m mentioning it here.

For the entire IIS config, including the security settings for webapps both in IIS and in the .NET code I’d like to refer to a lot of good articles from webdevelopers. Just open your favorite search engine and try something like “iis authentication spn” => happy reading!

Delegation

If you also need the SPN for delegation, then open AD Users and Computers and in the mmc-menu make sure the “advanced features” is selected.

SPNs - ADDS advanced features

SPNs – ADDS advanced features

If (and only if) you have set at least 1 SPN, you will see a delegation tab appearing in the properties of a service account or host.

If you select the second option “any service” then delegation is allowed for all services that are listed in the SPN-field.

But if you have multiple services running on the same service account but the account only needs delegation rights on one of those services (f.e. allow on SQL but not on CRM) then you can select the ones you need via the “specified services”.

SPNs - delegation settings

SPNs – delegation settings

Choose your account

SPNs - delegation settings

SPNs – delegation settings

If you have more than one SPN then you’ll see a list; select the SPNs for the services that you need delegation for.

SPNs - delegation settings

SPNs – delegation settings

And you’re done

SPNs - delegation tab

SPNs – delegation tab

Common mistake (1) Putting the SPN on the wrong account

Make sure you put your SPN on the service account of the application you’re trying to fix. A lot of people put an SPN for SQL on a sharepoint or a CRM service account because they think the sharepoint account needs rights to access the SQL.

This will not work and it often results in the second error: duplicate SPNs.

Common mistake (2) Duplicate SPNs

Because a service can run on one and only one service account, you need to add a specific SPN on only 1 account: the service account that the service is running on. A common mistake as seen above often results in a sharepoint account and a CRM account getting the same SPN to access a certain SQL instance. First of all the SPN is on the wrong account + there is a duplicate SPN, therefore creating error messages in the eventviewer.

Also if you push an SPN on a wrong account and later on you try to fix the problem by adding the correct SPN on the service account it was supposed to be on => you’ll get a duplicate SPN (one on the right account and an older SPN that you probably forgot even existed) => error!

In earlier versions of windows this was hard to solve because you had no idea where the wrong SPN was residing. But now there is also an option “setspn -Q”

f.e.

setspn -q MSSQLSvc/SQLinstance1.mydomain.local:1433

Will give you where this SPN is registered (if any exists)

SPNs - search particular SPN

SPNs – search particular SPN

—————————————————————-

 

btw: after starting a new initiative called Iternia, we can now assist you with any IT architectural challenges: Iternia.be

—————————————————————-

 

 

Advertisements

About Geert Baeten
IT service architect - cloud infrastructure solutions - datacenter infrastructure solutions - service design / governing processes

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: