Seed zone publishes an apex NS glued to the primary pod IP, and nothing ever replaces it #21

Closed
opened 2026-09-26 15:11:25 +10:00 by unkin-agent · 0 comments
Member

Every primary zone the operator creates is seeded with an apex NS ns1.<zone> plus a glue A pointing at the primary pod's IP at creation time (internal/bind/seed.go renderSeedZone). The comment calls it a placeholder replaced once real records load, but nothing replaces it: a zone with no spec.records and no DNSRecords keeps publishing a pod IP forever, and that IP goes stale on the first reschedule.

For a publicly delegated zone this is a latent outage. acme.unkin.net has served NS ns1.acme.unkin.net / A 10.42.6.38 (rke2 pod CIDR, no pod holds it) to public resolvers for 54 days; resolvers reach it only via the parent's glue for acme-ns1.unkin.net. When one re-resolves the in-zone NS name, DNS-01 breaks for every *.unkin.net cert.

Proposal

  • Let a zone declare its published nameserver(s), e.g. BindZone.spec.nameservers (out-of-zone names allowed), and render those in the seed instead of ns1.<zone>.
  • Keep the ns1 + pod-IP form only as the fallback when nothing is declared, and prefer a stable address (the primary Service IP/hostname) over the pod IP.
  • Reconcile the apex NS RRset on every reconcile, not only at seed time, so an existing zone converges.

Acceptance criteria

  • A zone with declared nameservers never has a pod IP in its zone file.
  • Changing the declared nameservers updates the live apex NS RRset on an already-created zone.
  • A zone with none declared still loads (check-integrity passes).
  • Unit tests over the render + apex-NS sync paths.
Every primary zone the operator creates is seeded with an apex `NS ns1.<zone>` plus a glue `A` pointing at the primary pod's IP at creation time (`internal/bind/seed.go` `renderSeedZone`). The comment calls it a placeholder replaced once real records load, but nothing replaces it: a zone with no `spec.records` and no DNSRecords keeps publishing a pod IP forever, and that IP goes stale on the first reschedule. For a publicly delegated zone this is a latent outage. `acme.unkin.net` has served `NS ns1.acme.unkin.net` / `A 10.42.6.38` (rke2 pod CIDR, no pod holds it) to public resolvers for 54 days; resolvers reach it only via the parent's glue for `acme-ns1.unkin.net`. When one re-resolves the in-zone NS name, DNS-01 breaks for every `*.unkin.net` cert. Proposal - Let a zone declare its published nameserver(s), e.g. `BindZone.spec.nameservers` (out-of-zone names allowed), and render those in the seed instead of `ns1.<zone>`. - Keep the `ns1` + pod-IP form only as the fallback when nothing is declared, and prefer a stable address (the primary Service IP/hostname) over the pod IP. - Reconcile the apex NS RRset on every reconcile, not only at seed time, so an existing zone converges. Acceptance criteria - A zone with declared nameservers never has a pod IP in its zone file. - Changing the declared nameservers updates the live apex NS RRset on an already-created zone. - A zone with none declared still loads (check-integrity passes). - Unit tests over the render + apex-NS sync paths.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unkin/bind-operator#21