## certbot and tinydns

Let's Encrypt now supports wildcard certificates. To confirm DNS control, they support several different DNS providers and dynamic DNS protocols, but they don't yet have a plugin for tinydns by DJ Bernstein.

Luckily, the excellent designs of both certbot and tinydns make it very easy to support on your own.

One of the great virtues of tinydns is that its zone file is a flat line-oriented text file. Part of my zone for this domain looks like this:

.fugue88.ws:72.250.210.18:a
.fugue88.ws:72.250.210.18:b
=fugue88.ws:72.250.210.18
@fugue88.ws:72.250.210.18:fugue88.ws
+blog.fugue88.ws:72.250.210.18
+www.fugue88.ws:72.250.210.18


The first character on the line determines the type of DNS record being described, and it's all detailed in the tinydns-data man page.

In order to authenticate your domain, Let's Encrypt really just needs to see a TXT record in the zone. The DNS plugins can interact with many popular DNS providers, but for tinydns, we'll use manual mode with its auth and cleanup hooks. For this, certbot needs to be invoked like this:

certbot certonly -n --preferred-challenges dns --manual \
--manual-public-ip-logging-ok \
--manual-auth-hook /etc/letsencrypt/auth.sh \
--manual-cleanup-hook /etc/letsencrypt/cleanup.sh \
-d fugue88.ws -d *.fugue88.ws


Note that I'm asking for a certificate covering my top-level domain along with all subdomains.

Once certbot finds out the secret value to be stored in your zone, it calls the auth hook, using environment variables to pass the domain in CERTBOT_DOMAIN and the validation token in CERTBOT_VALIDATION.

The validation token needs to appear as the TXT value for the _acme-challenge subdomain.

My auth script writes the TXT record (along with some markers) to tinydns's data file, then runs make to compile the critbit tree and atomically load it into the running server:

#!/bin/bash

cd /service/tinydns-public/root

cat <<EOF >> data
# BEGIN CERTBOT AUTH
'_acme-challenge.$CERTBOT_DOMAIN:$CERTBOT_VALIDATION
# END CERTBOT AUTH
EOF

export -n CERTBOT_VALIDATION

make


The script also un-exports CERTBOT_VALIDATION to avoid leaking sensitive data to children processes.

Once Let's Encrypt has verified the domain, certbot will call the cleanup script. Mine simply removes the TXT record by using the marker lines:

#!/bin/bash

cd /service/tinydns-public/root

sed -ri '/^# BEGIN CERTBOT AUTH$/,/^# END CERTBOT AUTH$/d' data

make


At this point, there should be a new certificate & key sitting in the /etc/letsencrypt/live hierarchy.

Gladly, the certbot authors have that covered. The renewal config for the certificate includes the auth and cleanup hooks to run, so your DNS-verified wildcard certs will renew as part of your renewal cron job as easily as any other certbot certificates!

Feel free to use and distribute these auth and cleanup scripts.