2020-11-04T16:03:03

Wildcard SSL Certificate from Let's Encrypt using certbot

Just spent a while on configuring certbot to validate wildcard certificate for 31415.eu domain.

Short intro → 31415.eu is by now 9 years old project of mine to allow for (nearly) number only paste-bin links. You can go there, paste text or a link and you'll get a numeric link, like for example 31415.eu/12345.

Why wildcard SSL certificate? Because it allows for hostnames-only links, like for example 12345.31415.eu, via secure https connection.

certbot

Here the certbot command to request Wildcard certificate using certbot command:

certbot certonly --cert-name 31415.eu -d 31415.eu -d *.31415.eu --preferred-challenges=dns --manual --manual-auth-hook /etc/letsencrypt/scripts/dns_update.sh --manual-cleanup-hook /etc/letsencrypt/scripts/dns_cleanup.sh --server https://acme-v02.api.letsencrypt.org/directory --agree-tos

The trick here are --manual-auth-hook and --manual-cleanup-hook scripts.

/etc/letsencrypt/scripts/dns_update.sh
certbot sets two ENV variables and executes it and script must set/add TXT record for _acme-challenge subdomain of CERTBOT_DOMAIN. Here example:

# CERTBOT_DOMAIN=31415.eu CERTBOT_VALIDATION=blahX /etc/letsencrypt/scripts/dns_update.sh
# CERTBOT_DOMAIN=31415.eu CERTBOT_VALIDATION=blahY /etc/letsencrypt/scripts/dns_update.sh
# host -t txt _acme-challenge.31415.eu ns2.meon.eu.
Using domain server:
Name: ns2.meon.eu.
Address: 116.203.6.179#53
Aliases:

_acme-challenge.31415.eu descriptive text "blahY"
_acme-challenge.31415.eu descriptive text "blahX"

Here my version of it:

#!/usr/bin/env bash

set -e
set -u
set -o pipefail

NSUPDATE="nsupdate -v -k /etc/letsencrypt/keys-dns/Kddns_31415_eu_update.+157+21083.key"
DNSSERVER="master-dns.meon.eu"
TTL=60

printf "server %s\nzone _acme-challenge.%s\nupdate add _acme-challenge.%s. %d in TXT \"%s\"\nsend\n" "${DNSSERVER}" "${CERTBOT_DOMAIN}" "${CERTBOT_DOMAIN}" "${TTL}" "${CERTBOT_VALIDATION}" | $NSUPDATE

sleep 3

exit 0

/etc/letsencrypt/scripts/dns_cleanup.sh
certbot sets one ENV variable and executes it and script must delete TXT record for _acme-challenge subdomain of CERTBOT_DOMAIN. Here example:

# CERTBOT_DOMAIN=31415.eu /etc/letsencrypt/scripts/dns_cleanup.sh
# host -t txt _acme-challenge.31415.eu ns2.meon.eu.
Using domain server:
Name: ns2.meon.eu.
Address: 116.203.6.179#53
Aliases:

_acme-challenge.31415.eu has no TXT record

Here my version of it:

#!/usr/bin/env bash

set -e
set -u
set -o pipefail

NSUPDATE="nsupdate -v -k /etc/letsencrypt/keys-dns/Kddns_31415_eu_update.+157+21083.key"
DNSSERVER="master-dns.meon.eu"
TTL=60

printf "server %s\nzone _acme-challenge.%s\nupdate del _acme-challenge.%s. TXT\nsend\n" "${DNSSERVER}" "${CERTBOT_DOMAIN}" "${CERTBOT_DOMAIN}" | $NSUPDATE

exit 0

bind

/etc/bind/named.conf.local
needs _acme-challenge.31415.eu zone to be dynamically configured, has to have check-names ignore; set (because of RFC non-conforming underscore in hostname name) and allow-update with a key:

include "/etc/bind/ddns_31415_eu.key";
zone "_acme-challenge.31415.eu" {
        type master;
        file "/var/cache/bind/db._acme-challenge.31415.eu";
        allow-update { key DDNS_31415_EU_UPDATE; };
        check-names ignore;
};