HAProxy stays in the middle of origin server and the visitors. Hence, You need a SSL for the Visitors to HAProxy. You can use HAProxy is a secure private network to fetch data from backend without any SSL. But the requests between the visitor and HAProxy has to be encrypted. You can use Let’s Encrypt free signed SSL for this purpose.
First, we need to install ‘certbot’, python based client for Let’s Encrypt SSL. It is available in epel repository. In CentOS, you may do the following to install certbot
$ yum install epel-release $ yum install certbot
Let’s Encrypt uses a Challenge Response technique to verify the host and issue the SSL. While HAProxy is enabled, and used to set to the origin service, this unfortunately, is not possible. certbot comes with an option called ‘standalone’, where it can work as a http server and resolve the Challenge Response issued by Let’s Encrypt. To do this, first we need to stop the haproxy server. You can do this with the following:
# stop haproxy service haproxy stop # get the ssl for your domain.com and www.domain.com certbot certonly --standalone --preferred-challenges http --http-01-port 80 -d www.domain.com -d domain.com
Once this is done, 4 files are saved under /etc/letsencrypt/live/domain.com/
These should be:
cert.pem (Your certificate)
chain.pem
privatekey.pem (Your private key)
fullchain.pem (cert.pem and chain.pem combined)
Now, for haproxy, we need to combine 3 files, cert.pem, chain.pem and privatekey.pem, we can do that by combining fullchain.pem & privatekey.pem. You need to create a directory under /etc/haproxy/certs and then put the file in there. You can do that as following:
# create the directory mkdir /etc/haproxy/certs # Combine two files into one in one line DOMAIN='domain.com' sudo -E bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem' # replace domain.com with each of your domain.
Now, we have the pem file ready to be used on haproxy frontend. To use, you may first edit the haproxy.cfg file, create a new section for frontend https, and use the certificate. An example is given below
frontend main_https bind *:443 ssl crt /etc/haproxy/certs/domain.com.pem reqadd X-Forwarded-Proto:\ https option http-server-close option forwardfor default_backend app-main
Once the https section is done, you may now want to force the http section to forward to https, you can do as following:
frontend main bind *:80 redirect scheme https code 301 if !{ ssl_fc } option http-server-close option forwardfor
You should be all set now using Let’s Encrypt with your Haproxy in the frontend.