Load balancing Microsoft Exchange

From securityrouter.org, an OpenBSD-based firewall
Revision as of 17:13, 10 February 2018 by Anders (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Many customers ask about load balancing Microsoft Exchange[1]. The procedure is a little different depending on if you're using Microsoft Exchange 2010 or 2013.

Exchange 2010

This guide, written by Jonas Back, describes load balancing of two (or more) Exchange 2010 servers, using a single-NIC load balancer; both on the inside network and Internet. The load balancer could be either a hardware appliance, or a virtual machine. To simplify this guide, SSL offloading is not used and therefore all SSL is terminated at the Exchange servers where we have the certificates installed.

Network overview

Both Exchange servers are multi-role running CAS/MB/HT. CAS is running in a CAS Array, MBX is running in a DAG and we will also load balance internal SMTP for 3rd party applications. The SR load balancer can be used in a cluster (high availability) setup, but this is not a requirement. Configuration is the same no matter if it’s a single-node or a clustered load balancer.

Configure static port mapping

Exchange 2010 uses different protocols for different clients:

Client Protocol TCP ports  Security zone
Outlook RPC Random  Internal only
OWA, ActiveSync, Outlook Anywhere, EWS HTTPS 443  External
Third-party clients POP3, IMAP4 110, 143, 993, 995  External
Mail transfer SMTP 25  External (MX, doesn't need load balancer)

By default, Exchange 2010 uses the TCP End Point Mapper port (135) and the dynamic RPC port range (6005-59530) for inbound connections every time an Outlook clients establish a connection to Exchange. Creating a load balancer configuration for this can get quite complex, so therefore it’s recommended to configure Exchange to use dedicated ports for RPC client communications. This can easily be configured on the Exchange SP1+ servers by adding the following registry keys. The ports values can be any value you want, but we recommend the below values to be able to easily follow this guide. In this example RPC Client Access Service will use TCP port 59532 and Address Book Service will use TCP port 59533. As before, TCP port 135 is still in use for the initial communication. Note that we assume you are running Exchange 2010 SP1 or newer. Otherwise, see the link below.

Path Type Name Value
 TCP/IP Port 59532
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\MSExchangeAB\Parameters REG_SZ
 RpcTcpPort 59533

After that, you need to restart the following services or reboot the server:

  • Microsoft Exchange RPC Client Access
  • Microsoft Exchange Address Book

You can verify that these static ports now are used by running the following command in the Command Prompt:

Netstat -an -p tcp

No change is needed on the clients since they will automatically use these ports. We also recommend you configure these values using GPP (Group Policy Preferences). For more information, please read the Microsoft official article[2].

Configuring CAS Array

There are a couple of steps you need to take in Exchange to prepare Exchange for load balancing. First you need to create a CAS Array:

New-ClientAccessArray -Name “My CAS Array” -Fqdn “outlook.lab.local” -Site “My AD site”

Then you need to configure all Mailbox databases to use this CAS Array:

Get-MailboxDatabase | Set-MailboxDatabase -RpcClientAccessServer “outlook.lab.local”

Then you need to create a DNS A record so that outlook.lab.local points to the VIP (Virtual IP) that we will configure shortly. In the meantime, you could configure the DNS A record to point to one of the CAS servers which will result in all clients going to this server.

Please note that all Outlook profiles configured prior to this are using the old server name for their Outlook profiles. They need to be re-configured so that they use the CAS Array name rather than the old server name. If you want to know more regarding the CAS Array and how it’s used, we recommend reading the Exchange team blog post Demystifying the CAS Array Object[3].

Firewall and load balancer setup

We assume you have setup basic network functionality. For more information, please read the getting started guide.

  1. Go to System > Administration
  2. Change the HTTPS port to something like 4433, or bind (listen on) an IP different than what you're going to load balance on
  3. Go to Network > Load balancer > Wizard
  4. Unless you will be using the load balancer as the Exchanges' router (default gateway), choose the layer 4+ method
    1. Name: anything you like
    2. Listen (load balance) on: the dedicated VIP that you added above
    3. Service (ports): HTTPS
    4. Hosts (nodes): the IP address of the Exchange CAS servers, one on each line
  5. Press "Add" (this will create the load balancer for HTTPS)
  6. Set the mode the load balancer is using to "Source hash" on the "Forward to" table
  7. Press "Save"
  8. Go to "System -> Load balancer", click on "Add.. -> Relay (Layer 4+)" and do the same procedure for the other ports
  9. Deploy the working copy on Configuration > Deploy working copy and commit
  10. You might get temporarily disconnected, because you changed the web interface settings

The resulting configuration should look similar to

interface vic0 {
	route default
load-balancer {
	table <exchange> { }
	relay "HTTPS" {
		listen on port 443
		forward to <exchange> check tcp mode source-hash
	relay "POP3" {
		listen on port 110
		forward to <exchange> check tcp mode source-hash
	relay "POP3S" {
		listen on port 995
		forward to <exchange> check tcp mode source-hash
	relay "IMAP" {
		listen on port 143
		forward to <exchange> check tcp mode source-hash
	relay "IMAPS" {
		listen on port 993
		forward to <exchange> check tcp mode source-hash
	relay "RPCLS" {
		listen on port 135
		forward to <exchange> check tcp mode source-hash
	relay "RPCCAS" {
		listen on port 59532
		forward to <exchange> check tcp mode source-hash
	relay "RPCABS" {
		listen on port 59533
		forward to <exchange> check tcp mode source-hash
system {
	authentication {
		user "admin" {
			password "admin"
	dns {
	http-server {
		port 4433

The final step is to forward traffic to the load balancer and if the firewall is active making sure that there are firewall rules allowing traffic in to the SR on the ports that are going to be load balanced. Because the security router software contains both a firewall and a load balancer, both these features can be integrated as one. Having one (or more) MX record pointing at multiple address will result in an even traffic distrubition among all cluster nodes. However, if you really feel like doing so, you can of course add port 25 to the load balancer, too.

Persistance and session affinity

In the example above, persistance is implied by "source-hash" mode, which essentially means that a given client (address) always reaches the same server using source address hashing. If you choose to use layer 3 (redirect) instead of layer 4+ (relay) using for example the "least-states" mode, it needs sticky-address and source tracking timeout settings.