feat: add NS TTL consistency and NS-target CNAME checks
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing

Observe the NS RRset TTL from each parent server (ParentView.NSTTL) and
whether each NS target name is a CNAME alias (ChildNSView.CNAMETarget).
Two new rules judge the collected facts:

- delegation_ns_ttl_inconsistent: warns when parent servers disagree on
  the NS TTL, which indicates zone-data inconsistency between primaries.
- delegation_ns_is_cname: flags NS targets that are CNAME aliases as
  critical, per RFC 2181 §10.3 which forbids aliased NS names.
This commit is contained in:
nemunaire 2026-05-16 21:21:12 +08:00
commit 70c548284e
4 changed files with 125 additions and 6 deletions

View file

@ -58,12 +58,14 @@ func (p *delegationProvider) Collect(ctx context.Context, opts sdk.CheckerOption
for _, ps := range parentServers {
view := ParentView{Server: ps}
ns, glue, _, qerr := queryDelegation(ctx, ps, delegatedFQDN)
ns, glue, nsTTL, nsTTLKnown, qerr := queryDelegation(ctx, ps, delegatedFQDN)
if qerr != nil {
view.UDPNSError = qerr.Error()
} else {
view.NS = ns
view.Glue = glue
view.NSTTL = nsTTL
view.NSTTLKnown = nsTTLKnown
}
if terr := queryDelegationTCP(ctx, ps, delegatedFQDN); terr != nil {
@ -97,6 +99,11 @@ func (p *delegationProvider) Collect(ctx context.Context, opts sdk.CheckerOption
// Phase B: per-child observations, seeded only from parent data.
for _, nsName := range primary.NS {
child := ChildNSView{NSName: nsName}
if target, cerr := queryCNAMETarget(ctx, nsName); cerr == nil && target != "" {
child.CNAMETarget = target
}
addrs := primary.Glue[nsName]
if len(addrs) == 0 {
// Out-of-bailiwick: no glue expected, fall back to the system resolver.