coredns/Corefile
Ryan Malloy 3720cd2885 deploy: enable rfc2136 plugin for all 84 production zones
Wires the custom CoreDNS image (built via coredns/Dockerfile, source
includes git.supported.systems/rsp2k/coredns-rfc2136) into production:

- docker-compose.yml: switch coredns service from upstream image pin
  to a build target. New `image: coredns-rfc2136:${COREDNS_IMAGE_TAG}`
  is locally-built; `up -d coredns` triggers the build.
- .env: COREDNS_IMAGE_TAG=2026.05.21 (CalVer). Old COREDNS_IMAGE kept
  as a comment for emergency rollback to upstream 1.11.3.
- Corefile: new rfc2136 directive inside (common) snippet enumerating
  all 84 zones currently in zones/. Plugin is now in the chain for
  every server block (plain DNS, DoT, DoH). UPDATE opcode lands in
  the plugin handler; auto-commit on, CalVer SOA serial bumping on,
  zones-dir /zones matches the existing bind-mount.

TSIG key is read from ${ACME_TSIG_SECRET} which lives in .env.local
(gitignored). Production deployment needs that file synced to dell01
separately.

This commit DOESN'T trigger the deployment by itself -- the image
must be built on dell01 and the container recreated to apply.
2026-05-21 12:17:20 -06:00

99 lines
4.8 KiB
Plaintext

# 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 *
}
# RFC 2136 dynamic DNS updates (TSIG-authenticated). Accepts UPDATE
# opcode messages from authorised clients (e.g. caddy-dns/rfc2136
# for ACME DNS-01) and applies them to the source zone files.
# SOA serial bumped automatically (CalVer); changes auto-committed
# to git. Plugin source: git.supported.systems/rsp2k/coredns-rfc2136
rfc2136 acrazy.org automaton.global automaton.host blender.bet blender.cam blender.partners blender.quest blender.systems cloud-dine.com context.bet coopermalloy.com copper-springs.online cyberinsuranceapp.com demostar.app demostar.click demostar.io demostar.net demo-tube.com dignity.ink dope.team encom.cash encom.ink encom.website encom.wtf enls.us enls.video freemyradicals.com garage.ceo garage.christmas garage.doctor garage.dog garage.engineering garage.makeup garage.rocks garage.supply glennsferry.site home-inspector.app home-inspector.pics home-inspector.site home-inspector.store home-inspector.website homestar.ink inpect.pro inspect.monster inspect.pics inspects.homes inspect.systems jobsite.homes kg7q.cc log.doctor lukascrockett.com malloys.us mcpdash.wtf mcp.website myhood.us nielsen-inspections.com nielsens.world ourjob.site paigemalloy.com paythatway.com powdercoatedcabinents.com powdercoatedcabinet.com powdercotedcabinets.com prezhub.com reviewr.guru rsvp-for.de ryanmalloy.com screencast.systems septic.report sidejob.pro spencernewbolt.com supported.systems supportedsystems.com supportedsystems.net syslog.chat tatemalloy.com tateorrtot.games timber.ink trackfeeds.cloud tuckermalloy.com upc.llc warehack.ing westboise.org zmesh.systems {
zones-dir /zones
tsig-key acme-update-key. hmac-sha256 {$ACME_TSIG_SECRET}
ttl 60
auto-commit true
git-author "coredns-rfc2136" "rfc2136@coredns.supported.systems"
}
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
# }