Certain use cases preclude DNS dynamic updates to a zone for technical, policy or other reasons. This post explains a simple way to enable automatic DNS-based authorization for Let’s Encrypt certificates – and perhaps for other vendors’ – by way of delegating the authorization challenge to a trusted DNS zone.
In the example below, we want to automatically issue or renew a wildcard certificate for athena.pics
but unfortunately no dynamic updates can be made under that domain. If you want to request wildcard certificates with Let’s Encrypt, this obstacle will need addressing.
By provisioning a simple CNAME
record pointing to a domain name where dynamic updates can be made, the dns-01
authentication can complete and the certificate can be issued or renewed automatically.
The CNAME
record can be added at any time, and left there for as long as desired. For our example, athena.pics
will trust proxy.lem.click
for its ACME authorizations. The new DNS record would look like this, in the athena.pics
DNS zone:
$ORIGIN athena.pics.
_acme-challenge.athena.pics. 60 IN CNAME _acme-challenge.proxy.lem.click.
This is an explicit trust relationship. Anyone with the ability to add records to
_acme-challenge.proxy.lem.click
will be able to request certificates on behalf ofathena.pics
.
With this CNAME
record in place, requesting the TXT
record through your plain old resolver will ultimately fetch the TXT
records that would complete the authorization. All you need to do is add the TXT
record with the authorization challenge under _acme-challenge.proxy.lem.click
. The example below uses dynamic updates to accomplish this:
nsupdate -k ~/mykey.conf
> update add _acme-challenge.proxy.lem.click. 1 IN TXT your-challenge-here
> send
> ^D
Querying a recursive resolver would now show the TXT
record we added in the previous step because the CNAME
will be traversed:
dig txt _acme-challenge.athena.pics @8.8.8.8
⋮
;; ANSWER SECTION:
_acme-challenge.athena.pics. 0 IN CNAME _acme-challenge.proxy.lem.click.
_acme-challenge.proxy.lem.click. 0 IN TXT "your-challenge-here"
⋮
Let’s Encrypt will perform a similar lookup, ultimately finding the challenges at the expected location.
The latest version of my nsupdate-hook script makes this process easy. For the example above to work, all you would need to do is set CHALLENGE_DOMAIN
to proxy.lem.click
in your shell or crontab
file.