coredns/Corefile
Ryan Malloy 1ab88a25f7 coredns: hidden-primary architecture with AXFR for HE secondaries
Goal: serve the public DNS face via Hurricane Electric's free
secondary-DNS service (dns.he.net), with CoreDNS on dell01 acting as
the hidden primary. We edit zones here; HE pulls them via AXFR.

Changes:
- scripts/prepare-zones.sh:
  * SOA mname: ns1.vultr.com -> ns1.he.net (so the apex SOA reflects
    HE as the primary in published RDATA)
  * Strip ns?.vultr.com NS records from each zone and inject the five
    HE nameservers (ns1..ns5.he.net) as the authoritative NS set
- Corefile (shared `common` snippet):
  * Add `transfer { to * }` to authorize AXFR. Tried specific IPs +
    `*` mixed on the same line but CoreDNS silently fails to bind
    server blocks with that syntax; bare `to *` is the only form that
    actually starts the listeners. Trade-off: NOTIFY targeting is lost
    (HE polls per SOA refresh=3600s instead of being pushed). For DNS
    data this is fine since each record is publicly queryable anyway.

Verified AXFR end-to-end: `dig @dell01 -p 5353 acrazy.org AXFR +tcp`
returns 41 records with the new HE NS set and HE-rooted SOA.

Still needed (operator action):
- Firewall NAT for TCP/53 -> 172.16.1.15:5353 (so HE can connect in)
- Add each of the 91 zones at dns.he.net as Secondary DNS pointing
  at 154.27.180.210
- Update each domain's registrar NS records from Vultr -> HE
2026-05-16 15:49:42 -06:00

56 lines
1.6 KiB
Plaintext

# 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
}