DNS-01 Challenge
The DNS-01 Challenge validates domain control through a TXT record in DNS, without requiring an accessible web server.
This is the only method that allows generating wildcard certificates (*.domain.com), which automatically work for all subdomains of your domain - whether api.domain.com, blog.domain.com, admin.domain.com, or any other you create in the future.
How does it work?β
Understanding the flow:
The diagram above shows communication between three components: the ACME Client (like Certbot or acme.sh), the Let's Encrypt server, and your domain's DNS Server.
-
Initial request: The ACME client (running on any machine with internet access) requests a certificate for the desired domain
-
DNS challenge: Let's Encrypt responds with a unique token and instructs: "prove you control this domain by creating a specific TXT record"
-
Record creation: The ACME client uses your DNS provider's API (Cloudflare, Route53, etc.) to automatically create the TXT record
_acme-challenge.domain.comwith the received token -
Verification: Let's Encrypt queries public DNS servers to verify the TXT record exists and contains the correct token
-
Issuance: After successful validation, Let's Encrypt issues the certificate and sends it to the ACME client
-
Cleanup: The TXT record can be removed after issuance (the ACME client usually does this automatically)
The ACME client (Certbot) doesn't need to run on the same server as your applications. It only needs:
- Internet access to communicate with Let's Encrypt
- Your DNS provider's API credentials to create/remove TXT records
- A location to save the generated certificates
After issuance, you distribute the certificates to the servers that need them (via rsync, NFS, Kubernetes Secrets, etc.).
DNS record exampleβ
# TXT record that needs to be created
_acme-challenge.domain.com. 300 IN TXT "gfj9Xq...Rg85nM"
When to use DNS-01?β
| Scenario | Why use DNS-01? |
|---|---|
| Wildcard Certificates | Only method that supports *.domain.com |
| Internal servers | Doesn't require public exposure on port 80 |
| Multiple servers | One certificate for several servers |
| Port 80 blocked | Firewall or ISP blocks HTTP |
Automation with DNS Providersβ
The biggest challenge with DNS-01 is automation. Creating TXT records manually doesn't scale. The solution is to use plugins that integrate with your DNS provider's API.
Certbot with DNS pluginsβ
# Cloudflare
sudo apt install python3-certbot-dns-cloudflare
certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d "*.domain.com" -d domain.com
# Route53 (AWS)
sudo apt install python3-certbot-dns-route53
certbot certonly --dns-route53 -d "*.domain.com"
# Google Cloud DNS
sudo apt install python3-certbot-dns-google
certbot certonly --dns-google \
--dns-google-credentials ~/.secrets/google.json \
-d "*.domain.com"
Credentials file (Cloudflare example)β
# ~/.secrets/cloudflare.ini
dns_cloudflare_api_token = your_token_here
# Secure permissions
chmod 600 ~/.secrets/cloudflare.ini
acme.sh (lightweight alternative)β
acme.sh is an ACME client in pure shell script, lighter than Certbot.
# Example: Wildcard certificate with Cloudflare
export CF_Token="your_token"
acme.sh --issue --dns dns_cf -d "*.domain.com" -d domain.com
# Example: Wildcard certificate with AWS Route53
export AWS_ACCESS_KEY_ID="xxx"
export AWS_SECRET_ACCESS_KEY="xxx"
acme.sh --issue --dns dns_aws -d "*.domain.com"
A compromised wildcard certificate affects all subdomains. Consider specific certificates for critical subdomains (api, admin, etc).
DNS Propagationβ
DNS-01 depends on TXT record propagation:
# Check if the record has propagated
dig TXT _acme-challenge.domain.com
# Typical propagation time
# - Cloudflare: seconds
# - Route53: 60 seconds
# - Traditional registrars: up to 48 hours
Scenario: Certbot creates the TXT record and immediately asks Let's Encrypt to verify. But Let's Encrypt queries DNS servers that haven't yet received the update β validation fails.
Solution: Use --dns-cloudflare-propagation-seconds 60 to force Certbot to wait 60 seconds after creating the record before requesting verification. Adjust the value according to your DNS provider.
Advantages and Disadvantagesβ
Advantages:
- Supports wildcard certificates
- Works with internal servers (not exposed to internet)
- Doesn't require port 80 open
- One certificate can serve multiple servers
Disadvantages:
- Requires DNS provider API access
- DNS propagation can take time
- More complex to configure initially
- DNS credentials are sensitive
Distribution to multiple serversβ
When you have multiple machines in separate environments, there are different strategies to distribute certificates:
By increasing complexityβ
| Scenario | Recommended solution |
|---|---|
| Few servers, same network | rsync/scp with cron |
| Multi-cloud or isolated networks | HashiCorp Vault or AWS Secrets Manager |
| Kubernetes | cert-manager (issues directly in cluster) |
| CDN/Load Balancer | Centralized TLS termination |
1. rsync/scp (simple)β
# On server with Certbot, after renewal
certbot renew --deploy-hook "rsync -avz /etc/letsencrypt/ user@server2:/etc/letsencrypt/"
2. HashiCorp Vault (multi-environment)β
# Store certificate in Vault
vault kv put secret/certs/wildcard \
cert=@/etc/letsencrypt/live/domain.com/fullchain.pem \
key=@/etc/letsencrypt/live/domain.com/privkey.pem
# Each server fetches from Vault
vault kv get -field=cert secret/certs/wildcard > /etc/ssl/cert.pem
3. Kubernetes cert-managerβ
For Kubernetes, cert-manager is the standard solution - it issues certificates directly in the cluster:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
4. Centralized TLS terminationβ
The simplest approach for multiple servers: centralize TLS at the load balancer.
Backend servers don't need the certificate - internal communication can be HTTP (in private network) or mTLS.
Supported DNS providersβ
Certbot and acme.sh support various providers:
- Popular: Cloudflare, AWS Route53, Google Cloud DNS, DigitalOcean
- Registrars: GoDaddy, Namecheap, OVH, Gandi
- Others: Azure DNS, Linode, Vultr, DNSimple
Consult the ACME client documentation for the complete list of available plugins.