One great thing with ADFS 3.0 is that it supports Group Managed Service Account (GMSA) which makes it easier and more secure to manage service accounts.
But when I installed a new ADFS Farm at a customer I ran in to some troubles. I have been able to reproduce it in one of my lab environments and wanted to share the story.
We had created a KDS Root key a couple of days before and gave it time to replicate. And then we installed the first ADFS server in the farm and all worked well using the GMSA account that was created during the setup.
But when we installed the next ADFS server we got some problems using the GMSA account, actually I got a couple of errors:
There were no SPNs set on the following service account ‘LABB\adfs$’. Specify the service account used to configure the other Federation Servers in the farm, or set host SPN for the farm on the service account.
The user name or password is incorrect
Unable to determine the Service SPN. There were no SPNs set on the following service account ‘LABB\adfs$’. Specify the service account used to configure the other Federation Servers in the farm, or set host SPN for the farm on the service account.
Unable to retrieve configuration from the primary server. The user name or password is incorrect
Well this was odd.
According to Microsoft documentation the requirements are at least one 2012 DC in the domain. And GMSAs can only be administered from Windows 2012 Servers or newer.
Group Managed Service Accounts can only be configured and administered on computers running Windows Server 2012 but can be deployed as a single service identity solution in domains that still have some DCs running operating systems earlier than Windows Server 2012. There are no domain or forest functional level requirements.
So we looked in the adfs$ object and clearly it had its SPN registered, everything was replicated to other DCs and the services worked on the first ADFS server.
In a command prompt we used the command: echo %LOGONSERVER% and got the 2012 DC as result to see if it could make some difference which DC it authenticates to:
Sadly this is not the whole truth, echo %logonserver% or the SET LOG command only shows you cashed information!
If you would really like to know which DC the server/client has a secure channel bind to, you should use NLTEST.EXE.
On the server, run the command: nltest /SC_VERIFY:DomainName and there you have it. It’s authenticated to a 2008R2 DC.
To get this working for now we could go back to the NLTEST tool and run the command: nltest /SC_RESET:labb.winsec.se\srv001 it will change DC and in my case it’s the SRV001 that is the 2012 DC.
Wait a few minutes or reboot and then the ADFS configuration wizard should work.
But this doesn’t explain it all since there is no requirement for all DCs being on Windows 2012 Server.
I wanted to see a little bit more and installed Network Monitor on the ADFS server and did a network capture of the prerequisites check in the ADFS configuration wizard.
At first I see a lot of LDAP queries to the 2008R2 DC and then it becomes more interesting. It actually starts to talk to the 2012 DC and do a AS request for a TGT for the ADFS$ account. But it fails several times with the error KDC_ERR_PREAUTH_FAILED.
And then I took a capture of it working:
When I compared the Kerberos AS REQ with the one that doesn’t work I cant see any differences everything seems to be there.
What to make out of all this, I don’t know, something is pretty broken.
To get to the bottom to this I talked to my dear friend Fredrik “DXter” Jonsson who is the guy to ask when you have a ADFS problem.
Basically there is two sets of code of the ADFS installation. One part for creating the farm and installing the first member. The other one for installing and adding secondary members to the farm. The second part has a few problems and one of them is the management of GMSAs when you still have DCs running on older versions then 2012.
Luckily, this is only a problem at the installation. After you have been able to install the second farm member, there is no problem for the services to run correctly.