How it used to be...

Initially, I started with CAs that offer "per subdomain" certificates, which was a start. Plus I didn't have any actual needs for certificates by the time, just started entering the SSL/TLS world as I got frustrated by the network transparency which was HUGE back then. Most websites were still not using HTTPS and this was definitely a problem that wasn't taken seriously enough. So, CAs... There wasn't much of a choice when it came to free certificates, which would also be trusted by default. I'm not going to elaborete more on that as this is not the case anymore, so let's move on. I mentioned earlier "per subdomain" certificates which basically boils down to a pair of files (certificate & key) for each subdomain. When you don't care much about subdomains and you just want to use "domain.ltd" or "www.domain.ltd", then it makes sense that this should be suitable for you. However, as we learn more about security and how benificial it is to setup well-known services such as a Mail Server (SMTP), a private cloud to sync data from everywhere and everything, etc, then it makes sense that you may want more than just one or two subdomains for your setup.

Wildcard certs and why should I care

So now that we know/want more from our domain and we want to self-host/self-service it on our own, then wildcard certificates are definitely something worth having. Wildcard certificates are basically just like any other certificate, but with one important difference. They can have a "Subject Alternative Name", which basically means what subdomains/domains it's been issued for. Having one could spare you lots of maintenance tasks and configuration issues. Since Let's Encrypt started offering wildcard certificates, I simply coulnd't resist to try it out, without waiting for the feature to reach maturity, as it was still considered (and most likely still is) experimental. To issue a certificate through their services, you would be most-likely be using the well-known utility "certbot", which by now it should be present in every Linux distro or BSD OS. The default validation is done via HTTP, using the ACME v1 protocol. Wildcard certificates can only be aqcuired by using a DNS validation (challenge), which is basically a DNS TXT record that has to be included in the domain zone file and checked/validated only once for the entire process. That and it also requires the ACME v2 protocol. The next renewal will require a new TXT record one would need to overwrite manually every single time. I thought that this definitely could be automated, but by the time I lacked knowledge to do it. Now that we're here, I obviously learned a few things that lead me to a successful wildcard renewal process - using Let's Encrypt's certbot tool and certbot's plugin for rfc2136.

My setup

OS: Arch Linux
Packages:

  • certbot
  • certbot-dns-rfc2136
  • bind
  • bind-tools

Configure BIND

In my previous configuration, all updates were disabled. We have to enable dynamic updates (rfc2136) in our configuration in order to allow updating BIND with new TXT challenges. But before doing that, we would need to generate a TSIG (Transaction Signature). You can do this with an unprivileged user:

$ tsig-keygen -a HMAC-SHA512 smirky-key

key "smirky-key" {
        algorithm hmac-sha512;
        secret "b99cQn3nwxWVJZt8HWRTiGGWOWRBRL136RGyEt1WkPw1Cmomb3cbswSqtTBCB3eiS/Gfnd9/oGMqS/rhr87L/w==";
};

Generate your own key and DO NOT use the example one - you have been warned! Place it in /etc/named.conf and adjust the configuration to use it:

zone "smirky.net" IN {
        ...
        // this is for certbot
        update-policy {
                grant smirky-key name _acme-challenge.smirky.net. txt;
        };
        ...
};

key "smirky-key" {
        algorithm hmac-sha512;
        secret "b99cQn3nwxWVJZt8HWRTiGGWOWRBRL136RGyEt1WkPw1Cmomb3cbswSqtTBCB3eiS/Gfnd9/oGMqS/rhr87L/w==";
};

Restart BIND:

# systemctl restart named

Configure certbot

You need to create a configuration file for the rfc2136 plugin. Since we're going to copy the secret key in it, we need to secure it too. Go to /etc/letsencrypt and create rfc2136.ini with the following content:

dns_rfc2136_server = IP.ADD.RE.SS
dns_rfc2136_name = smirky-key
dns_rfc2136_secret = b99cQn3nwxWVJZt8HWRTiGGWOWRBRL136RGyEt1WkPw1Cmomb3cbswSqtTBCB3eiS/Gfnd9/oGMqS/rhr87L/w==
dns_rfc2136_algorithm = HMAC-SHA512

Secure it:
# chmod 600 /etc/letsencrypt/rfc2136.ini

Test what we did

# certbot certonly --dns-rfc2136 --force-renewal --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.ini --server https://acme-v02.api.letsencrypt.org/directory --email smirky@smirky.net --agree-tos --no-eff-email -d smirky.net -d '*.smirky.net'

If you authenticate successfully and receive certificates, then you're good to go with the last step. Otherwise, something went wrong and you need to debug your setup.

We want AUTORENEW !

It basically boils down to executing certbot renew from now on. Everybody can choose how and how often to do it. For my system, I'm using a systemd timer and a systemd service file, as per the Arch Linux Wiki recommendation. It's checking twice a day and upon renewal, eventually it reloads particular services to make sure they are using the latest issued wildcard certificate.

# cat /etc/systemd/system/certbot.timer

[Unit]
Description=Twice daily renewal of Let's Encrypt's certificates

[Timer]
OnCalendar=0/12:00:00
RandomizedDelaySec=1h
Persistent=true

[Install]
WantedBy=timers.target

# cat /etc/systemd/system/certbot.service

[Unit]
Description=Let's Encrypt renewal

[Service]
Type=oneshot
ExecStartPost=/bin/systemctl reload postfix.service dovecot.service nginx.service # optional
ExecStart=/usr/bin/certbot renew --quiet --agree-tos

"Do the needful", as I often hear from some people:
# service daemon-reload
# service enable certbot.timer
# service start certbot.timer

Add a comment