Exempt internal split-horizon zones from resolver DNSSEC validation #251

Merged
benvin merged 1 commits from benvin/resolver-validate-except into main 2026-07-12 22:17:17 +10:00
Owner

Why

Resolving any unkin.net record through the resolver (.7) returns SERVFAIL, while the authoritative (.6) answers fine. Confirmed from the resolver's querylog:

view openforwarder:   validating unkin.net/SOA: got insecure response; parent indicates it should be secure
broken trust chain resolving 'ausyd1nxvm2120.main.unkin.net/A/IN': 198.18.200.6#53
query failed (broken trust chain)

The resolver runs dnssec-validation auto. The public unkin.net is DNSSEC-signed (the .net parent publishes a DS), but the in-cluster split-horizon authoritative serves unkin.net unsigned. The validator sees "parent says secure" + an insecure answer → treats it as spoofing → SERVFAIL. The authoritative works directly because it does no validation.

Fix

Add validate-except (via spec.extraOptions) for the forwarded internal domains, so the resolver treats them as insecure and skips validation:

validate-except { unkin.net; 18.198.in-addr.arpa; consul }
  • unkin.net covers all *.unkin.net (incl. main.unkin.net, k8s.syd1.au.unkin.net)
  • 18.198.in-addr.arpa covers every NN.18.198.in-addr.arpa reverse zone (subtree)
  • consul covers the consul TLD

This also makes internal resolution independent of Internet egress (no DNSSEC chain-walk needed). External-name validation is unchanged. No operator change required.

Validation

bind-internal renders and passes kubeconform (56/56); pre-commit clean.

Activation

After merge + operator reconcile, the resolver ConfigMap re-renders; the running pods hold a startup snapshot, so they need a reload: kubectl -n bind-internal rollout restart statefulset/bind-resolvers.

## Why Resolving any `unkin.net` record through the resolver (`.7`) returns **SERVFAIL**, while the authoritative (`.6`) answers fine. Confirmed from the resolver's querylog: ``` view openforwarder: validating unkin.net/SOA: got insecure response; parent indicates it should be secure broken trust chain resolving 'ausyd1nxvm2120.main.unkin.net/A/IN': 198.18.200.6#53 query failed (broken trust chain) ``` The resolver runs `dnssec-validation auto`. The public `unkin.net` is DNSSEC-signed (the `.net` parent publishes a DS), but the in-cluster split-horizon authoritative serves `unkin.net` **unsigned**. The validator sees "parent says secure" + an insecure answer → treats it as spoofing → SERVFAIL. The authoritative works directly because it does no validation. ## Fix Add `validate-except` (via `spec.extraOptions`) for the forwarded internal domains, so the resolver treats them as insecure and skips validation: ``` validate-except { unkin.net; 18.198.in-addr.arpa; consul } ``` - `unkin.net` covers all `*.unkin.net` (incl. `main.unkin.net`, `k8s.syd1.au.unkin.net`) - `18.198.in-addr.arpa` covers every `NN.18.198.in-addr.arpa` reverse zone (subtree) - `consul` covers the consul TLD This also makes internal resolution independent of Internet egress (no DNSSEC chain-walk needed). External-name validation is unchanged. No operator change required. ## Validation `bind-internal` renders and passes `kubeconform` (56/56); pre-commit clean. ## Activation After merge + operator reconcile, the resolver ConfigMap re-renders; the running pods hold a startup snapshot, so they need a reload: `kubectl -n bind-internal rollout restart statefulset/bind-resolvers`.
unkinben added 1 commit 2026-07-12 22:13:52 +10:00
Exempt internal split-horizon zones from resolver DNSSEC validation
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/kubeconform Pipeline was successful
2706632f54
Resolver queries for unkin.net records returned SERVFAIL (broken trust
chain): the in-cluster authoritative serves unkin.net UNSIGNED, but the
public parent publishes a DS record (unkin.net is DNSSEC-signed on the
Internet), so the validating resolver rejects the insecure answer.

Add validate-except for the forwarded internal domains so the resolver
treats them as insecure and does not validate them. unkin.net covers all
*.unkin.net (incl. k8s.syd1.au.unkin.net); 18.198.in-addr.arpa covers
every NN.18.198.in-addr.arpa reverse zone; consul covers the consul TLD.
benvin merged commit 5e7dc580b7 into main 2026-07-12 22:17:17 +10:00
benvin deleted branch benvin/resolver-validate-except 2026-07-12 22:17:17 +10:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: unkin/argocd-apps#251