Home » Random Goodies » HAProxy with SSL support

HAProxy with SSL support

While the easiest way currently is to install HAProxy from a repo, chances are the 1.4 version is still there, which does not support SSL natively. As such, we’re going to be going over installing HAProxy on a 64bit CentOS (both CentOS 5 and CentOS 6 installs would be the same), from source. Brace yourselfs… lol 🙂

Anyways, first we get the source; I have mirrored all releases since they fail to use Github or Sourceforge and, well, I always get 10K/s downloads and hate it. We will use the 1.5 dev22 source in this howto, but it will likely apply for future releases as well, if not, drop a message and I’ll get it updated.

[[email protected] ~]# cd /usr/local/src/
[[email protected] src]# wget -qq http://mirror.gurutek.biz/haproxy/1.5/src/devel/haproxy-1.5-dev22.tar.gz

And extract:

[[email protected] src]# tar zxf haproxy-1.5-dev22.tar.gz

Great. Now we can finally build our load balancer:

Prereqs:

[[email protected] src]# yum -y install openssl-devel pcre-devel

Start building and installing:

[[email protected] src]# cd haproxy-1.5-dev22
[[email protected] haproxy-1.5-dev22]# make -j4 TARGET=linux26 USE_PCRE=1 USE_OPENSSL=1 ARCH=$(uname -m) PCRE_LIB=/usr/lib64 SSL_LIB=/usr/lib64
[[email protected] haproxy-1.5-dev22]# make install
install -d /usr/local/sbin
install haproxy /usr/local/sbin
install haproxy-systemd-wrapper /usr/local/sbin
install -d /usr/local/share/man/man1
install -m 644 doc/haproxy.1 /usr/local/share/man/man1
install -d /usr/local/doc/haproxy
for x in configuration architecture haproxy-en haproxy-fr; do \
install -m 644 doc/$x.txt /usr/local/doc/haproxy ; \
done
[[email protected] haproxy-1.5-dev22]#

As you can see, the default source install is /usr/local, as are the current packages found in repositories. If you were following this article for an upgrade, this should conclude your binary update process. Personally, I don’t like the long directory path and I work out of /etc/haproxy for the remainder of this post.

Now on to a configuration example. This is a simple config, which will demonstrate the following:

– Loading an SSL directly in to HAProxy
– Creating a frontend and backend
– Use of a simple ACL to redirect /wp-admin requests to the primary slave. This is useful when not using asynchronous file sharing between your slaves.

[[email protected] haproxy-1.5-dev22]# cat /etc/haproxy/haproxy.cfg
global
maxconn 5000
spread-checks 3
pidfile /var/run/haproxy.pid
daemon

defaults
log global
maxconn 15000
mode http
retries 3
contimeout 5000
clitimeout 90000
srvtimeout 90000
balance leastconn
option abortonclose # abort request if client closes output channel while waiting
option httpclose # add “Connection:close” header if it is missing
option forwardfor # insert x-forwarded-for header so that app servers can see both proxy and client IPs
option redispatch # any server can handle any session
timeout client 180s # previously 60
timeout connect 10s
timeout server 180s # previously 30
timeout check 5s
stats enable
stats realm Haproxy\ Statistics
stats auth view:password
stats refresh 8s
monitor-uri /monitor # Returns 200 if we\’re up

frontend http-in
bind 1.1.1.1:80
acl is_admin url_beg /wp-admin
use_backend admin_backend if is_admin
default_backend haproxy.demo.slaves

frontend haproxy.demo.ssl
bind 1.1.1.1:443 ssl crt /etc/haproxy/ssl/haproxy.demo.pem no-sslv3 ciphers RC4-SHA:AES128-SHA:AES256-SHA
option http-server-close
reqadd X-Forwarded-Proto:\ https if { ssl_fc }
acl is_admin url_beg /wp-admin
use_backend admin_backend if is_admin
default_backend haproxy.demo.slaves

backend haproxy.demo.slaves
cookie ha_lb insert
server ha_lb_1 2.2.2.2:80 cookie ha_lb_1 check maxconn 10
server ha_lb_2 3.3.3.3:80 cookie ha_lb_2 check maxconn 1000

backend admin_backend
server ha_rw 2.2.2.2:80 check
[[email protected] haproxy-1.5-dev22]#

The init.d script reads as follows:

[[email protected] haproxy-1.5-dev22]# cat /etc/init.d/haproxy
#!/bin/sh
#
# haproxy
#
# chkconfig: – 85 15
# description: HAProxy is a free, very fast and reliable solution \
# offering high availability, load balancing, and \
# proxying for TCP and HTTP-based applications
# processname: haproxy
# config: /etc/haproxy/haproxy.cfg
# pidfile: /var/run/haproxy.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ “$NETWORKING” = “no” ] && exit 0

exec=”/usr/local/sbin/haproxy”
prog=$(basename $exec)

[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog

lockfile=/var/lock/subsys/haproxy

check() {
$exec -c -V -f /etc/$prog/$prog.cfg
}

start() {
$exec -c -q -f /etc/$prog/$prog.cfg
if [ $? -ne 0 ]; then
echo “Errors in configuration file, check with $prog check.”
return 1
fi

echo -n $”Starting $prog: ”
# start it up here, usually something like “daemon $exec”
daemon $exec -D -f /etc/$prog/$prog.cfg -p /var/run/$prog.pid
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}

stop() {
echo -n $”Stopping $prog: ”
# stop it here, often “killproc $prog”
killproc $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}

restart() {
$exec -c -q -f /etc/$prog/$prog.cfg
if [ $? -ne 0 ]; then
echo “Errors in configuration file, check with $prog check.”
return 1
fi
stop
start
}

reload() {
$exec -c -q -f /etc/$prog/$prog.cfg
if [ $? -ne 0 ]; then
echo “Errors in configuration file, check with $prog check.”
return 1
fi
echo -n $”Reloading $prog: ”
$exec -D -f /etc/$prog/$prog.cfg -p /var/run/$prog.pid -sf $(cat /var/run/$prog.pid)
retval=$?
echo
return $retval
}

force_reload() {
restart
}

fdr_status() {
status $prog
}

case “$1″ in
start|stop|restart|reload)
$1
;;
force-reload)
force_reload
;;
check)
check
;;
status)
fdr_status
;;
condrestart|try-restart)
[ ! -f $lockfile ] || restart
;;
*)
echo $”Usage: $0 {start|stop|status|restart|try-restart|reload|force-reload}”
exit 2
esac
[[email protected] haproxy-1.5-dev22]#

Make sure to make it executable:

[[email protected] haproxy-1.5-dev22]# chmod +x /etc/init.d/haproxy

And fire it up!

[[email protected] haproxy-1.5-dev22]# service haproxy start
Starting haproxy: [ OK ]
[[email protected] haproxy-1.5-dev22]#

Later 😉