Let’s Encrypt wildcard certificates without DNS API

For a long time, I wanted to use a Let’s Encrypt (LE) wildcard certificate for *.jay2k1.com, but my domain and DNS provider does not offer a DNS API, and I did not want to manually change a DNS TXT record every 2-3 months. So I kept using a single certificate that contained all my subdomains. Until I found a solution to this problem.

The solution

Enter Agnos. The idea is brilliantly simple:

  • Usually, when you request a wildcard certificate with your ACME client, LE requires a challenge string be set as DNS TXT┬árecord at _acme-challenge.domain.tld. You can either do this by hand or have your ACME client do it via DNS API of your DNS provider.
  • Instead, to use Agnos, you create an NS record called _acme-challenge.domain.tld pointing to e.g. yourserver.yourdomain.com (and if you don’t yet have one, an A or AAAA record for that, pointing to the IP of your server).
  • You configure your wildcard domain and LE account in the Agnos config file
  • When you run Agnos, it will request the certificate from LE, LE will check _acme-challenge.domain.tld, see the NS entry and subsequently ask your server for this TXT record. Agnos has a small built-in DNS server listening to this exact query, and it will answer LE’s request. And boom, Agnos receives the certificate and places it in a location you can specify in the config file.

Of course, you need to have a server (with root access) and open port 53 in your server’s firewall for this to be possible. Agnos itself does not need to be run as root, you can run setcap 'cap_net_bind_service=+ep' agnos to allow it to bind to port 53 when run from an unprivileged user.

Now all you need to do is to create a cron job that runs agnos every so often, e.g. for twice per day with a random delay of up to 12 hours:

0 */12 * * * youruser test -x /opt/agnos/agnos && perl -e 'sleep int(rand(43200))' && /opt/agnos/agnos /opt/agnos/config.toml --no-staging && systemctl reload apache2

Just change the user name and – if necessary – the webserver reload command.

You do not need a DNS API, you do not need to store DNS API credentials on your server, and you do not need to worry about TTLs or propagation times.

Using an existing LE account

Agnos can be run with your existing account that you already use with, say, certbot. I found that my account’s email address is stored in /etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory/<uid>/regr.json and my private key in /etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory/<uid>/private_key.json. I had to transform that JSON key into a different format for it to work using the instructions here to do it with python.

Leave a Reply

Your email address will not be published. Required fields are marked *