How to Implement Let’s Encrypt DNS-01 Challenge Validation for Certificate Issuance


4 views

The DNS-01 challenge in Let's Encrypt's ACME protocol allows domain validation by creating a specific TXT record in your DNS zone. This method is particularly useful when:

  • You can't expose HTTP/HTTPS ports (common in internal systems)
  • You want to issue wildcard certificates (*.example.com)
  • You need automation without web server access

Before proceeding, ensure you have:

1. A domain with DNS management access
2. Certbot 0.22.0+ installed
3. API access to your DNS provider (if automating)
4. Proper TXT record propagation time (typically 1-5 minutes)

For manual validation using Certbot:

certbot certonly \
  --manual \
  --preferred-challenges=dns \
  --manual-auth-hook /path/to/auth-hook.sh \
  -d example.com \
  -d *.example.com

Certbot will pause and display the required TXT record:

_acme-challenge.example.com. 300 IN TXT "gfj9Xq...Rg85nM"

For popular DNS providers, use existing plugins:

# For Cloudflare
certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  -d example.com

# For Route53
certbot certonly \
  --dns-route53 \
  -d example.com

For unsupported providers, create an auth hook:

#!/bin/bash
# auth-hook.sh
DOMAIN="_acme-challenge.$CERTBOT_DOMAIN"
TXT_VALUE="$CERTBOT_VALIDATION"

# Use your DNS provider's API to add TXT record
curl -X POST "https://api.example-dns.com/records" \
  -H "Authorization: Bearer $API_KEY" \
  -d '{"type":"TXT","name":"'"$DOMAIN"'","content":"'"$TXT_VALUE"'"}'

To obtain a wildcard certificate:

certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  -d *.example.com \
  -d example.com

After setting the TXT record, verify propagation:

dig TXT _acme-challenge.example.com +short

Common issues include:

  • DNS propagation delays
  • Incorrect TXT record format
  • API rate limiting
  • Permission issues with DNS provider

For automatic renewal, add to crontab:

0 0 * * * certbot renew \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  --post-hook "systemctl reload nginx"

The DNS-01 challenge is an alternative to HTTP-01 validation in Let's Encrypt's ACME protocol. Instead of placing a file on your web server, you prove domain ownership by creating a specific TXT record in your domain's DNS zone.

Before using DNS-01 validation, ensure you have:

  • Control over your domain's DNS records
  • Certbot 0.9.3 or later installed
  • API access to your DNS provider (if automating)

Here's how to manually complete DNS-01 validation:

certbot certonly --manual --preferred-challenges dns -d example.com

Certbot will prompt you to add a TXT record like:

_acme-challenge.example.com. 300 IN TXT "gfj9Xq...Rg85nM"

For automated renewals, use a DNS plugin. Example for Cloudflare:

certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d example.com -d *.example.com

Create a configuration file for automated renewals:

# /etc/letsencrypt/cli.ini
authenticator = dns-cloudflare
dns-cloudflare-credentials = /path/to/cloudflare.ini
preferred-challenges = dns
email = your@email.com
domains = example.com, *.example.com

Problem: DNS propagation delays
Solution: Add --dns-cloudflare-propagation-seconds 60 to wait longer

Problem: Wildcard certificates
Solution: DNS-01 is required for wildcards. Use the same process but include -d *.example.com

For more flexibility, consider acme.sh:

acme.sh --issue --dns dns_cf -d example.com -d *.example.com \
--yes-I-know-dns-manual-mode-enough-go-ahead-please

Always secure your DNS API credentials:

  • Store credentials in files with 600 permissions
  • Use API tokens with minimal permissions
  • Consider IP restrictions for API access

Set up automatic renewal with cron:

0 0 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx"