Apache’s HAProxy is a proxy software but it can also load balance between servers. The significance of version 1.5 is it’s ability to handle SSL connections where as before you needed to off load the connection to a different server such as nginx or Apache.
Unfortunately the the latest Long Term Release (LTS) of Ubuntu came out 4-5 months before 1.5 made it to stable release. This means 1.5 was not include in the official repositories.
Fortunately Vincent Bernat has created and maintained Personal Package Archives (PPA) so that it can be installed using apt-get.
Install helper utility to add additional repositories:
Add HAProxy PPA to the repository list:
sudo add-apt-repository ppa:vbernat/haproxy-1.5
Update cached repositories:
sudo apt-get update
Install HAProxy:
sudo apt-get install haproxy
HAProxy allows rules to be configured to match on incoming requests and direct the request to the relevant backend. It’s not a 1:1 relationship so multiple frontends can be redirected to the same backend.
For now we will just make a load balanced configuration which means you’ll need 2 or more servers.
Make a backup of the config file:
sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak
Change /etc/haproxy/haproxy.cfg where necessary. I have an example of load balancing WordPress found here. The example has this type of topology:
Any names used in configuration from frontend to cookies can be changed to any name as long as they are one word and it’s best not to use too many special characters.
Some HAProxy terminology:
Line by line explaination of frontend configuration:
frontend www-http
Defines the section for a front end. The second word after frontend is the name of the frontend.
bind *:80
The interface and port the frontend will accept and handle incoming requests. The * means any interface and :80 is the port.
bind *:443 ssl crt /etc/haproxy/ssl/dannytsang.co.uk.pem crt /etc/haproxy/ssl/
A variation of the *:80 is the one above using SSL. This defines a frontend which listens on the HTTPS port (443), ssl tells HAProxy to expect a SSL connection. crt /etc/haproxy/ssl/dannytsang.co.uk.pem is the certificate to use. Certificates can be listed here so if more than one certificate is used for different domains e.g sub domains then it can be listed with crt /path/to/cert.pem. A folder can also be specified like crt /etc/haproxy/ssl/. In this case it will use any certificate in the folder where the Common Name matches the request address. If no matches are found then it will default to the crt /etc/haproxy/ssl/dannytsang.co.uk.pem
reqadd X-Forwarded-Proto:\ http
Forward extended header information to the backend.
option forwardfor
Forward the source IP to the backend.
use_backend wordpress-http if { hdr(host) -i dannytsang.co.uk }
This tells the front end what backend to forward the request to. wordpress-http is the name of the backend. This backend will only be used if the request was trying to access the domain name dannytsang.co.uk. Multiple lines can be used to define different pattern matching and pass the request to different backends.
default_backend wordpress-http
Passes the request to wordpress-http if no matches were found.
Line by line description for the backend configraution:
backend wordpress-http
Start of a backend configuration. The name of the backend group of servers is called wordpress-http
cookie WP_ID insert
Declare a cookie for cookie based sticky session. The cookie name is called WP_ID and it will be inserted into the client’s session.
server wpssl1 10.0.0.2:443 cookie wp1 check
Create a server as part of the backend group named wpssl1 and it’s IP address and port (10.0.0.2:443). The server will use a cookie based sticky session. The cookie to check if the client has already had any dealings with HAProxy before is called wp1. It will also perform periodic checks on this server to make sure it’s up.
server wpssl1 10.0.0.2:443 cookie wp1 check ssl verify none
As above but the difference is this one is an SSL connection (ssl) and also the backend will have it’s own SSL which it should not check it’s validity e.g for self signed certificates (verify none).
On my “journey” to attempt to get high availability, I have found the prefix for a cookie session didn’t work for TT RSS, a self hosted RSS aggregator. It would constantly reload the whole page when it made a call to backend.php. The prefix means it will use an existing cookie and attach session data. I may have been configuring it incorrectly so it may not have detected an existing cookie to use.
The above example sets up a Layer 4 load balancing strategy which is one of the basic methods of load balancing. The advantage is higher availability but complications can arise if the backend response are not synchronized and managing sessions (both beyond the scope of this article).
How To Implement SSL Termination With HAProxy on Ubuntu 14.04