I recently became aware that ACME DNS validation can be accomplished via proxy. By proxy, I mean you can update the DNS records of another domain, not the domain for which the certificate is being issued.
Why would you do this (as taken from acme.sh DNS Alias Mode):
- Your DNS provider does not provide API access; you can’t update the domain easily.
- You are concerned about the security implications. That is, a third-party applications can manipulate the DNS of your main domain.
My goal lies in the security implications. At present, the updates I allow acme.sh to perform are tightly restricted to TXT records only.
Now I’d like to tie that down even more.
There is another side effect of this change: less DNS churn. Sure, it only happens every 60 days, but it is churn. Now that churn can be restricted to one domain.
All my DNS changes are recorded to a repo. If required, I can review DNS changes via the repo.
Some anticipated side effects of moving all DNS challenge changes to one domain:
- If I want to check changes to a domain, I also need to look in another domain.
- All Let’s Encrypt domain changes are in one domain, so I can quickly find them all.
- Less churn on the other domains.
- More churn on that one auth domain.
In my case, I have multiple domains. Instead of allowing acme.sh to access each one of my domains, I could restrict it to a single domain, such as example.org. You could also restrict it a sub-domain, or create a register a new domain, just for DNS auth.
Delegation required for each domain
This example assumes you are using example.org to do your DNS auth.
Delegation is easy. For langille.org, I would add this CNAME to that domain:
_acme-challenge.langille.org 600 CNAME _acme-challenge.example.org.
Changes to the issue process
I am sure this applies to the renewal process as well, but I have now gotten that far yet.
You need to add –challenge-alias example.org when you invoke acme.sh.
How this works is straight forward. acme.sh knows to set DNS in the example.org domain, not the langille.org domain, because of the –challenge-alias parameter you supplied.
When Let’s Encrypt checks the TXT record of original domain _acme-challenge.langille.org to validate your domain, because of the CNAME, it goes forward to the aliased domain _acme-challenge.example.org to check.
Even better, a subdomain
You can restrict a DNS key to a specific subdomain, via something like this BIND configuration:
zone "auth.example.org" { type master; file "zones/auth.example.db"; allow-transfer { AllowZoneTransfer; }; update-policy { grant certs.int.example.org zonesub TXT; }; also-notify { SlaveServersToNotify; NonSlavesToNotify; }; };
This restricts the key, specified by certs.int.example.org, to the updates of TXT records within the auth.example.org subdomain. Nothing else.
This is much more tied down / restrictive than my current solution which allows any domain and any TXT record.
If I wanted to try this approach, I would do this instead of the above.
The CNAME:
_acme-challenge.langille.org 600 CNAME _acme-challenge.auth.example.org.
When invoking acme.sh, use this –challenge-alias auth.example.org.
A domain dedicated to DNS auth
This section covers my thoughts about benefits and changes to risk should I choose to use one domain, either an existing domain, or a new domain.
Restricting a DNS auth key to only TXT records is a good start. There are some TXT records which are important, but they won’t cripple the domain. Other TXT records are used for KeyBase, SPF, or DMARC, for example. While annoying if removed, the main function of the domain will persist.
What benefit would I have to moving DNS auth to another domain?
- Less DNS configuration – I do not have to specify a DNS key for DNS auth on every domain
- A slightly smaller attack vector – if the 3rd party applications are compromised, they have the keys to TXT records in only one domain
The use of one domain or many for DNS auth does not affect the level of risk of malicious certificates. When the DNS key is compromised, they can do anything they want with it, with respect to TXT records.
I could buy another domain, and use it only for DNS auth. That domain would have no other use. I like that approach, if only making all other domains equal. That is, all my other domains have specific purposes. This one one would too: DNS auth.
Notes
Please note that the magic here is the use of CNAMES, not any interaction with Let’s Encrypt.
The –challenge-alias parameter is a directive to acme.sh to use a different domain for DNS updates, not something passed on to Let’s Encrypt.