coredns: script-based NOTIFY to ns1.he.net on every prep
Hurricane Electric requires asymmetric transfer config:
- AXFR pull from 216.218.133.2 (slave.dns.he.net / ns4.he.net)
- NOTIFY destination 216.218.130.2 (ns1.he.net)
CoreDNS's transfer plugin uses a single bidirectional `to` list for
both, which is fine in principle but breaks in a confirmed bug: any
`to` with more than one specific IPv4 silently kills server-block
listener startup (no error, zones load, but :53 never binds).
Reproduced on 1.11.3 + 1.12.2 even with a minimal fresh `docker run`.
Workaround:
- Corefile keeps `transfer { to * }` (open AXFR; firewall does the
real source-IP filtering on TCP/53)
- scripts/notify-he.py crafts and sends NOTIFY messages directly to
216.218.130.2 (only). Pure-stdlib Python — no dependencies.
- Makefile `prep` target runs notify-he.py after prepare-zones.sh
so every zone-bump fires NOTIFY automatically.
Verified end-to-end: HE acks NOTIFY (rcode=0) for the 10 zones it
hosts as secondaries; remaining 81 return REFUSED (rcode=5) because
HE doesn't have them configured yet. Note: HE's free slave service
acks NOTIFY but only actually re-pulls AXFR on its hourly poll cycle
(observed behavior — they're poll-based by design). NOTIFY still
useful long-term in case HE changes that behavior; harmless either way.
This commit is contained in:
parent
e31f83b6ae
commit
d4a5ce9f82
3 changed files with 150 additions and 18 deletions
30
Corefile
30
Corefile
|
|
@ -1,29 +1,25 @@
|
|||
# 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
|
||||
}
|
||||
|
||||
# AXFR authorization is `to *` at this layer, with HE-only filtering
|
||||
# done by the FortiWiFi firewall (source IP restriction on the
|
||||
# TCP/53 DNAT rule). Reasons we don't filter at CoreDNS:
|
||||
# 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).
|
||||
#
|
||||
# 1. CoreDNS plugin quirk: `to <specific-IP>` (any form — single,
|
||||
# multi-line, space-separated) silently fails to start server
|
||||
# blocks. Reproduced on 1.11.3 and 1.12.2. Only `to *` works.
|
||||
# 2. Docker port publishing with userland-proxy rewrites source
|
||||
# IPs to the bridge gateway, so IP filtering wouldn't see HE's
|
||||
# real address anyway (without network_mode: host).
|
||||
# 3. Filtering at the perimeter (FortiWiFi) is correct-layered
|
||||
# defense: bad packets don't reach the host at all.
|
||||
# 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.
|
||||
#
|
||||
# Required FortiWiFi rule:
|
||||
# VIP "coredns-tcp" — src in {216.218.130.2, 216.218.131.2,
|
||||
# 216.218.132.2, 216.218.133.2, 216.66.1.2} —
|
||||
# dst WAN:53/tcp → 172.16.1.15:5353/tcp
|
||||
# NOTIFY is sent externally by scripts/notify-he.py (invoked from
|
||||
# `make prep`) so we can target ns1.he.net specifically.
|
||||
transfer {
|
||||
to *
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue