Archive for September, 2010
SSL load balancing with HAProxy and stunnel on Debian
HAProxy is a great load balancer; however, it doesn't natively terminate SSL connections. Fortunately, stunnel can terminate SSL connections and seamlessly forward them to HAProxy. To be able to log the client's IP address, we'll need to patch stunnel to provide X-Forwarded-For headers to HAProxy.
The following instructions are based on Debian Squeeze, HAProxy 1.4.8-1, and stunnel 4.32.
To get started, download the stunnel source and X-Forwaded-For patch:
wget http://www.stunnel.org/download/stunnel/src/stunnel-4.32.tar.gz wget http://haproxy.1wt.eu/download/patches/stunnel-4.32-xforwarded-for.diff
Before building stunnel, we need to install a few other packages:
apt-get install build-essential libssl-dev haproxy
To install stunnel:
tar -zxvf stunnel-4.32.tar.gz cd stunnel-4.32 patch -p1 < ../stunnel-4.32-xforwarded-for.diff ./configure make && make install adduser stunnel ln -s /usr/local/etc/stunnel /etc/stunnel touch /var/log/stunnel.log chown -R stunnel:stunnel /usr/local/etc/stunnel chown -R stunnel:stunnel /var/run/stunnel chown stunnel:stunnel /var/log/stunnel.log
Then we have to create the necessary files in /etc/stunnel: stunnel.conf, stunnel.pem, and the SSL certificate (server.crt) and key file (server.key). The server.crt and server.key are the SSL certificate and key which would normally go on a web server. The following stunnel.conf will accept incoming HTTPS connections on port 443, then forward it to port 81 as regular HTTP traffic – just change the ip address from 192.168.1.1 to your own.
Example /etc/stunnel/stunnel.conf:
cert=/etc/stunnel/stunnel.pem setuid=stunnel setgid=stunnel pid=/var/run/stunnel/stunnel.pid output = /var/log/stunnel.log socket=l:TCP_NODELAY=1 socket=r:TCP_NODELAY=1 [https] cert=/etc/stunnel/server.crt key=/etc/stunnel/server.key accept=192.168.1.1:443 connect=192.168.1.1:81 xforwardedfor=yes
Next, we'll need to create our stunnel certificate file, stunnel.pem. More details about the certificate creation process are available at Using Certificates with stunnel, but you can just run the following command:
openssl req -new -x509 -days 365 -nodes -config /etc/stunnel/stunnel.conf -out /etc/stunnel/stunnel.pem -keyout /etc/stunnel/stunnel.pem
Finally, here's an example haproxy.cfg file (/etc/haproxy/haproxy.cfg) – just change your web server IPs:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
user haproxy
group haproxy
daemon
maxconn 20000
defaults
log global
option dontlognull
balance leastconn
clitimeout 60000
srvtimeout 60000
contimeout 5000
retries 3
option redispatch
listen http 192.168.1.1:80
mode http
cookie WEBSERVERID insert
option httplog
balance source
option forwardfor except 192.168.1.1
option httpclose
option redispatch
maxconn 10000
reqadd X-Forwarded-Proto:\ http
server webserver1 192.168.1.2 cookie webserver1 maxconn 5000
server webserver2 192.168.1.3 cookie webserver2 maxconn 5000
listen https 192.168.1.1:81
mode http
cookie WEBSERVERID insert
option httplog
balance source
option forwardfor except 192.168.1.1
option httpclose
option redispatch
maxconn 10000
reqadd X-Forwarded-Proto:\ https
server webserver1 192.168.1.2 cookie webserver1 maxconn 5000
server webserver2 192.168.1.3 cookie webserver2 maxconn 5000
