How To Configure NetScaler Load Balancing for Exchange 2013

How To Configure NetScaler Load Balancing for Exchange 2013

book

Article ID: CTX202446

calendar_today

Updated On:

Description

This article describes NetScaler load balancing configuration for user access to the Exchange 2013 CAS servers.

Citrix ADM StyleBooks simplifies Citrix ADC load balancing configurations for Exchange. Refer to Citrix Docs to learn more - Microsoft Exchange StyleBook.


Instructions

Table of Contents

Basic Principles and Design Choices

When we talk about load balancing Exchange CAS, it is mostly about load-balancing HTTPS traffic. While the other types of traffic (SIP, SMTP, IMAP4 and so on) are also important, they are not nearly as big in terms of volume and not nearly as complex. That is why most of this article is about load balancing HTTPS traffic.

In our design, we followed both Microsoft and Citrix recommendations. Microsoft has a good but rather theoretical article (Load Balancing in Exchange 2013) on the Exchange 2013 CAS load balancing. Accumulating our experience of working with both NetScaler and Exchange, we decided on the following:

  1. We are using single namespace layer 7 proxy with no session affinity. 
  2. All the idle timeouts on the NetScaler must be at least 1.5 times longer than on Exchange server. 
  3. As described in the article above, we created custom monitors for all the Exchange web apps and bound them to their respective back-end entities (service groups). That allows us to adhere to the Microsoft-recommended health-per-protocol principle. 
  4. Exchange 2013 load balancing does not require any connection persistence.
Back to top

Preparing Exchange CAS Servers

Configuring Exchange CAS server correctly is a vast task. However, we are only interested in the parts connected to load balancing. In Exchange 2013, there are no CAS arrays anymore, so no need to create one. The only thing to do is to configure TCP/IP idle timeout. The default value is two hours. Set it to 20 minutes. This is done through registry. By default, this parameter in the registry does not exist so we need to add it:

Name: KeepAliveTime
Path: HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
Data Type: REG_DWORD
Value: 0x124F80 (1,200,000 milliseconds)

Back to top

General Architecture of the SSL Content Switch

Below is the load-balancing architecture as seen by the Microsoft:

User-added image

The basic idea is that Layer 7 proxy allows us to have independent logical entry point for each Exchange web app which in turn allows us to independently switch them on and off based on their individual health rather than overall health of the server. Now, let us see how this general architecture can be translated into NetScaler configuration.

First thing that comes to mind is that some web apps can be grouped together to avoid excessive complexity. We grouped together OWA and ECP. Also, our testing indicates that Outlook Anywhere (RPC) and EWS need to be grouped together in order to avoid transient Outlook errors. In addition, we are not implementing MAPI at this point. It can be easily added later. Finally, we need a catchall default entity for cases when URL does not match anything. The general diagram is presented in Figure 2.

As you can see, user connects to the Content Switch first. Content Switch directs user’s request to the appropriate LB Virtual Server based on the URL. Finally, there is a Service Group bound to each Virtual Server. It is important to note, that, since all the Exchange web apps live on the same server and the same TCP port, all five Virtual Servers and all five Service Groups are nearly identical to each other. They only have different monitors.

User-added image

Back to top

Implementing Exchange Web Load-Balancing

Creating Health Monitors

Starting with Exchange 2013, we can check individual Exchange app’s health by running a simple HTTP query with the URL https://<server>/<app>/healthcheck.htm. If the app is healthy, the code 200 is returned. NetScaler allows us to easily create Monitors.

Figure 3 and Figure 4 show how to create Monitor for OWA. Make sure to do the following:

  1. Select type HTTP-ECV. 
  2. Uncheck LTRM. 
  3. Check Secure. 
  4. Specify Send String: "GET /owa/healthcheck.htm" 
  5. Specify Return String: "200".

User-added image

User-added image

To create Monitors for all the other apps, repeat the same with app-appropriate URLs. On the other hand, you can more efficiently, create all the monitors by running the following commands in the NetScaler CLI:

add lb monitor https-ecv-mail-owa HTTP-ECV -send "GET /owa/healthcheck.htm" -recv 200 -LRTM DISABLED -secure YES
add lb monitor https-ecv-mail-ecp HTTP-ECV -send "GET /ecp/healthcheck.htm" -recv 200 -LRTM DISABLED -secure YES
add lb monitor https-ecv-mail-ews HTTP-ECV -send "GET /EWS/healthcheck.htm" -recv 200 -LRTM DISABLED -secure YES
add lb monitor https-ecv-mail-msa HTTP-ECV -send "GET /Microsoft-Server-ActiveSync/healthcheck.htm" -recv 200 -LRTM DISABLED -secure YES
add lb monitor https-ecv-mail-oab HTTP-ECV -send "GET /OAB/healthcheck.htm" -recv 200 -LRTM DISABLED -secure YES
add lb monitor https-ecv-mail-rpc HTTP-ECV -send "GET /Rpc/healthcheck.htm" -recv 200 -LRTM DISABLED -secure YES
add lb monitor https-ecv-mail-mapi HTTP-ECV -send "GET /MAPI/healthcheck.htm" -recv 200 -LRTM DISABLED -secure YES
add lb monitor https-ecv-mail-autodisc HTTP-ECV -send "GET /AutoDiscover/healthcheck.htm" -recv 200 -LRTM DISABLED -secure YES

Simply, copy and paste them into the NetScaler CLI.

Back to top

Creating Service Groups

First, before even creating Service Groups, we need to create Servers. That is easy enough. Just specify a name and an IP address of a CAS server – see Figure 5. You need to create as many of those as many CAS servers you have. We created two - CAS1 and CAS2.

User-added image

Back to top

Example: Creating OWA Service Group Using GUI

The next step is to create Service Groups in accordance with Figure 2. Again, let us look at OWA as an example. When adding a new Service Group using GUI, make sure you do the following:

  1. Select SSL as Protocol (Figure 6). 
  2. Add all CAS servers by a) selecting Server Based; b) selecting the server from the list; c) specifying port 443 and d) clicking Add (Figure 6). 
  3. Add OWA and ECP monitors on the Monitors tab (Figure 7). 
  4. Enter 1800 as both client and server timeouts on the Advanced tab (Figure 8) 
  5. Enable client IP address in the header by a) clicking on Override Global; b) clicking on Client IP and c) entering " X-Forwarded-For" as Header (Figure 8). This will allow you to see client IP addresses (instead of NetScaler IP address) in the Exchange logs.

Of course, creating all the Service Groups this way might be tedious. Especially, if you have more than one Exchange access point. In addition, as noted above the Service Groups are almost identical (except for Monitors). Makes sense to automate this.

User-added image

User-added image

User-added image

Back to top

Creating All the Service Groups Using CLI

First, run the following to create Service Group objects:

add serviceGroup mail_owa SSL -maxClient 0 -maxReq 0 -cip ENABLED X-Forwarded-For -usip NO -useproxyport YES -cltTimeout 1800 -svrTimeout 1800 -CKA NO -TCPB NO -CMP YES -appflowLog DISABLED
add serviceGroup mail_as SSL -maxClient 0 -maxReq 0 -cip ENABLED X-Forwarded-For -usip NO -useproxyport YES -cltTimeout 1800 -svrTimeout 1800 -CKA NO -TCPB NO -CMP YES -appflowLog DISABLED
add serviceGroup mail_rpc SSL -maxClient 0 -maxReq 0 -cip ENABLED X-Forwarded-For -usip NO -useproxyport YES -cltTimeout 1800 -svrTimeout 1800 -CKA NO -TCPB NO -CMP YES -appflowLog DISABLED
add serviceGroup mail_autodisc SSL -maxClient 0 -maxReq 0 -cip ENABLED X-Forwarded-For -usip NO -useproxyport YES -cltTimeout 1800 -svrTimeout 1800 -CKA NO -TCPB NO -CMP YES -appflowLog DISABLED
add serviceGroup mail_oab SSL -maxClient 0 -maxReq 0 -cip ENABLED X-Forwarded-For -usip NO -useproxyport YES -cltTimeout 1800 -svrTimeout 1800 -CKA NO -TCPB NO -CMP YES -appflowLog DISABLED
add serviceGroup mail_d SSL -maxClient 0 -maxReq 0 -cip ENABLED X-Forwarded-For -usip NO -useproxyport YES -cltTimeout 1800 -svrTimeout 1800 -CKA NO -TCPB NO -CMP YES -appflowLog DISABLED

Here is the convention used:

  •  "_owa" – OWA and ECP; 
  •  "_as" – ActyveSync; 
  •  "_rpc" – Outlook Anywhere and EWS; 
  •  "_autodisc" – Autodiscover; 
  •  "_oab" – OAB; 
  •  "_d" – Catch all. 

Then, run the following to bind all CAS servers to all Service Groups:

bind serviceGroup mail_owa CAS1 443 -CustomServerID "\"None\""
bind serviceGroup mail_owa CAS2 443 -CustomServerID "\"None\""
bind serviceGroup mail_as CAS1 443 -CustomServerID "\"None\""
bind serviceGroup mail_as CAS2 443 -CustomServerID "\"None\""
bind serviceGroup mail_rpc CAS1 443 -CustomServerID "\"None\""
bind serviceGroup mail_rpc CAS2 443 -CustomServerID "\"None\""
bind serviceGroup mail_autodisc CAS1 443 -CustomServerID "\"None\""
bind serviceGroup mail_autodisc CAS2 443 -CustomServerID "\"None\""
bind serviceGroup mail_oab CAS1 443 -CustomServerID "\"None\""
bind serviceGroup mail_oab CAS2 443 -CustomServerID "\"None\""
bind serviceGroup mail_d CAS1 443 -CustomServerID "\"None\""
bind serviceGroup mail_d CAS2 443 -CustomServerID "\"None\""

And finally, bind all the monitors to their respective Service Groups:

bind serviceGroup mail_owa -monitorName https-ecv-mail-owa
bind serviceGroup mail_owa -monitorName https-ecv-mail-ecp
bind serviceGroup mail_as -monitorName https-ecv-mail-msa
bind serviceGroup mail_rpc -monitorName https-ecv-mail-ews
bind serviceGroup mail_rpc -monitorName https-ecv-mail-rpc
bind serviceGroup mail_oab -monitorName https-ecv-mail-oab
bind serviceGroup mail_autodisc -monitorName https-ecv-mail-autodisc
bind serviceGroup mail_d -monitorName tcp

Note: We are using a default TCP Monitor for the catch all Service Group.

Back to top

Creating LB Virtual Servers

Additional consideration: by default, all the NetScaler HTTP and SSL Virtual Servers have caching enabled. Our experience indicates that caching causes problems for some Exchange clients. Based on Microsoft's recommendation, we disabled caching by applying "NoCache" policy.

Back to top

Example: Creating OWA LB Virtual Server Using GUI

When creating OWA LB Virtual Server, male sure you do the following:

  1. Select HTTP Protocol (Figure 9). 
  2. Uncheck Directly Addressable checkbox (Figure 9). 
  3. On the Service Groups tab, check the checkbox next to the "mail_owa" Service Group (Figure 10). 
  4. On the Policies tab, click on Cache (Request) and bind "noCacheRest" policy by clicking on Insert Policy and selecting the policy name from the drop-down list (Figure 11). 
  5. Do not change anything on the Methods and Persistence tab as we do not need any persistence (Figure 12). 
  6. On the Advanced Tab, enter "1800" in the Client Timeout field (Figure 13).

User-added image

User-added image

User-added image

User-added image

User-added image

Back to top

Creating All the LB Virtual Servers Using CLI

First, create the LB Virtual Servers:

add lb vserver mail.citrix.com_443_owa HTTP 0.0.0.0 0 -persistenceType NONE -cltTimeout 1800
add lb vserver mail.citrix.com_443_as HTTP 0.0.0.0 0 -persistenceType NONE -cltTimeout 1800
add lb vserver mail.citrix.com_443_rpc HTTP 0.0.0.0 0 -persistenceType NONE -cltTimeout 1800
add lb vserver mail.citrix.com_443_autodisc HTTP 0.0.0.0 0 -persistenceType NONE -cltTimeout 1800
add lb vserver mail.citrix.com_443_oab HTTP 0.0.0.0 0 -persistenceType NONE -cltTimeout 1800
add lb vserver mail.citrix.com_443_d HTTP 0.0.0.0 0 -persistenceType NONE -cltTimeout 1800

Second, disable caching:

bind lb vserver mail.citrix.com_443_owa -policyName _noCacheRest -priority 100 -gotoPriorityExpression END -type REQUEST
bind lb vserver mail.citrix.com_443_as -policyName _noCacheRest -priority 100 -gotoPriorityExpression END -type REQUEST
bind lb vserver mail.citrix.com_443_rpc -policyName _noCacheRest -priority 100 -gotoPriorityExpression END -type REQUEST
bind lb vserver mail.citrix.com_443_autodisc -policyName _noCacheRest -priority 100 -gotoPriorityExpression END -type REQUEST
bind lb vserver mail.citrix.com_443_oab -policyName _noCacheRest -priority 100 -gotoPriorityExpression END -type REQUEST
bind lb vserver mail.citrix.com_443_d -policyName _noCacheRest -priority 100 -gotoPriorityExpression END -type REQUEST

Finally, bind the Service Groups to their respective LB Virtual Servers:

bind lb vserver mail.citrix.com_443_owa mail_owa
bind lb vserver mail.citrix.com_443_as mail_as
bind lb vserver mail.citrix.com_443_rpc mail_rpc
bind lb vserver mail.citrix.com_443_autodisc mail_autodisc
bind lb vserver mail.citrix.com_443_oab mail_oab
bind lb vserver mail.citrix.com_443_d mail_d

Additionally, if you are using XenMobile NetScaler Connector (XNC), you need to bind XNC responder policies to the ActiveSync virtual server:

bind lb vserver mail.citrix.com_443_as -policyName <POLICY_W_DEVICEID> -priority 90 -gotoPriorityExpression END -type REQUEST
bind lb vserver mail.citrix.com_443_as -policyName <POLICY_WO_DEVICEID> -priority 100 -gotoPriorityExpression END -type REQUEST

Back to top

Creating the Content Switch

Exchange Content Switch exists for the sole purpose of directing HTTPS traffic to the appropriate LB Virtual Server based on the URL. That behavior is determined by the Content Switch Policies.

Back to top

Creating Content Switch Policies

Without diving too much into theory, Content Switch is just a logical expression that needs to be bound to the Content Switch and associated with the LB Virtual Server.

User-added image

Using GUI to create the OWA Content Switch Policy is shown on Figure 14. You can see that the expression is true if the URL starts with either "/owa" or "/ecp". All the policies are shown in Table 1.

Exchange Apps 

Plolicy Name 

Expression 

OWA & ECP 

mail_owa 

HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH("/owa") || HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH("/ecp") 

ActiveSync 

mail_as 

HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH("/Microsoft-Server-ActiveSync") 

Outlook Anywhere & EWS 

mail_rpc 

HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH("/Rpc") || HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH("/EWS") 

Autodiscover 

mail_autodisc 

HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH("/Autodiscover") 

OAB 

mail_oab 

HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH("/OAB") 

To create all the policies, run the following in the CLI:

add cs policy mail_owa -rule "HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH(\"/owa\") || HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH(\"/ecp\")"
add cs policy mail_as -rule "HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH(\"/Microsoft-Server-ActiveSync\")"
add cs policy mail_rpc -rule "HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH(\"/Rpc\") || HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH(\"/EWS\")"
add cs policy mail_autodisc -rule "HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH(\"/Autodiscover\")"
add cs policy mail_oab -rule "HTTP.REQ.URL.SET_TEXT_MODE (IGNORECASE).STARTSWITH(\"/OAB\")"

Back to top

Creating the Content Switch

Lastly, we need to create the content switch and bind all the policies. Do the following:

  1. Open Create Virtual Server (Content Switching) dialog box. 
  2. Specify Name, Protocol (SSL), IP Address and Port (443) - Figure 15. 
  3. On the Advanced tab, enter "1800" in the Client Time-out field - Figure 16 
  4. On the SSL Settings tab select the right certificate. 
  5. Click Create.

User-added image

User-added image

In order to automate creating the Content Switch, run the following in the CLI instead:

add cs vserver mail.citrix.com_cs_443 SSL <ip_address> 443 -cltTimeout 1800
bind ssl vserver mail.citrix.com_cs_443 -certkeyName <cert_name>

You need to enter specific IP address and certificate name.

At this point, the Content Switch is created but it is "empty". Now you need to bind the Content Switch Policies and associate them with LB Virtual Servers.

Back to top

Binding Content Switch Policies

To bind the policies, open the Content Switch properties and click on CSV - Figure 17. To bind each policy, you need to a) click Insert Policy; b) select the policy name from the dropdown list; and c) select LB Virtual Server name from the Target dropdown list. The last policy you bind should be "(Default)". That is not really a policy. You are just binding the catchall LB Virtual server.

User-added image

Figure 17 is a good example of what it should look like after you are done.

To perform the same operations in CLI, run the following:

bind cs vserver mail.citrix.com_cs_443 -policyName mail_as -targetLBVserver mail.citrix.com_443_as -priority 80
bind cs vserver mail.citrix.com_cs_443 -policyName mail_rpc -targetLBVserver mail.citrix.com_443_rpc -priority 90
bind cs vserver mail.citrix.com_cs_443 -policyName mail_owa -targetLBVserver mail.citrix.com_443_owa -priority 100
bind cs vserver mail.citrix.com_cs_443 -policyName mail_oab -targetLBVserver mail.citrix.com_443_oab -priority 105
bind cs vserver mail.citrix.com_cs_443 -policyName mail_autodisc -targetLBVserver mail.citrix.com_443_autodisc -priority 110
bind cs vserver mail.citrix.com_cs_443 -lbvserver mail.citrix.com_443_d

Back to top

Load Balancing Other Types of CAS Traffic

Load balancing other types of traffic is simple: we create TCP LB Virtual Server for the following ports:

  1. 25 (default SMTP) 
  2. 80 (HTTP) 
  3. 110 (POP3) 
  4. 143 (IMAP4) 
  5. 587 (client SMTP) 
  6. 993 (IMAP4-S) 
  7. 995 (POP3-S) 
  8. 5060 (Unified Messaging TCP) 
  9. 5061 (Unified Messaging TLS) 

Other things to pay attention:

  1. There is no persistence on these LB Virtual Servers. 
  2. All the idle tem-outs are set to 1800 sec. 
  3. Port 80 LB Virtual Server is in fact just a redirect to HTTPS.

Back to top

Issue/Introduction

This article describes NetScaler load balancing configuration for user access to the Exchange 2013 CAS servers.