Let's Encrypt with Hitch and Varnish (CentOS7) Tutorial

Introduction

In their own words “Let’s Encrypt is a free, automated, and open Certificate Authority. Using the Let’s Encrypt services lets anyone acquire valid certificates for TLS/SSL encryption for free.”

In this tutorial, we will show you how to use the official certbot tool to obtain a free Let’s Encrypt TLS certificate and use it with Hitch and Varnish.

Prerequisites

In order to complete this guide, you will need a couple of things:

  • You should have a Linux based server, with either a privileged account, or an account with sudo capabilities. This guide will describe the process on a CentOS7/Red Hat EL7 based system, using sudo.

  • You must own or control a registered domain name that you wish to use the certificate with. If you do not yet own a domain name, please take a moment to acquire one from one of the many available registrars. (See Icann.org for an exhaustive list.)

When you are in control of a domain name, create an A-record with the name of the domain that points to the public IP-address of the host you are setting up. The following guide assumes that this A-record is set up and working, as the way the certificates are acquired relies on this for validation of domain name ownership.

In this guide we will use example.com as the domain name, and we will have set up both example.com and www.example.com to point to our hosts public IP-address.

Once you have the prerequisites in order, proceed to the actual software setup.

Step 1 - Install Hitch and Varnish

We need to install EPEL (Extra Packages for Enterprise Linux) in order to get both certbot and hitch. Installing EPEL should be as easy as installing the epel-release package:

sudo yum install epel-release

We then install Varnish Cache 4.1 from the official Varnish Cache repository. If you prefer a manual repository setup over the script based one, follow the guide over on Packagecloud.io.

curl -s https://packagecloud.io/install/repositories/varnishcache/varnish41/script.rpm.sh | sudo bash
sudo yum install hitch varnish

For Varnish Plus customers, install varnish-plus and varnish-plus-addon-ssl instead. This requires the plus-repositories to be set up in advance:

sudo yum install varnish-plus varnish-plus-addon-ssl

Step 2 - Add certbot passthrough VCL

With either Varnish Cache or Varnish Cache Plus installed, we will now set up Varnish VCL to pass all incoming certificate server challenge requests through to certbot. This is done by routing all urls matching the acme-challenge pattern to the certbot listener.

Create a new file /etc/varnish/letsencrypt.vcl with your favourite editor, and add this configuration to it:

backend certbot {
    .host = "127.0.0.1";
    .port = "888";
}

sub vcl_recv {
    if (req.url ~ "^/\.well-known/acme-challenge/") {
        set req.backend_hint = certbot;
        return(pipe);
    }
}

sub vcl_pipe {
    if (req.backend_hint == certbot) {
        set req.http.Connection = "close";
        return(pipe);
    }
}

Then include the newly created letsencrypt.vcl file in your main VCL, by adding this include statement right after the vcl 4.0; line in /etc/varnish/default.vcl:

include "/etc/varnish/letsencrypt.vcl";

Note that if running Varnish in a load balanced cluster, the certbot backend definition should point to the master certbot node and certificates need to be copied back around the cluster after renewal and hitch reloaded.

Step 3 - Configure and start Varnish

By default Varnish listens to port 6081, but in order to accept the challenge request from the Let’s Encrypt system, we will make it listen to port 80. We will also add a PROXY listening port on 6086, to receive requests passed from Hitch.

Edit /etc/varnish/varnish.params with your editor, and change these two lines in the file to match the below:

VARNISH_LISTEN_PORT=80

DAEMON_OPTS="-a '[127.0.0.1]:6086,PROXY' -p vsl_reclen=4084"

If your server has SELinux enabled, you will also need to add port 6086 to allowed ports for the Varnish daemon. Using semanage you can do this:

sudo semanage port -a -t varnishd_port_t -p tcp 6086

We’re now ready to start the Varnish daemon:

sudo systemctl enable varnish
sudo systemctl start varnish

Step 4 - Prepare hitch

To make the certificate installs with hitch easier, we will add a small script to act as a renewal hook. Create a new file /usr/local/bin/hitch-renew-hook with your editor and paste this into it:

#!/bin/bash
# Full path to pre-generated Diffie Hellman Parameters file
dhparams=/etc/hitch/dhparams.pem

if [[ "${RENEWED_LINEAGE}" == "" ]]; then
    echo "Error: missing RENEWED_LINEAGE env variable." >&2
    exit 1
fi

umask 077
cat ${RENEWED_LINEAGE}/privkey.pem \
${RENEWED_LINEAGE}/fullchain.pem \
${dhparams} > ${RENEWED_LINEAGE}/hitch-bundle.pem

Make the script executable:

sudo chmod a+x /usr/local/bin/hitch-renew-hook

In order to enable Perfect Forward Secrecy, we need to create a Diffie Hellman Parameter file that Hitch will use, this is done using openssl:

openssl dhparam -rand - 2048 | sudo tee /etc/hitch/dhparams.pem

Before actually starting hitch we need to enable the systemd service:

sudo systemctl enable hitch

Step 5 - Install and run certbot

The certbot client is installable through the EPEL repository we have already configured, so install it via yum:

sudo yum install certbot

Now we have everything in place to request a certificate from Let’s Encrypt. Use this certbot command to request a certificate:

sudo certbot certonly --standalone --preferred-challenges http \
--http-01-port 888 -d example.com -d www.example.com \
--renew-hook="/usr/local/bin/hitch-renew-hook" \
--post-hook="service hitch reload"

The first time you use certbot, it will ask for your email address and for you to accept the Terms of Service. Once those questions are answered, the certificate will be obtained after the challenges are completed.

We also need to start the certbot-renew service and timer, which handles automatic certificate renewals once per day:

sudo systemctl enable certbot-renew
sudo systemctl enable certbot-renew.timer
sudo systemctl start certbot-renew
sudo systemctl start certbot-renew.timer

Step 6 - Start hitch

You should now have a hitch bundle consisting of the private key, the CA chain and the pregenerated Diffie Hellman parameter file. Add the resulting pem-file to your /etc/hitch/hitch.conf using your editor:

pem-file = "/etc/letsencrypt/live/example.com/hitch-bundle.pem"

Now we can start the hitch daemon:

sudo systemctl start hitch

Conclusion

Hitch should start and if you open a browser to the configured hostname you should see that the connection is successfully encrypted using TLS. The certbot renewal process will ensure your certificates are automatically updated, and that hitch is reloaded whenever a new certificate is fetched.