Brute force attacks can be quite the nuisance for users, especially if they manage to start hitting your AD FS portal with authentication attempts. The Extranet Lockout feature can help alleviate these pains by preventing the users local AD account from being locked out, but it is by no means a complete solution. Please see this post from TechNet for reference on initial setup, and this post also from TechNet for reference on logging/troubleshooting. Without further ado, let’s dig in.
So what does the Extranet Lockout feature actually do? Well, it is quite simple really. Every time AD FS receives an authentication request it will check that AD users badPwdCount attribute before trying to actually authenticate the users against AD. If that value is greater than or equal to the threshold you set it will no longer allow any authentication requests through AD FS for that user for X amount of time,which naturally you configure, preventing it from locking out the AD account. Now just to be clear, this provides zero value if you set the thresholds to higher values than your domain policies. Seems like common sense I know, but you should see some of the comments on these blog sites.
So let’s get into enabling the feature. This is not very involved, just note that this must be done on the AD FS server, not the WAP. Before we get into the PowerShell, let’s define the three settings that we are going to concern ourselves with:
- ExtranetLockoutEnabled: Enables or Disables the Extranet Lockout feature. Pretty straightforward.
- ExtranetLockoutThreshold: Defines the maximum number of bad password attempts allowed before lockout takes effect. Remember, it will be looking at the badPwdCount attribute on the AD user account for this so you will want this to be lower than your domain lockout threshold.
- ExtranetObservationWindow: Defines the amount of time AD FS will not attempt to authenticate against AD. Again, everything works off of AD badPwdCount attribute so you want this to be longer than your domain password attempt count reset threshold.
So now that we know what the settings we are configuring do, let’s configure it!
$objTimespan = New-TimeSpan -Minutes 45
Set-AdfsProperties -EnableExtranetLockout $true -ExtranetLockoutThreshold 3 -ExtranetObservationWindow $objTimespan
Great now we have it configured! Now we have to know how to navigate our way through the logs should it become a persistent issue that we need to troubleshoot. By default a lot of the logging is not going to be configured yet which brings us to our next section of this post, setting up all of the logging so you can troubleshoot with your new and shiny feature!
First thing we need to do is tell AD FS to log success and failure events to the event log. You do this by opening up AD FS Management on your AD FS server and opening Federation Service Properties. Select the Events tab and check the Success audits and Failure audits options. You don’t need success audits, but I think they’re nice to have.
Next we need to configure the AD FS server to audit properties generated by applications. You do this with GPO (local or domain, dealers choice), as seen below.
We’re all set for logging now! But what did that time and effort buy you? Well really it comes in three forms of Event IDs in the security log of the AD FS server: 403, 411, and 516.
- Event ID 403: This is most useful for figuring out the User Agent that is making the request. The User Agent is the application being used so think of things like Chrome, Mozilla, a native phone app, etc. This will also give you the Client IP, but if you have this behind a WAP as is Microsoft’s recommendation you will only see your WAP’s IP.
- Event ID 411: These are your failed token validation attempts, aka your failed authentication attempts. These logs provide the actual Client’s IP which is quite useful when trying to source the device.
- Event ID 516: These are your Extranet Lockout events, your bread and butter. This tells you the Bad Password Count AD FS saw, the Last Bad Password Attempt, and the actual Client IP like 411 does.
Now I’ll be frank, Event ID 516 is the one you’ll be looking at the most so I’ll put a screenshot of that one below.
I would like to talk about 516 a little more in depth. You will notice that all of these errors will have a Activity ID which can be matched to each other. This will allow you to match them up to aggregate the different information you get from each Event ID. I bring this up because you will, and I meant to use the word will, come across events where the Activity ID is going to be 00000000-0000-0000-0000-000000000000 as you see above. After much heartache to figure this out, this means that the request came from a legacy application such as a native phone email application or Thunderbird. With these you will get TWO IP addresses. One of these will be a Microsoft IP address and the other will be the IP address where the request came from. This is significant because the request is actually coming from the Microsoft IP address as Exchange Online processes the credentials and forwards them on to your AD FS server. I’m sure you’re already seeing how this makes blocking the requests difficult, as you can’t control Microsoft’s perimeter network. I’ll leave dealing with that for another post.