27 février 2015

Use Citrix Netscaler as a replacement for ADFS Proxy


I did a setup last year to replace the Microsoft ADFS Proxy by using the Netscaler 10.1 as the reverse proxy for ADFS 2.0 on Windows 2008r2 (I found a Citrix article about ADFS 3.0 that refer to the fact that Netscaler doesn't support the sni feature for the backend server that is used in ADFS 3.0 which is most likely causing headache to ADFS 3.0 users. http://support.citrix.com/article/CTX125798
The citrix article refer you to this microsoft article that talk about a way to partially disable the SNI feature for ADFS 3.0... http://blogs.technet.com/b/applicationproxyblog/archive/2014/06/19/how-to-support-non-sni-capable-clients-with-web-application-proxy-and-ad-fs-2012-r2.aspx

Citrix recently published a document to accomplish this but after looking at it I realized that my setup was looking much simpler so I will publish it in this article. This blog article assume you already have your Netscaler deployed in the DMZ ready to accept external connection (we use "2 arm mode" as we do some Load balancing internally and also some reverse proxy externally)

To use the Netscaler as a reverse proxy for ADFS you need to have your Netscaler licensed for "AAA - Traffic Management" (AAA-TM) so that you can authenticate directly on the Netscaler using LDAP.

This step is optional but I strongly suggest that you Load Balance (LB) your Domain Controller (DC) to have LDAP redundancy in your Netscaler as you can't configure it to authenticate to more than 1 source so if that source is a LB then you have redundancy. 

Go into Traffic management, Load Balancing, Servers -> Add, enter the name of your domain controller (DC1.domain), the IP address and then click create. Repeat for the rest of your DC. 

Next, you need to create a service group for LDAP, go into Traffic management, Load Balancing, Service Groups-> Add, name: SG_LDAP_Domain_389 -> Protocol: TCP -> under members, click on server based, under port, type: 389, then choose the DC you created previously DC1.domain and click add, repeat for every DC in that domain, go into the monitors tab and choose TCP (note: this will only monitor if port 389 is open and listening on the DC (Citrix has some documentation on how to create a complete LDAP monitor if you really want to be bullet proof but I didn't do it so I can't comment on this part, for us, monitoring TCP port 389 was considered reliable enough to confirm if the DC is up or not). Note: Citrix documentation configure things using "Services" but I prefer to do the configuration using "Service Groups" as to me it's always simpler and safer to create a Group and put member in it instead of configuring multiple service for the same need with multiple server. 

Next we create the LB Vserver for LDAP, go into Traffic management, Load Balancing, Virtual Servers -> Add, name: LB_LDAP_Domain, IP address: x.x.x.x, Port: 389, Services Group: SG_LDAP_Domain_389, in the Method and Persistence Tab, LB Method: Least connection, Persistence: None.

Now we will create the LDAP authentication, go into Security, AAA - Application Traffic, Policies, Authentication, LDAP, in the Servers tab, click on add, Name: LDAP-LB_LDAP_Domain, Authentication type: LDAP, IP address: x.x.x.x (you need provide the IP address of the LB Vserver you created earlier) Type: AD, Port: 389, Timeout: 5, Base DN: DC=corp,DC=company,DC=com (I input the root of the domain as the search point but you can "OU=users," in front of it to restrict the search) "Administrator Bind DN" is the user you define to authenticate in AD, this user doesn't need any special permission as everyone that is authenticated has read access in AD, password and confirm password are self-explaining. Server logon Name: SamAccountName, Group Attribute: memberOf, Sub Attribute name: CN, Security: PLAINTEXT (we used port 389 above which is unencrypted). Put a check mark into "Authentication" and "User Required", under nested group extraction, I choose enable, Maximum Nesting Level: 4, GroupName: SamAccountName, Group Search: memberof, Group Search Sub-attribute: CN. Click create.

Next, still under LDAP go into the Policies tab, click Add -> Name: domain.company.com, Authentication Type: LDAP, Server: LDAP-LB_LDAP_Domain, Expression: ns_true, click create.

Next, under Security, AAA-TM, Virtual Servers, click Add, Name: vs_Auth.domain.com IP: x.x.x.x. Protocol: SSL, Port: 443 Domain: company.com (This field is very important see AuthDomainNote for more detail) Certificates: choose a valid certificate for the URL your user will be redirected to for login (Ex: auth.company.com), under authentication tab, click on "Insert Policy" in the bottom of the page and choose the policy we created earlier: domain.company.com and click on create. Note, you can configure multiple authentication profile if you want to use the dual factor authentication you can create an RSA authentication policy and insert it in the "Second..." and you will have dual authentication. http://support.citrix.com/article/CTX113640/ explain how to setup RSA with Netscaler, just do the setup under security, AAA-TM, Policies, Authentication, Radius instead of under Netscaler Gateway.

Next we need to make sure SSO is enable in AAA-TM -> go into Security, click on AAA - Application Traffic and choose "Change global settings" and put a check mark into "Single Sign-on to Web Applications" then click OK.

Finally we create the ADFS LB_Vserver and his component, go to traffic management, Load Balancing, Servers to add your ADFS servers the same way we created the DC earlier, then go into "Service Groups", create a new service group for your ADFS servers, Name: SG_ADFS_HTTPS Protocol: SSL, choose "server based", port: 443 click "add" on your ADFS server, in the monitor tab: choose: httpS-ecv

Go to Load Balancing, Virtual Servers, click Add
Name: LB_ADFS_ExternalUrl, Protocol: SSL, IP: x.x.x.x (This need to be resolvable externally as your ADFS URL, it's the IP address that was pointing to your ADFS Proxy before), Port: 443, Service Groups Tab: SG_ADFS_HTTPS, Method and Persistence tab: Least connection, Persistence: COOKIEINSERT, time-out: 0, SSL settings: Choose the certificate that match your ADFS URL. The important part is under advanced tab, scroll down to the bottom and expend "Authentication settings", check the "Authentication" box and then enter the FQDN of the url your user will be redirected to for authentication (EX: auth.company.com) See AuthDomainNote2 below.

 AuthDomainNote: The domain here is critical if you want to have everything working, it must match with the domain name that your user will be coming from to this Vserver, if user want to authenticate to application.testcompany.com and your domain name is company.com then the authentication will not work, it will only authenticate user coming from the domain company.com, this is not related to the domain name you put in AD, it can be anything as long as your domain match the domain of the url it's coming from.

AuthDomainNote2: This URL must be reachable externally and it must point to the Authentication Vserver IP address.

Now if everything works fine when you try and reach your ADFS URL you will land on the Black Netscaler login page. Type your LDAP credential and the Netscaler will then request an ADFS token on your behalf from the ADFS server and you will then be granted access to Office365 portal. This also works with any other ADFS provider that you may have configured.

Next step you will most likely want is to customize the Netscaler login page to fit your company need. I published an article in December 2014 that explain how to achieve this: http://cividan.blogspot.ca/2014/12/customize-netscaler-101-aaa-tm-login.html



7 commentaires:

  1. Great guide Thanks very much. Just a small question do I need to use a separate IP for the "vs_Auth.domain.com IP: x.x.x.x.? or can I use the same as "LB_LDAP_Domain"?

    RépondreEffacer
    Réponses
    1. Hi, for me the "LB_LDAP_Domain" is an internal IP in our corporate network while the "vs_auth_domain.com" is an IP exposed to internet so that user can authenticate from outside and is published with the DNS name auth.company.com

      Effacer
  2. Thanks very much again - it makes sense.

    RépondreEffacer
  3. Hello, thanks for sharing this very good post!
    Is there anything especially I need to configure to log on to ADFS after entering credentials at the Netscaler log on page?
    Currently when I enter credentials I need to enter it again on the ADFS log on page..
    Any idea? Under Global Settings is SSOn enabled...
    Much appreciated your guide and your help...

    Greetz, Nik

    RépondreEffacer
  4. Hi, yes SSO needs to be enable in the global settings, and also make sure you direct your request straight to the ADFS server. I'm using authentication profile for 3 differents levels of authentication and my netscaler send the credentials to all the different backend server without any problem. Try with another server that require authentication to test if it works or ask in the citrix forum depending on your NS version things might be done a bit different.

    RépondreEffacer
  5. Have you configured Kerberos Constrained Delegation on your NetScaler in order to impersonate your ADFS server? This step seems to be missing from all of the NetScaler/ADFS Proxy guides, I don't understand how to configure SSO without it.

    RépondreEffacer
    Réponses
    1. No I have not configured Kerberos on the Netscaler as we never needed it. The netscaler passes the credential to the ADFS server (ADFS 2.0) and the ADFS server react the same way as if you were authenticating straight on it.

      Effacer