This Blog is for anyone wanting to load balance the Exchange 2010 CAS role using only open source software. In my example I will be starting with a simple Debian net-install and building the HAProxy package from source because I wanted the latest feature set available. I would definitely recommend using a recent 1.5-dev build if following this guide or parts of the HAProxy configuration may be incompatible.
Update the system and install dependencies :
1. Update
root@localhost:~# apt-get update
2. Install dependencies
root@localhost:~# apt-get install build-essential make libpcre3 libpcre3-dev
Downloading/Building the HAProxy package :
1. Download the HAProxy Package available from http://haproxy.1wt.eu
root@localhost:~# wget http://haproxy.1wt.eu/download/1.5/src/devel/haproxy-1.5-dev11.tar.gz
2. Extract the package
root@localhost:~# tar -xvzf haproxy-1.5-dev11.tar.gz
3. Change directory and make the package
root@localhost:~# cd haproxy-1.5-dev11
root@localhost:~/haproxy-1.5-dev11# make TARGET=linux2628 ARCH=x86_64 USE_PCRE=1
4. Install the newly compiled package and confirm it is installed.
root@localhost:~/haproxy-1.5-dev11# make install root@localhost:~/haproxy-1.5-dev11# /usr/local/sbin/haproxy -vv
Assuming you didn’t run into any errors with the previous commands you should now have HAProxy installed.
Configuring startup script :
1. Create the startup script
root@localhost:~/haproxy-1.5-dev11# nano -w /etc/init.d/haproxy
2. Paste the following into the new file and save it(with Ctrl+X)
#!/bin/sh # /etc/init.d/haproxy PATH=/bin:/usr/bin:/sbin:/usr/sbin pidfile=/var/run/haproxy.pid binpath=/usr/local/sbin/haproxy options="-f /etc/haproxy/haproxy.cfg" test -x $binpath || exit 0 case "$1" in start) echo -n "Starting HAproxy" $binpath $options #start-stop-daemon --start --quiet --exec $binpath -- $options echo "." ;; stop) echo -n "Stopping HAproxy" kill `cat $pidfile` #start-stop-daemon --stop --quiet --exec $binpath --pidfile $pidfile echo "." ;; restart) echo -n "Restarting HAproxy" #start-stop-daemon --stop --quiet --exec $binpath --pidfile $pidfile kill `cat $pidfile` sleep 1 $binpath $options echo "." ;; *) echo "Usage: /etc/init.d/haproxy {start|stop|restart}" exit 1 esac exit 0
3. Change permissions and register the startup script
root@localhost:~/haproxy-1.5-dev11# cd /etc/init.d root@localhost:~/etc/init.d# chmod +x haproxy root@localhost:~/etc/init.d# update-rc.d haproxy defaults
You should now be able to start and stop haproxy with “service haproxy <action>” where the action is start/stop/restart.
Creating the HAProxy configuration file :
1. Create folder structure and open the config file for editing
root@localhost:~/etc/init.d# mkdir /etc/haproxy root@localhost:~/etc/init.d# nano -w /etc/haproxy/haproxy.cfg
2. Paste in the example configuration and adapt for your settings.
N.B. The bind lines below can be adapted to listen on a specific IP address, simply add your desired local IP: bind 192.168.72.120:135,192.168.72.120:60200,192.168.72.120:60201
global daemon stats socket /var/run/haproxy.stat mode 600 level admin pidfile /var/run/haproxy.pid maxconn 40000 ulimit-n 81000 defaults mode http balance roundrobin timeout connect 4000 timeout client 86400000 timeout server 86400000
frontend CAS-RPC bind :135,:60200,:60201 mode tcp maxconn 40000 default_backend CAS-RPC-SERVERS
frontend CAS-WEB bind :80,:443 mode tcp maxconn 40000 default_backend CAS-WEB-SERVERS
frontend HT-SMTP bind :25 mode tcp maxconn 40000 default_backend HT-SERVERS
backend CAS-RPC-SERVERS stick-table type ip size 10240k expire 60m stick on src option redispatch option abortonclose balance leastconn server EXCH01 192.168.72.222 weight 1 check port 135 inter 2000 rise 2 fall 3 on-marked-down shutdown-sessions server EXCH02 192.168.72.223 weight 1 check port 135 inter 2000 rise 2 fall 3 on-marked-down shutdown-sessions
backend CAS-WEB-SERVERS stick-table type ip size 10240k expire 60m stick on src option redispatch option abortonclose balance leastconn server EXCH01 192.168.72.222 weight 1 check port 443 inter 2000 rise 2 fall 3 on-marked-down shutdown-sessions server EXCH02 192.168.72.223 weight 1 check port 443 inter 2000 rise 2 fall 3 on-marked-down shutdown-sessions
backend HT-SERVERS option redispatch option abortonclose balance leastconn server EXCH01 192.168.72.222 weight 1 check port 25 inter 2000 rise 2 fall 3 on-marked-down shutdown-sessions server EXCH02 192.168.72.223 weight 1 check port 25 inter 2000 rise 2 fall 3 on-marked-down shutdown-sessions
listen stats :7777 stats enable stats uri / option httpclose stats admin if TRUE stats auth admin:password
3. Start HAProxy with your new configuration
root@localhost:~/etc/init.d# service haproxy start
N.B. At this stage if you receive errors like below please check that something else is not listening on any of the required ports.
[ALERT] 205/123152 (2839) : Starting proxy CAS: cannot bind socket [192.168.72.120:135]
You now also have a WUI in the form of the HAProxy stats page which includes useful options such as taking a server offline etc.
http://<IP-ADDRESS>:7777/
Configuring the Exchange 2010 CAS role :
1. Either configure the ports manually or using the following Registry file(user beware)
Link to the Registry file = http://downloads.loadbalancer.org/RPC%20Ports.reg
Manual Static Port Configuration
To set a static port for the RPC Client Access Service, open the registry on each CAS and navigate to:
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesMSExchangeRPC
Here, you need to create a new key named ParametersSystem, and under this key create a new DWORD(32-bit) Value named TCP/IP Port as shown below. The Value for the DWORD should be the port number you want to use. Microsoft recommends you set this to a unique value between 59531 and 60554 and use the same value on all CAS. In this Blog the port used is 60200.
N.B. Make sure you use a DWORD Value for this key
To set a static port for the Address Book Service, open the registry on each CAS and navigate to:
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesMSExchangeAB
Here, you need to create a new key named Parameters, and under this key create a new String Value named RpcTcpPort as shown below. Microsoft recommends you set this to a unique value between 59531 and 60554 and use the same value on all CAS. In this Blog the port used is 60201.
N.B. Make sure you use a STRING Value for this key
2. Creating the DNS entry
Create a DNS record for the CAS Array, this should be the same as the load balancer’s IP address(bind address if used earlier), e.g. cas.domain.com
3. Configure the CAS array object
Use the following command from the Exchange 2010 management shell to create the object :
New-ClientAccessArray –Name “CAS-array” –FQDN “cas.domain.com” -Site “default-first-site-name”
N.B. change “default-first-site-name” to the AD site appropriate for your Client Access Servers
N.B. change “cas.domain.com” to the FQDN of the CAS array(same as the DNS entry)
If the mail database already existed before creating the array, you’ll also need to run the following command to relate the new CAS array to the database:
Set-MailboxDatabase "NameofDatabase" -RpcClientAccessServer “cas.domain.com”
To verify the configuration of the CAS array, use the following commands from the Exchange Shell :
get-ClientAccessServer
lists the available Client Access Servers
get-ClientAccessArray
lists the Client Access Array and its members
Finished
Once you’ve completed all the previous steps you can now access your CAS services via your load balancer IP, it should also be correctly load balancing connections for better performance and real server resilience. There are still many ways you could build further resilience or add more features to this solution such as HA, DAG’s and SSL Termination but this will still give you perfectly adequate load balancing of the CAS and HT roles.