Using a Let’s Encrypt Wildcard Certificate with macchina.io REMOTE

For running the macchina.io REMOTE server (also known as reflector server), a wildcard certificate is required. Wildcard certificates have become quite expensive recently. While it was possible to buy one for about 250 $, minimum prices seem to have doubled in recent months. However, it’s not necessary to buy a wildcard certificate. A free wildcard certificate from Let’s Encrypt works perfectly fine.

However, a bit of set-up work is required in order to obtain and automatically renew wildcard certificates from Let’s Encrypt. The issue with Let’s Encrypt wildcard certificates is that issuing them requires proof of domain ownership via a DNS challenge (this method is known as DNS-01 challenge). This involves creating a TXT entry in the DNS zone for the wildcard domain, which is then checked by the Let’s Encrypt backend. Fortunately, Certbot supports a number of plugins for dealing with the APIs of different DNS providers to automate this process. 

The following instructions are therefore based on Route 53, the DNS service offered by AWS. With a different DNS provider, the steps will be slightly different.  

Apart from using Route 53 for DNS, the following prerequisites must be met:

  • The macchina.io REMOTE server runs on Ubuntu 18.04 or 20.04
  • HAProxy is used for TLS termination

Create an IAM user for Certbot

This first step is specific to AWS Route 53. The goal is to create an API account that can be used by the certbot-dns-route53 plugin to update the TXT entry for the DNS zone. Note that the account must be created in IAM (AWS Identity and Access Management), not in the organization, and must be created for API access, not interactive use. The account’s permissions should be restricted with a policy. The certbot-dns-route53 documentation has a description of the required permissions, and an example policy, which should look like this:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "route53:ChangeResourceRecordSets",
"Resource": [
"arn:aws:route53:::hostedzone/<your_zone_id>"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"route53:GetChange",
"route53:ListHostedZones"
],
"Resource": "*"
}
]
}

After creating the user and assigning the policy, note the access key and secret.

Configure Certbot and the Route 53 Plugin

After creating the new IAM user, on the Ubuntu system running the macchina.io REMOTE server, create a new configuration file containing the AWS credentials for the newly created user.

$ sudo mkdir /root/.aws

$ sudo vi /root/.aws/config

The configuration file should contain the access key and secret access key and look like:

[default]
aws_access_key_id=<your_access_key>
aws_secret_access_key=<your_secret_access_key>

Installing Certbot and the Route 53 Plugin

Run the following commands to install Certbot:

$ sudo snap install core; sudo snap refresh core; sudo snap install --classic certbot

Then, install the plugin:

$ sudo snap set certbot trust-plugin-with-root=ok 

$ sudo snap install --beta certbot-dns-route53

$ sudo snap connect certbot:plugin certbot-dns-route53

Passing the Certificate and Private Key to HAProxy

Certbot will obtain a private key and certificate and store both in separate files in /etc/letsencrypt/live/<your_domain>/privkey.pem and /etc/letsencrypt.live/<your_domain>fullchain.pem.

However, HAProxy expects both the certificate and the private key in a single file. Furthermore, after automatically renewing the certificate, HAProxy must be reconfigured to load the new certificates. This can be handled via a renew hook script. The script looks as follows:

#! /bin/bash
# Certbot post-renew hook for HAProxy

cat /etc/letsencrypt/live/<your_domain>/fullchain.pem >/etc/haproxy/reflector.pem
cat /etc/letsencrypt/live/<your_domain>/privkey.pem >>/etc/haproxy/reflector.pem
/etc/init.d/haproxy reload

It copies the certificate chain and the private key into a single file (/etc/haproxy/reflector.pem), then tells HAProxy to reload its configuration. Store the script in a suitable location (e.g., /etc/haproxy/certbot-renew-hook.sh) and make it executable.

Obtaining the Wildcard Certificate

The final step is to initially obtain the wildcard certificate.

$ sudo bash

# export AWS_CONFIG_FILE=/root/.aws/config

# certbot certonly --dns-route53 -d '*.my-devices.net' --post-hook /etc/haproxy/certbot-renew-hook.sh

If all goes well (obtaining the certificate may take a couple of seconds), HAProxy should then run with the Let’s Encrypt wildcard certificate. Furthermore, the certificate should be renewed automatically.

 

Tagged ,