read the live apex NS with a signed query, retract nothing when unreadable
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful

An unsigned localhost query is REFUSED for a zone behind a key-matched view and
answers empty with exit 0; signing it with the update creds reaches the view.
This commit is contained in:
2026-09-26 19:25:06 +10:00
parent dc57ac1b2d
commit 08d46ccce0
9 changed files with 67 additions and 65 deletions
+12 -21
View File
@@ -159,35 +159,26 @@ func zoneNameservers(zone *bindv1alpha1.BindZone, cluster *bindv1alpha1.BindClus
return clusterNameservers(cluster), ttl, false
}
// publishedNameservers is what the operator has already put in the apex NS RRset.
// It retracts only these, never a name someone else added, and needs no query
// against the pod: reading the live RRset back would take a view-scoped lookup,
// and an unsigned one silently returns nothing for a zone behind a BindView.
func publishedNameservers(zone *bindv1alpha1.BindZone, cluster *bindv1alpha1.BindCluster) []string {
if len(zone.Status.Nameservers) > 0 {
return zone.Status.Nameservers
}
// Nothing recorded yet, so the only names in the RRset are what a seed can
// write: an in-zone ns1 glued to the primary pod's IP (older seeds) or the
// stable in-cluster name (current ones).
return append([]string{fqdn("ns1", zone.Spec.ZoneName)}, clusterNameservers(cluster)...)
}
// apexNSUpdates moves a zone's apex NS RRset from published to desired, and
// retires the glue of any in-zone name it retracts. Adds come first: BIND refuses
// to leave an apex with no NS record, so the replacement must exist before the old
// apexNSUpdates moves a zone's apex NS RRset from live onto desired, and retires
// the glue of any in-zone name it retracts. Adds come first: BIND refuses to
// leave an apex with no NS record, so the replacement must exist before the old
// name goes, and deleting glue still referenced by an in-zone NS fails named's
// post-update nameserver sanity check.
func apexNSUpdates(zone *bindv1alpha1.BindZone, desired, published []string, ttl int32) []bind.RecordUpdate {
//
// An empty live set means the query could not see the zone, not that the apex has
// no NS records — a primary always has one. Nothing is retracted in that case:
// retracting blind is what turns a delete into "delete the last NS", which named
// rejects outright.
func apexNSUpdates(zone *bindv1alpha1.BindZone, desired, live []string, ttl int32) []bind.RecordUpdate {
apex := fqdn("@", zone.Spec.ZoneName)
add := missing(desired, published)
del := missing(published, desired)
add := missing(desired, live)
var updates []bind.RecordUpdate
if len(add) > 0 {
updates = append(updates, bind.RecordUpdate{FQDN: apex, Type: "NS", TTL: ttl, Values: add, PerValue: true})
}
if len(del) == 0 {
del := missing(live, desired)
if len(live) == 0 || len(del) == 0 {
return updates
}
updates = append(updates, bind.RecordUpdate{FQDN: apex, Type: "NS", Values: del, PerValue: true, Delete: true})