# Shared zone-loading + recursive-forwarding config. # CoreDNS snippets are textually expanded by `import`, so we keep anything # that's not transport-specific (TLS) in here. (common) { auto { directory /zones (.*)\.zone {1} reload 30s } # Authorize AXFR (zone transfer) and send NOTIFY messages. # # The `transfer` plugin only accepts single IPs or `*` (no CIDR), so # for now we open AXFR to anyone. Two reasons this is acceptable: # # 1. DNS data is public anyway — every record is queryable # individually. AXFR just bundles them, no new secrets exposed. # 2. Docker's published-port NAT rewrites source IPs to the bridge # gateway, so we couldn't pin to Hurricane Electric's IPs # reliably even if we wanted to. # # NOTIFY messages go OUT to the listed IPs on zone change. We send # to all five HE secondaries so they refresh promptly when SOA bumps. transfer { to * } forward . 1.1.1.1 1.0.0.1 9.9.9.9 { max_concurrent 1000 } cache 30 errors log loop reload 10s } # Plain DNS — UDP/TCP :53. Health + metrics live here only (one binding). . { import common health :8080 prometheus :9153 } # DNS-over-TLS — RFC 7858. Port 853 is the IANA-assigned DoT port. tls://.:853 { tls /etc/coredns/certs/cert.pem /etc/coredns/certs/key.pem import common } # DNS-over-HTTPS — RFC 8484. Default path is /dns-query. # Clients: curl -H 'accept: application/dns-message' https://host:8443/dns-query?dns=... https://.:443 { tls /etc/coredns/certs/cert.pem /etc/coredns/certs/key.pem import common }