Let’s Encrypt wildcard domains with DNS challenge and Alpine Linux

Let’s Encrypt wildcard domains with DNS challenge and Alpine Linux

The Let’s Encrypt http challenge relies on three servers being able to reach you. One is primary, two are secondary, for the challenge to succeed the primary server must be able to reach you. For some reason the secondary servers could reach me, but the primary couldn’t. We tried everything, everyone on the Let’s Encrypt forum could reach me and port scan me, I could traceroute and ping the Let’s Encrypt servers from my VPS, but the primary server couldn’t reach me back.

Enter the DNS challenge, this is useful if you want wildcard domains (*.catona.cloud) or if the servers aren’t easily reachable, they could be behind a load balancer, on a private test network or affected by a mysterious disease. The first time it requires you to manually set a CNAME record on your registrar but after that certbot renew just works. Here is how it’s done:

apk add certbot

curl -o /etc/letsencrypt/acme-dns-auth.py \
https://raw.githubusercontent.com/joohoi/acme-dns-certbot-joohoi\
/master/acme-dns-auth.py

chmod 0700 /etc/letsencrypt/acme-dns-auth.py

certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py \
--preferred-challenges dns --debug-challenges \
-d \*.catona.cloud -d catona.cloud

It will ask you to set the CNAME record and wait until you press enter, don’t press enter until the record has propagated. You are throttled to 5 attempts per hour, use a tool like mxtoolbox to watch the records. The first time I mistakenly copy pasted the entire domain _acme-challenge.catona.cloud on my registrars UI, resulting in _acme-challenge.catona.cloud.catona.cloud.

If you did something wrong and want to start again simply delete /etc/letsencrypt/acmedns.json and the associated keys under /etc/letsencrypt/{csr,keys}/.

After pressing enter everything should just work, but you still need to setup nginx with SSL and automate certificate renewal.

Sample /etc/nginx/http.d/catona.cloud.conf partially copied from here:

server {
    listen 80;
    root /var/www/catona.cloud/html;
    index index.html;
    server_name catona.cloud www.catona.cloud;
		
    # Rewrite all nonssl requests to ssl
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_certificate /etc/letsencrypt/live/catona.cloud/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/catona.cloud/privkey.pem;

    server_name catona.cloud www.catona.cloud;

    location / {
        root  /var/www/catona.cloud/html;
        index  index.html;
    }
}

Test the config with nginx -t and restart the service rc-service nginx restart.

Now to automate renewal, on Alpine open /etc/periodic/weekly and add:

# Run certbot every Sunday midnight
0 0 * * 0 /usr/bin/certbot renew

Restart crond with rc-service crond restart.

That’s it, you now have https on the wildcard domain *.example.com and example.com.

References:

  1. The certbot DNS challenge instructions were partially copied from cloudness.net, there wasn’t an obvious place to insert the link.