Categories
Fixes for Windows

Fix missing Service Principal Name for ADFS’ gMSA

I’ve been wanting to document this because I had such a bad time with it. I think it stems from Microsoft’s horrible documentation and the army of zealots it hires to copy and paste into their own blogs without fact checking…allegedly.

Perhaps the most difficult role or task to set up in Windows Server, besides the mere accomplishment of preventing Windows to fuck itself up, it Active Directory Federation Services.

You might be lucky that it manages to complete its setup without warnings or issues but that, if it happens, it’ll be the first time only. It rarely ever happens again. A lot of Microsoft crap is heavily dependent on the directory service and will happily write stuff to it but do a horrible job at collecting its shit when it’s time to go. You’d think after 20 years it should have the ability to self-heal but no, that was split off into another product, System Center, while they still have the nerve to charge you per user and in some cases over time as if improvements were done to warrant it.

Anyway. Rant aside. Fixing the SPN on the gMSA is actually quite easy but it’s buried in a mountain of jargon everywhere in the docu.

You can scroll all the way down if you’re in a hurry, look for text in bold letters and you should be alright.

[First a few] Concepts

Group Managed Service Account, gMSA

If you haven’t read endlessly by now: a gMSA is just like any other user account but with the ability of have its password always fresh automatically. Active Directory takes care of that, it also changes passwords for computer account automatically, if you didn’t know that. This account is invoked to perform tasks on one or more servers, in this case that’d the ADFS farm, whether it’s a single server farm or not.

gMSAs are by default held in the container Managed Service Accounts at the root of your directory. You can use ADSI Edit, AD Administrative Center or AD Users and Computers to find it.

Kerberos Delegation

Behind the scenes and before we get to certificates, communications in Active Directory are secured using Microsoft’s version of Kerberos, an old protocol by MIT. How the whole thing doesn’t matter right now. What you we should focus is on some Kerberos principals, these are:

  • host/federation.domain.tld
  • http/federation.domain.tld

And thanks to Microsoft’s incompetency their NetBIOS forms as well:

  • host/FEDERATION
  • http/FEDERATION

This is how your server is named in the directory in its pre-Windows 2000 form.

In my case, my server is federation–you know–to the point. But yours is most likely other thing.

By registering a principal of one domain account into another account, we’re delegating the former into the latter. This is Kerberos Delegation in a nutshell. The service account will represent the service part of the machine and as such it has power to do shit in the server now.

Duplicate SPNs

Let just say I’m by no means an expert on any of this, you shouldn’t even be trusting me. But I’ve tested over and over and observed enough to make my own conclusions and to learn what works.

Kerberos Principals are like IDs on the directory. Two of the same cannot exist. Technically they can, but all sorts of errors ensue.

Sometimes you’ll encounter this annoying error that you have duplicate SPNs, you can query the directory for SPNs using the -Q switch with setspn.

We’re about to enter the command line domain, when you do this in places like Linux, it means power and and honest connection with the system. That’s not true in the Microsoft realm. In Microsoft products you have a lot of code protecting stupid stuff like activation, licensing, and making things found in other platforms deliberatively different enough so they cannot be sued for stealing them. This bullshit adds a lot of layers of unnecessary complexity and this won’t always give you the same results. For instance, I was not able to modify an SPN twice in the same PowerShell window because it suddenly couldn’t find the gSMA.

HOST vs HTTP

I have not checked the Windows Server 2019 documentation but up to 2016 this is where they had it wrong. This was copied verbatim to countless of blogs with the same wrong shit.

Microsoft docu states that to manually add the SPN of an ADFS server to a service account you must register its HOST SPN when it fact it’s the HTTP SPN they one that must be registered.

Remember SPNs are like IDs, well, services/capabilitiesOf running in a server sort of have their own identity. HTTP I assume is a web service’s identity.

More importantly, the server itself, needs to have an identity in the directory otherwise there would be no server. The host principal cannot be removed from machine accounts or they become disconnected from Active Directory. If you already did, don’t panic, just add it back to the server (both in FQDN and NetBIOS forms) and restart the server and it should reconnect with the domain as before. You might be able to use Test-ComputerSecureChannel as well for this, I haven’t tested that myself.

The host principal is for servers, the HTTP principal is for service. Therefore you need to add the HTTP principal of the ADFS server(s) to the service account.

First, a little reconnaissance and housekeeping, list all HOST SPNs for every ADFS server you have on your farm. If you’re reading this I assume it’s just the one, otherwise you’d probably would be too knowledgeable anyway, in PowerShell:

setspn -L host/adfsserver

That should match host/adfsserver and host/adfsserver.domain.tld, yup, it seems to work like regular expressions. You’ll get a list by domain account, this should ideally match the machine account with the same name as SPN, but it might be listed under other accounts as well, if that is the case you need to remove it from any other places before adding it back to its machine account. You need to remove it because remember: no duplicates. You won’t be allowed to add it if it exists elsewhere.

You can add the HOST principal using the -R or the -S switches, the -R adds both HOST principals to a computer account at once but if one exists already, you might get an error, so try the -S:

## "adfsserver" at the end of the commands is not a NetBIOS name it's an directory account name so might as well be written "DOMAIN\adfsserver" or "domain.tls\adfsserver" or it will take it just the same.
setspn -R adfsserver
## or with -S (remember that NetBIOS name are usually UPPERCASE)
setspn -S host/adfsserver.domain.tls adfsserver
setspn -S host/ADFSSERVER adfsserver

Now that’s all cleared do the same for the HTTP principal, only this time you’ll remove it from its host and add it to the service account.

There’s actually a dedicated form to do this with setspn but that’s assuming everything’s fine and even so it doesn’t always work:

setspn -U -S http/adfsserver serviceaccount$

If it work, double check with -L. If if not, we still have options. Manually remove HTTP principals from their hosts and add them to the service account:

setspn -D http/adfsserver.domain.tld adfsserver
setspn -D http/ADFSSERVER adfsserver
setspn -S http/adfsserver.domain.tld serviceaccount
setspn -S http/ADFSSERVER serviceaccount
## If it can't find the service account try spelling it with a $ at the end:
setspn -S http/adfsserver.domain.tld serviceaccount$
setspn -S http/ADFSSERVER serviceaccount$
## Still nothing? Try adding in the domain name:
setspn -S http/adfsserver.domain.tld DOMAIN\serviceaccount
setspn -S http/ADFSSERVER DOMAIN\serviceaccount

If you’re still having trouble, there’s always nuclear option: ADSI Edit. Launch the console from the Tools menu in Server Manager or Run adsiedit.msc.

Right-click ADSI Edit in the tree and click Connect to… then leave everything as is and just click OK, if you have no other issues with your domain it should connect you correctly to the Default naming context which is your directory except spelled in LDAP. Locate the service account, which should have a name like CN=serviceaccount and a little folder icon. Right-click it and select Properties. Select any attribute from the list and (quickly) type “serv” to fast-forward down the list straight to servicePrincipalName. Double-click it to edit and add http/adfsserver.domain.tld and http/ADFSSERVER, delete anything else if you have more than one server, they add them as well, only HTTP principals, no HOST principals. If PowerShell is still open, run Restart-Computer -Force to reboot the computer without annoying questions.

When the server comes back online in Event Viewer’s or in the ADFS view of Server Manager you should see messages of ADFS starting up.

I hope I have been able to help you and let you continue on what’s very likely the next step of your journey: dealing with ADFS WAP’s own set of issues.

Categories
Spiritual

Adagio

Si las olas del mar llegan hasta la orilla,

Más rápido puedes lavar la vajilla.