Pages

Sunday, May 3, 2020

Configure Citrix ADC to load balance Microsoft Active Directory Federation Services (AD FS) on Windows Server 2019

As a continuation of the AD FS deployment from two of my previous posts:

Deploying a redundant Active Directory Federation Services (ADFS) Web Application Proxy servers on Windows Server 2019
http://terenceluk.blogspot.com/2020/04/deploying-redundant-active-directory_21.html

Deploying a redundant Active Directory Federation Services (ADFS) farm on Windows Server 2019
http://terenceluk.blogspot.com/2020/04/deploying-redundant-active-directory.html

This post serves to demonstrate the configuration of Citrix ADC (formerly known as Citrix NetScalers) to load balance the ADFS farm as well as the ADFS Web Application Proxy (WAP) servers.

Design Considerations

As outlined in the Load Balancer requirements section in the following Microsoft documentation:

AD FS Requirements
https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/overview/ad-fs-requirements

  • The load balancer MUST NOT terminate SSL. AD FS supports multiple use cases with certificate authentication which will break when terminating SSL. Terminating SSL at the load balancer is not supported for any use case, which means the Protocol you will use for your Load Balancing Service Group and Virtual Server will be SSL_BRIDGE and not SSL as the latter terminates the SSL connection and re-establishes the connection.
  • SNI support is recommended and any Citrix ADC / NetScaler above version 11.1 supports it (https://www.citrix.com/content/dam/citrix/en_us/citrix-developer/documents/Netscaler/how-to-connect-to-adfs-3-0-from-netscaler-adc-load-balancer.pdf)
  • The health probe that the Citrix ADC should use to monitor the health of the ADFS servers should be HTTP and not HTTPS.
  • ADFS also does not support HEAD requests (https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/overview/ad-fs-faq#does-ad-fs-support-head-requests) so the Citrix ADC should use a GET request to probe the health of the server.
  • DNS round robin is not recommended but this won’t be an issue as we’ll be using a Citrix ADC to provide load balancing.
  • It is NOT recommended to use IP based session affinity or sticky sessions for authentication traffic to AD FS within the load balancer. This can cause an overload of certain nodes when using legacy authentication protocol for mail clients to connect to Office 365 mail services (Exchange Online).

IP Requirements

  • 1 x IP address will be required for the VIP of the load balancing virtual server on the Citrix ADC that represents the internal ADFS farm
  • 1 x IP address will be required for the VIP of the load balancing virtual server on the Citrix ADC that represents the internal ADFS WAP servers
  • 1 x public IP address will be required to NAT traffic from the internet to the WAP VIP

We’ll be using a Citrix ADC VPX 200 Standard license with the build NS13.0 52.24.nc for this demonstration.

Firewall Rules

  • Other than port 443 traffic between the Citrix ADC / NetScaler, you will also need to allow port 80 in order to monitor the health of the ADFS server (both internal farm and Web Access Proxy)
  • ICMP is optional and is convenient for troubleshooting at times but it is not necessary

Internal ADFS farm and WAP Servers

  • The Load Balancing virtual server for the internal ADFS farm servers and the WAP servers will have the same configuration all of the components:
    • Monitor
    • Service Group
    • Virtual Server

This essentially means that you can confirm the load balancing virtual server for the internal ADFS farm servers then repeat the same for the WAP servers.

Creating a Service Monitor

One of the most common question I am asked the most is how to properly create a service monitor for the ADFS servers as Microsoft recommends against monitoring the service via HTTPS and to use HTTP as described in the following documentation under the Load Balancer requirements:

AD FS Requirements

https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/overview/ad-fs-requirements#BKMK_7

  • It is recommended to use the HTTP (not HTTPS) health probe endpoints to perform load balancer health checks for routing traffic. This avoids any issues relating to SNI. The response to these probe endpoints is an HTTP 200 OK and is served locally with no dependence on back-end services. The HTTP probe can be accessed over HTTP using the path ‘/adfs/probe'
  • http://<Web Application Proxy name>/adfs/probe
  • http://<ADFS server name>/adfs/probe
  • http://<Web Application Proxy IP address>/adfs/probe
  • http://<ADFS IP address>/adfs/probe

image

Another common blog post I am sent for review is the following:

Load balancing ADFS and ADFS Proxy using Citrix ADC

https://www.vcloudnine.de/load-balancing-adfs-and-adfs-proxy-using-citrix-adc/

While the write up is excellent with describing the behavior and monitoring process of the service, the following use of the HEAD request for the monitor would not work:

add lb monitor mon_adfs_http HTTP -respCode 200 -httpRequest "HEAD /adfs/probe" -LRTM ENABLED -destPort 80

Attempting to configure such a monitor with the HTTP Request configured as HEAD /adfs/probe as shown in the following screenshot will cause the probe to fail.

image

It does not come to a surprise that this is a common mistake as the HEAD request is the default when a HTTP monitor is created and the Microsoft documentation explicitly states ADFS also does not support HEAD requests (https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/overview/ad-fs-faq#does-ad-fs-support-head-requests) so the monitor would display the following probe error:

Failure - HTTP response code 405 received.

image

This can also be tested directly from the Citrix ADC / NetScaler by getting into the Linux shell and executing:

HEAD <IP Address>/adfs/probe

image

The correct method of retrieving the health of the ADFS server is through the GET method, which would return a 200 OK response:

GET -s <IP Address>/adfs/probe

***Note that you need to include the -s as that switch displays the status code but it is not needed when configuring the monitor.

image

If you omit the -s then no output would be displayed:

image

----------------------------------------------------------------------------------------------------------------------------

Extra Commands to Test

Another command that can be executed within the Linux shell of the Citrix ADC / NetScaler to test the health of the ADFS is:

curl -i http://<IP Address>/adfs/probe

image

You can also use the same curl command within a PowerShell console to probe the health ADFS server:

curl http://<IP Address>/adfs/probe

image

----------------------------------------------------------------------------------------------------------------------------

With the above outlined, create a HTTP type monitor as shown in the following screenshots:

Name: A preferred monitor name (e.g. mon_adfs_http)

Type: HTTP

Interval: 5 seconds

Response Time-out: 2 seconds

Response Codes: 200

Custom Header: <leave blank>

HTTP Request: GET /adfs/probe

Secure: <unchecked>

Advanced Parameters

Leave all settings as default and configure the following:

Destination Port: 80

Enable LRTM (Lease Response Time using Monitoring):

imageimageimage

Create Server Objects

Create the server objects on the Citrix ADC that represents ADFS servers. This demonstration will use the internal server farm servers as an example but the steps are the same for the Web Application Proxy (WAP) servers that provide external ADFS connectivity.

image

Repeat the same procedure for all of the servers in the farm.

Create Service Group

It is possible to use either Services of Service Groups to represented the ADFS service that will be offered but Service Groups provide an simpler method of adding more than one server for the service so this example will employ this approach.

image

Provide a name for the Load Balancing Service Group, configure the protocol as SSL_BRIDGE and leave the rest of the parameters as the default.

***Note that as mentioned above (and repasted below), we cannot terminate the SSL connection on the load balancer as this is not supported.

The load balancer MUST NOT terminate SSL. AD FS supports multiple use cases with certificate authentication which will break when terminating SSL. Terminating SSL at the load balancer is not supported for any use case.

imageimage

With the empty service group will be created, click on No Service Group Member to add the previously created server objects that were created:

image

Proceed to select the servers for the ADFS farm:

image

Configure the Port for the two servers to be 443 and leave the rest as defaults:

image

The selected servers will now be in the service group:

image

Proceed to click on the Monitors option on the right side of the load balancing service group:

image

Click on the No Service Group to Monitor Binding to add the previously created monitor for the ADFS servers:

image

Click on the Add button to display the available monitors:

image

Select the previously created monitor from the bottom of the list (new monitors are placed at the bottom):

image

Click on the Bind button to bind the monitor to the service group:

image

The Monitors section should now display 1 Service Group to Monitor Binding:

image

Click Done to complete the configuration for the service group:

image

Create Virtual Server

Proceed to create a new virtual server:

image

Provide a name for the Virtual Server, configure the protocol as SSL_BRIDGE, enter the pre-allocated VIP as the IP Address, specify the port as 443, and leave the rest of the parameters as the default.

image

With the newly created Load Balancing Virtual Server created, click on No Load Balancing Virtual Server ServiceGroup Binding to add the previously created Service Group:

image

Click on the Add button:

image

Select the Service Group created earlier:

image

Click on the Bind button to complete the configuration:

image

Complete the creation of the virtual server by clicking on Done:

image

Confirm that the virtual server’s State and Effective State is in an UP state, then repeat the same procedure for the Web Application Proxy (WAP) servers.

image

3 comments:

arma said...

Hello, is it possible to see originating source IP in the ADFS logs with this method?

Anonymous said...

Any answer to arma's question? I'd like to know this as well.

Terence Luk said...

Hello, apologies for the late reply but there isn't an easy way to do so because we are using SSL_Bridge which means we cannot insert an IP into the packets being delivered to the ADFS server. The only way I can think of is using DSR but I usually do not recommend that because a requirement would be that your NetScaler resides on the same subnet as the ADFS server.