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.
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