Building/enabling HAProxy to use tls 1.3 centos 7 / ubuntu

This article gives an outline of how to build HAProxy with OpenSSL so it can use TLS v1.3 on centos or ubuntu.

1. Build and install OpenSSL 1.1.1

In order to have TLS 1.3 support, you will need to install version 1.1.1 of OpenSSL.

These instructions build OpenSSL into a directory /usr/local/openssl-1.1.1 shared to ensure that it’s separate from any other OpenSSL installs on the machine. If you want you can upgrade your existing OpenSSL to version 1.1.1

OpenSSL will require GCC. Install GCC using either of the commands

#The command installs a bunch of new packages including gcc, g++ and make
sudo yum group install "Development Tools"

#This will just install gcc package
yum -y install gcc
wget https://www.openssl.org/source/openssl-1.1.1.tar.gz
tar -xzf openssl-1.1.1.tar.gz
cd openssl-1.1.1
./config --prefix=/usr/local/openssl-1.1.1 shared
make
sudo make install

Build and install HAProxy

You need HAProxy 1.8.1 or later to enable TLS 1.3 support. We are using 2.4.4

For Ubuntu follow this instruction.

Uninstall the existing haproxy installation first. I would suggest to take a backup of old haproxy configuration if you have one.

sudo mv /etc/haproxy /etc/haproxy-old

apt remove haproxy*
sudo apt install build-essential libpcre2-dev zlib1g-dev

cd ~
wget https://www.haproxy.org/download/2.4/src/haproxy-2.4.4.tar.gz
tar -xzf haproxy-2.4.4.tar.gz
cd haproxy-2.4.4/
make TARGET=linux2628 CPU=native USE_PCRE2=1 USE_PCRE2_JIT=1 USE_OPENSSL=1 SSL_LIB=/usr/local/openssl-1.1.1/lib SSL_INC=/usr/local/openssl-1.1.1/include USE_ZLIB=1
sudo make install

For Centos follow this instruction

sudo mv /etc/haproxy /etc/haproxy-old

yum remove haproxy*
yum install -y make gcc gcc-c++ pcre-devel openssl-devel readline-devel systemd-devel zlib-devel

cd ~
wget http://www.haproxy.org/download/2.4/src/haproxy-2.4.4.tar.gz
tar -xvzf haproxy-2.4.4.tar.gz
cd haproxy-2.4.4

make -j $(nproc) TARGET=linux-glibc USE_OPENSSL=1 SSL_LIB=/usr/local/openssl-1.1.1/lib SSL_INC=/usr/local/openssl-1.1.1/include USE_ZLIB=1 USE_PCRE=1 USE_SYSTEMD=1

make install

Adding haproxy user

useradd -M -r -s /sbin/nologin haproxy

Now create systemd file
LD_LIBRARY_PATH must be added because OpenSSL 1.1.1 is direct installed or else you will get an error.

nano /etc/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=network.target
[Service]
Environment=LD_LIBRARY_PATH=/usr/local/openssl-1.1.1/lib/
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "EXTRAOPTS=-S /run/haproxy-master.sock"
ExecStartPre=/usr/local/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS
ExecStart=/usr/local/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE $EXTRAOPTS
ExecReload=/usr/local/sbin/haproxy -f $CONFIG -c -q $EXTRAOPTS
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed
Restart=always
SuccessExitStatus=143
Type=notify
[Install]
WantedBy=multi-user.target

Now create haproxy config directory in /etc.

mkdir -p /etc/haproxy

Now you can enable the systemd configuration

systemctl enable haproxy
systemctl start haproxy

Check Installed HAProxy version

haproxy -v

Add the following to the HAProxy config (Note the ssl-default-bind-ciphers and ssl-default-bind-options lines), updating any paths as required.

If you only want TLSv1.3 with no fallback to TLSv1.2 then set ssl-default-bind-options to force-tlsv13

global
        log /dev/log    local0
        chroot /usr/local/var/lib/haproxy
        user haproxy
        group haproxy
        maxconn  4000
        pidfile  /usr/local/var/run/haproxy.pid
        tune.ssl.default-dh-param  2048
# Add below lines for tls 1.3 configuration rest you can ignore
        ssl-default-bind-ciphers TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:TLS13-CHACHA20-POLY1305-SHA256:EECDH+AESGCM:EECDH+CHACHA20
        ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11

# Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private

defaults
        balance roundrobin
        timeout  http-request 10s
        timeout  queue 1m
        timeout  connect 10s
        timeout  client 1m
        timeout  server 1m
        timeout  check 10s

listen dns
# Note the keycert.pem file is the concatenation of  the certificate chain and key into one file which is what HAProxy requires.
        bind :::853 v4v6 tfo ssl crt /etc/certs/keycert.pem
        mode tcp
        server server1 127.0.0.1:9999

If you are using above configuration. The above configuration sets HAProxy to run chroot in a directory /usr/local/var/lib/haproxy. It’s necessary to create this directory. OpenSSL also needs access to /dev/urandom and /dev/random in the chroot.

mkdir -p /usr/local/var/lib/haproxy/dev
cd /usr/local/var/lib/haproxy/dev
mknod urandom c 1 9
mknod random c 1 8

Restart again HAProxy

sudo service haproxy restart 

sudo systemctl restart haproxy

Lastly, the firewall on CentOS is quite restrictive by default. If required use the following commands to allow the required services and reload the firewall.

sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-port=8181/tcp
sudo firewall-cmd --reload
0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments