DNS-01 ACME challenge delegation using acme-dns for wildcard certificates. BIND9 stays untouched except for static NS/CNAME records.
See dns-01-flow.md for sequence and architecture diagrams.
- Traefik requests a wildcard cert for
*.WILDCARD.DOMAIN. - Let's Encrypt challenges
_acme-challenge.WILDCARD.DOMAIN. - BIND9 returns a CNAME pointing into the
acme.DOMAINdelegated zone. - The CA follows the CNAME to acme-dns, which answers with the TXT token.
- BIND9 is never dynamically updated.
- Docker and Docker Compose
- A separate host (or IP) for acme-dns with ports 53 and 80 available
- Access to add records to your BIND9 zone
config/config.cfg.in— acme-dns config templatezone.in— BIND9 zone additions templatetraefik/traefik.yml.in— Traefik static config templatetraefik/acme-dns-creds.json.in— acme-dns credentials templatetraefik/dynamic.yml.in— Traefik dynamic router templatedocker-compose.yml— acme-dns container definitionMakefile— build and run targets
# 1. Generate acme-dns config and start the container
make config DOMAIN=mysite.com ACME_DNS_IP=10.1.1.1
make up
# 2. Register — save the full JSON output
make registermake register returns JSON with username, password, fulldomain, and subdomain.
Use those values in step 3.
# 3. Generate everything: zone file, traefik configs
make yolo \
DOMAIN=mysite.com \
WILDCARD=lab \
ACME_DNS_IP=10.1.1.1 \
ACME_EMAIL=myemail@example.com \
CNAME_TARGET=$fulldomain \
REG_USERNAME=$username \
REG_PASSWORD=$password \
REG_SUBDOMAIN=$subdomain# 4. Add contents of "zone" to your BIND9 zone, bump serial, reload
rndc reload mysite.com| Target | Description |
|---|---|
make config |
Generate config/config.cfg from template |
make zone |
Generate zone file with BIND9 record additions |
make traefik |
Generate Traefik configs from templates |
make yolo |
All of the above in one shot |
make up |
Start acme-dns container |
make down |
Stop acme-dns container |
make register |
Register a new acme-dns account |
| Variable | Description |
|---|---|
DOMAIN |
Your base domain |
WILDCARD |
Subdomain for the wildcard cert (*.WILDCARD.DOMAIN) |
ACME_DNS_IP |
Public IP of the acme-dns host |
ACME_EMAIL |
Email for Let's Encrypt registration |
CNAME_TARGET |
fulldomain from make register |
REG_USERNAME |
username from make register |
REG_PASSWORD |
password from make register |
REG_SUBDOMAIN |
subdomain from make register |
make zone produces three records:
acme.mysite.com. NS acme-dns.mysite.com.
acme-dns.mysite.com. A 10.1.1.1
_acme-challenge.lab.mysite.com. CNAME a1b2c3d4.acme.mysite.com.
- NS+glue delegates the
acme.mysite.comzone to your acme-dns host. - The CNAME redirects the wildcard challenge to acme-dns.
dig @10.1.1.1 <fulldomain-from-register> TXTFor each additional *.other.mysite.com, run make register to get a new credential set, then add one CNAME to BIND9:
_acme-challenge.other.mysite.com. CNAME <fulldomain-from-register>.
The NS delegation and glue record are shared across all subnets.