ADFS extranet lockout and PDC requirement

IMPORTANT: This article applies to Windows Server 2012 R2 ADFS (aka ADFS 3). In Windows Server 2016 ADFS (aka ADFS 4), there is an option to remove this dependency: Set-ADFSProperties -ExtranetLockoutRequirePDC $false (https://docs.microsoft.com/en-us/powershell/module/adfs/set-adfsproperties).

The Extranet Lockout is a new feature available on Windows Server 2012 R2 ADFS when the Web Application Proxy is used. In a nutshell, it protects against password discovery attacks coming from the Internet... If you have no idea what I am talking about, here is an excellent article explaining how it works and how to enable it:

This is a feature I very often see enabled, yet not many are aware of its ultimate requirement. When this feature is enabled (by the way, it is not enabled by default), every password based authentication coming from a WAP server has to be verified by the ADFS server to ensure the lockout status of the account. The ADFS server does it by checking the value of the badPwdCount attribute for the user on... the PDC. Why the PDC? Because it is the domain controller with the most up to date value of this attribute. The badPwdCount attribute is not replicated, so other DCs than the PDC might have a lower value for this attribute.

What does it look like on the network?

The user is hitting the signon page on the WAP server, enters its username and password and hits Signin. The WAP server sends that request to the ADFS server. The ADFS server tries to locate the PDC on the network for the domain of the user:

Once the name is resolved, it does its LDAP ping (LDAP query over UDP to determine whether the server is reachable):

Then it starts talking LDAP...

Etc... You got the drift.

What if the PDC is not available?

I'll keep it simple, as of today, if the PDC is not available, whether or not the password typed by the user is the correct one, the authentication will fail.

In the following example, the user AD\piaudonnmsdn will try to authenticate against the WAP signin page. The account is currently not locked out and the password entered is correct.

Here is what you will see in the logs, a series of events: eventid 342, eventid 1000 and eventid 364.

It's true that it isn't that obvious, looking at this error message, that the reason of the authentication failure is the unavailability of the PDC. If you retry with the debug logs enabled, here is what you see:

This time, no doubt about the root cause. The function GetPDCName returned an error 1355:

SPOF OMG!

Yes, time to discuss the scary acronym. The extranet lockout is a protection against password discovery and denial of service attacks. As such, it is a security feature. The single point of failure related to the PDC requirement has to be seen as a risk too. So it is your call to decide if the SPOF outweighs the security risks of the attacks aforementioned. Things you need to take in consideration:

  • This is affecting the password based authentications on the WAP, this is not affecting certificate based authentications. This is not affecting ANY type of SSO scenarios for users connected internally.
  • The users who are already authenticated are not affected either. As long as they have a valid SSO cookie, they will not have to re-authenticate.
  • The PDC role could be transferred if you need to restart it and don't want to break new authentication requests hitting the WAP servers.
  • For update management (deployment, installation...), the PDC might be unavailable just for a few seconds/minutes. At the end of the day, the user can just retry a few minutes later (besides, because the error message isn't specific, the user might just think a wrong password was entered...).

But my walls are on fire! (update: 10/28/2015)

Maybe the PDC is up and running, however your ADFS servers are in a network segment that can talk to only few DCs and not the PDC. If you have several domains within your forest or if you have some trusted domains, your ADFS servers also have to be able to contact them. So what if you have a firewall in between? Well, in that case you can create some rules to allow the following traffic:

  • Source: ADFS Servers Destination: PDCs (of all trusted domain as long as users from those domains are authenticated on the WAP) Protocol: TCP Port: 389
  • Source: ADFS Servers Destination: PDCs Protocol: UDP Port: 389

This is enough to enable to badPwdCount lookup.