How to install Haproxy, Letsencrypt, Varnish cache and Nginx tutorial

Actually I won’t get into details with Varnish and Nginx configuration because it really depends on your particular case. But it should be pretty straight forward as installing default packages:

apt install varnish
apt install nginx

I’m using port 443 for SSL services, so HAProxy is using this one. It also uses HTTP port 80 and redirects that to https. Everybody knows that Haproxy is stable and quick in jobs it does and that’s load balancing and proxying traffic. In our case, we are going to use it for SSL termination and forward traffic to Varnish which is going to occupy port 6081 (default). And Nginx will use port 8080 because it’s the final destination in our setup. Varnish should cache most of the web content and hopefully put our dedicated server’s CPU at ease most of the time and leverage quite slow CPU to a large amount of RAM (128GB).

In case of traffic increase we can easily balance our traffic to other servers behind Varnish,  because Varnish can play a load-balancing role as well.

So, let’s install Haproxy and Letsencrypt. Letsencrypt is your way to free digital certificates. There are few drawbacks of using Letsencrypt like cert expiration time is 3 months but it’s free and for time being stable so if you don’t need something better it’s fine. And EFF has a nice newsletter about digital freedom just to keep you informed how close we are to digital enslavement in the form of abolishing net neutrality led by large telecoms. Well, maybe we are already digital slaves of our devices, so it’s not important. 🙂

add-apt-repository ppa:certbot/certbot
apt update
apt install haproxy
apt install certbot

Of course, if you’re not root you have to use sudo in front of the commands.

In our particular case, I already have valid certificates so I just copied everything from directory /etc/letsencrypt from old server to new one. If you need to generate new certificates you can use certbot:

certbot certonly --standalone --preferred-challenges http --http-01-port 888 -d example.com -d www.example.com

By specifying the deploy-hook parameter it’s possible to perform some tasks after a certificate is generated, like restarting web server or in our case HAProxy. So the certbot command can look like this:

certbot certonly --standalone --preferred-challenges http --http-01-port 888 --deploy-hook /etc/letsencrypt/deploy-hook.sh -d example.com -d www.example.com

Deploy-hook.sh script may contain the following code:

#!/bin/bash
cat /etc/letsencrypt/live/steadyhealth.net/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem > /etc/haproxy/certs/example.pem
systemctl reload haproxy

You should use port 80 to generate a certificate and it should not be used by another service on your server. Test if the port is in use with:

netstat -na | grep ‘:80.*LISTEN’

If you already have installed web server it could occupy this port, so for Nginx you might need to issue following command to stop it while generating certificate:

systemctl stop nginx

You don’t need to use port 80 to generate your certificates, you can use port 443 as well, because you’re using standalone plugin which in effect serve its own server for authentication. Also, you could listen on other ports with certbot server but in that case, you must forward letsencrypt validation requests from whatever you have listened to those port to certbot server. Note that we set certbot standalone mode to listen on port 888 so we need to forward challenge requests from port 80 to port 888. Another thing that is important is your DNS record, meaning your FQDN should point to the correct IP.

For Haproxy to work as SSL terminator you need to combine fullchain.pem and privkey.pem in one file and add it in config. So the first cd to /etc/letsencrypt/live/example.com/ and then type:

cat fullchain.pem privkey.pem > example.com.pem

Open /etc/haproxy/haproxy.cfg and change bind line in your frontend settings to something like:

bind xxx.xxx.xxx.xxx:443 ssl crt /etc/letsencrypt/live/example.com/example.com.pem

You also need to add forwarding or redirection on backend settings like this:

redirect scheme https if !{ ssl_fc }

And typical redirection (in my case to Varnish port 6081) like this:

server web01 xxx.xxx.xxx.xxx:6081 check

Restart Haproxy and you’re ready to go. One more thing to keep in mind is to renew certificate every three months, which you can automate with simple shell script and crontab.

Leave a Reply

Your email address will not be published. Required fields are marked *