We’ve been setting up Active Directory Federation Services (ADFS) on Windows Server 2012 R2 to tie up with Office365, and we ran into a snag with load balancing ADFS on our aging F5 BIG-IP LTM. It’s on the dinosaur end of the historical timeline, or to put it another way, “it’s in its sunset year”, and the latest supported code is 10.2.4.
This poses a bit of an issue with monitoring the ADFS servers, since the version shipping with Windows Server 2012 R2 includes a new SSL TLS feature called “Server Name Indication”, or SNI. The prehistoric 10.2.4 BIG-IP code doesn’t support SNI. Thankfully, Microsoft provides a way to monitor the servers over HTTP (instead of HTTPS), but the documentation we found–links below–was lacking an important detail.
- F5 DevCentral article for ADFS 2012 (not R2/3.0/SNI)
- Microsoft Application Proxy Blog re: supporting non-SNI capable clients
Most articles out there simply say to use an HTTP monitor with the pool (of HTTPS members). Bigger issue. Others vary the Send String details. Minor issue.
The bigger issue here is that a standard/basic HTTP monitor applied to a pool of HTTPS members will attempt its health checks over HTTPS, not HTTP. This won’t work when checking /adfs/probe on the ADFS servers. You have to specify an “Alias Service Port” in the Advanced configuration of the monitor when you create it.
Now that we found that, it seems a bit obvious, so veterans of the F5 community might be thinking, “no duh”, but everywhere we looked, it wasn’t mentioned. Sure, it was implied, but we’ve never had a use case like this. Anyways, that’s the first part.
After that, the Send String is important to get right, because the LTM won’t get its desired Receive String match unless you do.
Send String: GET /adfs/probe HTTP/1.1\nHost: \nConnection: Close\n\r\n\r
Receive String: HTTP/1.1 200 OK
Initially, we lacked the duplicate “\n\r” at the end (we just had one), and the connection never closed. The host seemed to accept a variety of options, including the FQDN (i.e. “adfs.domain.com”), hostname (though this only works when applying it in a member-specific manner), and blank.
Here’s what ours looked like in the end. You’re welcome to tweak the interval/timeout, as other instructions may state (30/91), but we wanted a more timely response (5/16).