Cluster, Part 12: TLS for Breakfast | Configuring Fabio for HTTPS
Hey there, and happy new year 2022! It's been a little while, but I'm back now with another blog post in my cluster series. In this shorter post, I'm going to show you how I've configured my Fabio load balancer to serve HTTPS.
Before we get started though, I can recommend visiting the series list to check out all the previous parts in this series, as a number of them give useful context for this post.
In the last post, I showed you how to setup certbot / let's encrypt in a Docker container. Building on this, we can now reconfigure Fabio (which we setup in part 9) to take in the TLS certificates we are now generating. I'll be assuming that the certificates are stored on your NFS share you've got setup (see part 8) for this post. In the future I'd love to use Hashicorp Vault for storing these certificates, but as of now I've found Hashicorp Vault to be far too complicated to setup, so I'll be using the filesystem instead.
Configuring Fabio to use HTTPS is actually really quite simple. Open /etc/fabio/fabio.properties
for editing, and at the beginning insert a line like this:
proxy.cs = cs=some_name_here;type=file;cert=/absolute/path/to/fullchain.pem;key=/absolute/path/to/privkey.pem
cs
stands for certificate store, and this tells Fabio about where your certificates are located. some_name_here
is a name you'd like to assign to your certificate store - this is used to reference it elsewhere in the configuration file. /absolute/path/to/fullchain.pem
and /absolute/path/to/privkey.pem
are the absolute paths to the fullchaim.pem
and privkey.pem
files from Let's Encrypt. These can be found in the live
directory in the Let's Encrypt configuration directory in the subdirectory for the domain in question.
Now that Fabio knows about your new certificates, find the line that starts with proxy.addr
. In the last tutorial, we configured this to have a value of :80;proto=http
. proxy.addr
can take a comma-separated list of ports to listen on, so append the following to the existing value:
:443;proto=https;cs=some_name_here;tlsmin=tls12
This tells Fabio to listen on TCP port 443 for HTTPS requests, and also tells it which certificate store to use for encryption. We also set the minimum TLS version supported to TLS 1.2 - but you should set this value to 1 version behind the current latest version (check this page for that). For those who want extra security, you can also add the tlsciphers="CIPHER,LIST"
argument too (see the official documentation for more information - cross referencing it with the ssl-config.mozilla.org is a good idea).
Now that we have this configured, this should be all you need to enable HTTPS! That was easy, right?
We still have little more work to do though to make HTTPS the default and to redirect all HTTP requests to HTTPS. We can do this by adding a route to the Consul key-value store under the path fabio/config
. You can do this either by editing it in the web interface by creating a new key under fabio/config
and pasting the following in & saving it:
route add route_name_here example.com:80 https://example.com$path opts "redirect=308"
Alternatively, through the command line:
consul kv put fabio/config/some_name_here 'route add some_name_here example.com:80 https://example.com$path opts "redirect=308"'
No need to restart fabio - it should pick routes up automatically. I have found however that I do need to restart it occasionally if it doesn't pick up some changed routes as fast as I'd like though.
With this, we now have automatic HTTPS setup and configured! Coming up in this series:
- Using Caddy as an entrypoint for port forwarding on my router (status: implemented; there's an awesome plugin for single sign-on, and it's amazing in other ways too) - this replaces the role HAProxy was going to play that I mentioned in part 11
- Password protecting Docker, Nomad, and Consul (status: on the todo list)
- Semi-automatic docker image rebuilding with Laminar CI (status: implemented)