Send DNS NOTIFY to secondaries after every UPDATE
Per RFC 1996, a master that mutates a zone SHOULD notify its
secondaries so they can immediately AXFR rather than wait for their
next SOA-refresh poll. Without this, propagation lag from UPDATE to
public DNS is bounded by the secondary's refresh interval (300s for
us) — which is borderline for ACME validation timing.
New Corefile directive:
notify <host[:port]> [<host[:port]>...]
Targets accept bare hostnames (port 53 default), host:port, or
[ipv6]:port. The same list applies to every zone in the rfc2136
block.
Implementation: fire-and-forget UDP per target, each in its own
goroutine, capped by a 2s timeout. The UPDATE response to the client
is never held pending NOTIFY acks (RFC 1996 §4 explicitly decouples
them). Failures log at DEBUG only — a briefly-unreachable secondary
is normal and would otherwise spam logs.
Retires the external scripts/notify-secondaries.py workflow for any
deployment that wires the directive: secondaries now hear about
changes within seconds of the UPDATE landing, no cron or manual
invocation needed.
New tests:
- TestSendNotify_DeliversToTarget — packet arrives, opcode + zone correct
- TestSendNotify_NoTargets_NoCrash — empty list short-circuits
- TestSendNotify_BadTarget_LogsButDoesNotBlock — fire-and-forget timing
- TestNotifyOne_AppendsDefaultPort — host vs host:port normalization
This commit is contained in:
parent
89993ca207
commit
7367401734
6 changed files with 241 additions and 0 deletions
|
|
@ -179,6 +179,13 @@ func (p *RFC2136) handleUpdate(w dns.ResponseWriter, r *dns.Msg, verified bool)
|
|||
|
||||
log.Infof("UPDATE applied: zone=%s prereqs=%d updates=%d msg=%q",
|
||||
zone, len(r.Answer), len(r.Ns), msg)
|
||||
|
||||
// Fire NOTIFY to configured secondaries (RFC 1996). Non-blocking:
|
||||
// each target gets its own goroutine, capped by notifyTimeout. The
|
||||
// UPDATE response to the client is not held on these acks — RFC
|
||||
// 1996 §4 explicitly decouples them.
|
||||
sendNotify(zone, p.NotifyTargets)
|
||||
|
||||
return p.updateResp(w, resp, dns.RcodeSuccess)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue