Easy SSL Auto-Renewal via DNS using Certbot with Lexicon

February 9 2018

Certbot, the official Let’s Encrypt client, has the unfortunate characteristic of having complicated dependencies and being primarily being distributed through OS repositories.

Since not all in-use versions of all Linux distributions distribute it, EFF helpfully publishes a portable Linux version, certbot-auto. Again unfortunately, there is a long-standing issue that none of the certbot-dns-* plugins are available by default.

Here we’ll avoid the Certbot plugins and instead rely on the more featureful Lexicon to provide the functionality needed to perform DNS validation with Certbot with automatic (non-interactive) renewal.

NB. This page requires JavaScript to function properly.

June 2018 update: Due to outstanding bugs in Lexicon, this may not be a reliable way to do DNS validation. I’ll leave this post up but a number of providers are known to be broken (e.g. Route53).

1. Configure your DNS authenticator

Who is my DNS hosted by? If you’re not sure who hosts your DNS, you will need to find out first. If your DNS host is not listed, I am sorry but Lexicon probably doesn’t support them :(.

We will be creating pre and post-validation hooks for Certbot.

Create /etc/letsencrypt/lexicon-provider_route53.sh with the following contents (you will need root to save this file).

#!/usr/bin/env bash
/opt/eff.org/certbot/venv/bin/pip install dns-lexicon urllib3
/opt/eff.org/certbot/venv/bin/pip install dns-lexicon[route53]
/opt/eff.org/certbot/venv/bin/lexicon route53 \
--auth-access=route53_COMPLETE_ME --auth-token=route53_COMPLETE_ME --auth-username=route53_COMPLETE_ME \
"$1" "${CERTBOT_DOMAIN}" TXT \
--name "_acme-challenge.${CERTBOT_DOMAIN}" \
--content "${CERTBOT_VALIDATION}" || exit 255

if [ "$1" == "create" ]; then
  sleep 30
fi

Replace all route53_COMPLETE_ME in the above file with your API credentials for route53. If you don’t know what these are, you need to search on the web or contact the DNS host. They will usually either be your login details or dedicated API credentials from inside the DNS host’s control panel.

Protect your authentication hooks:

sudo chown root:root /etc/letsencrypt/lexicon-*.sh
sudo chmod 0700 /etc/letsencrypt/lexicon-*.sh

2. Issue your SSL certificate

You can now try issue your certificate via Certbot, the usual ways.

certonly

If you only want a certificate without Certbot altering your webserver configuration, you can run it in certonly mode:

sudo ./certbot-auto certonly --manual \
--manual-public-ip-logging-ok \
--manual-auth-hook "/etc/letsencrypt/lexicon-provider_route53.sh create" \
--manual-cleanup-hook "/etc/letsencrypt/lexicon-provider_route53.sh delete" \
--preferred-challenges dns \
-d example.org -d www.example.org

Apache or nginx

(Replace --installer apache with --installer nginx as required).

sudo ./certbot-auto --authenticator manual \
--installer apache \
--manual-public-ip-logging-ok \
--manual-auth-hook "/etc/letsencrypt/lexicon-provider_route53.sh create" \
--manual-cleanup-hook "/etc/letsencrypt/lexicon-provider_route53.sh delete" \
--preferred-challenges dns \
-d example.org -d www.example.org

Closing Notes

You are done! Unlike in the scenario of completing the DNS challenge manually, Certbot will be able to preform automatic renewals.

You may need to increase or decrease the duration of the 30 second sleep in the authenticator script. This is due to variance between DNS hosts on how long it takes for DNS changes to become available throughout their DNS clusters. For example, Linode can take a very long time.

You can also make this a bit shorter by just passing the entire Lexicon command line as the --manual-auth-hook flag to Certbot and avoid creating a separate hook file, however that is avoided here to try draw a clear (newbie-friendly) delination between components here.

If you need help, please ask on the Let’s Encrypt Community forums :) !