You want a valid HTTPS certificate for a service that nobody on the internet should reach. DNS-01 proves you own the domain without opening a single port.
The short answer
The DNS-01 challenge is a way to prove control of a domain name in ACME, the protocol Let's Encrypt and other certificate authorities use to issue certificates automatically (RFC 8555) [1]. Your ACME client places a TXT record at _acme-challenge.<your domain>, and the certificate authority looks it up in the public DNS [1][2]. Of Let's Encrypt's challenge types HTTP-01, DNS-01 and TLS-ALPN-01, only DNS-01 can be used for wildcard certificates, and it also works for names whose web servers are not exposed to the internet [2]. Our assessment: DNS-01 is the right choice for internal services in a homelab, as long as you protect the DNS API key that comes with it.
How it works
- The record name. The client builds the validation name by prepending the label
_acme-challengeto the domain being validated [1]. - The record value. The value is derived from the token the certificate authority hands out and from your ACME account key; RFC 8555 defines it as the base64url-encoded SHA-256 digest of this "key authorization" [1][2].
- The check. Once the client reports that the record is ready, Let's Encrypt queries the DNS for it; if it finds a match, issuance can proceed [2]. Several TXT records under the same name are allowed, for example when a wildcard and a normal name are validated together, but old ones should be cleaned up, because Let's Encrypt rejects responses that grow too large [2].
- Automation needs an API. Let's Encrypt says DNS-01 only makes sense if your DNS provider has an API to automate updates, and that a client without a propagation check should wait long enough, often as much as an hour, before it triggers validation [2].
- The key is the risk. Putting full DNS API credentials on a web server significantly increases the damage if that server is hacked. Let's Encrypt recommends narrowly scoped credentials, or running validation on a separate machine and copying certificates over [2].
- Delegation helps. Let's Encrypt follows CNAME and NS records for DNS-01, so you can point
_acme-challengeto a separate zone that only serves validation [2]. - Locking it down further. A CAA record names the certificate authorities that may issue for your domain; with the
validationmethodsparameter you can restrict Let's Encrypt to, for example,dns-01[3][4].
A practical example
You want nas.example.com with a valid certificate on your home network, without forwarding port 80. Your ACME client (in a reverse proxy or a standalone tool) gets an API token that may only edit TXT records in your zone, creates the challenge record and waits for propagation. While it waits, you can check what public DNS returns:
dig +short TXT _acme-challenge.nas.example.comIf the answer shows the expected value, validation can succeed [1][2]. Afterwards, a CAA record such as example.com. CAA 0 issue "letsencrypt.org; validationmethods=dns-01" restricts issuance to that method [3]. The name nas.example.com is a made-up example, not one of our hosts.
Checklist
- Check that your DNS provider offers an API before you choose DNS-01 [2].
- Create an API token with the narrowest rights your provider allows, and never store it in a repository [2].
- Delegate
_acme-challengewith CNAME to a separate zone if your provider cannot scope tokens [2]. - Allow enough propagation time in your client before it triggers validation [2].
- Clean up old
_acme-challengeTXT records [2]. - Add a CAA record that names your certificate authority and, if you like, the validation method [3][4].