# Shared zone-loading + recursive-forwarding config.
(common) {
    auto {
        directory /zones (.*)\.zone {1}
        reload 30s
    }

    # AXFR is open to everyone here. The FortiWiFi firewall does the
    # real source-IP filtering (only 216.218.133.2 / slave.dns.he.net
    # can reach our public :53/tcp).
    #
    # Why not narrow the `to` list to HE's IPs? CoreDNS's transfer
    # plugin has a confirmed bug: any `to` with more than one specific
    # IPv4 address silently breaks listener startup (no error logged,
    # zones load, but .:53 / tls://.:853 / https://.:443 never bind).
    # Reproduced in 1.11.3 and 1.12.2, even in a minimal fresh
    # `docker run` — not a compose state issue. Single-IP works, but
    # we need asymmetric config (AXFR from .133.2, NOTIFY to .130.2)
    # which the single-line `to` directive can't express.
    #
    # NOTIFY is sent externally by scripts/notify-he.py (invoked from
    # `make prep`) so we can target ns1.he.net specifically.
    transfer {
        to *
    }

    forward . 1.1.1.1 1.0.0.1 9.9.9.9 {
        max_concurrent 1000
    }
    # Use default cap (3600). Earlier `cache 30` clamped authoritative
    # TTLs too aggressively — every record HE pulled showed TTL≈5 because
    # the cache plugin sits in the (common) plugin chain and clamps any
    # response passing through, not just forwarded-resolver answers.
    cache
    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
}

# ─── PHASE 0 SCAFFOLDING — NOT YET ACTIVE ──────────────────────────
# Dynamic-update server for ACME DNS-01 challenges (RFC 2136 + TSIG).
# Caddy uses caddy-dns/rfc2136 to push TSIG-signed UPDATE messages here;
# the plugin stores TXT records in memory and serves them for Let's
# Encrypt's validation queries.
#
# Activation requires:
#   1. The coredns-rfc2136 plugin built into a custom CoreDNS image
#      (see coredns/Dockerfile and docker-compose.yml build directive).
#   2. ACME_TSIG_SECRET set in .env.local (already generated).
#   3. zones/supported.systems.zone delegating `auth` sub-zone to dell01:
#        auth   300   IN   NS   dns.supported.systems.
#   4. FortiWiFi firewall opening UDP/53 to dell01 from 0.0.0.0/0.
#
# Until those land, this block is a comment. The plan lives at
#   ~/.claude/plans/dood-does-coredns-offer-enumerated-piglet.md
#
# .:53 auth.supported.systems {
#     rfc2136 auth.supported.systems {
#         tsig-key acme-update-key. hmac-sha256 {$ACME_TSIG_SECRET}
#         ttl 60
#     }
#     errors
#     log
# }
