Skip to content

Add per-account dns_resolvers and skip_authoritative_ns_check#31

Open
abic wants to merge 2 commits into
PlayEveryWare:mainfrom
abic:per-account-dns-resolvers
Open

Add per-account dns_resolvers and skip_authoritative_ns_check#31
abic wants to merge 2 commits into
PlayEveryWare:mainfrom
abic:per-account-dns-resolvers

Conversation

@abic
Copy link
Copy Markdown

@abic abic commented May 12, 2026

In split-horizon DNS setups, lego's authoritative-SOA walk can stop at an internal subdomain that isn't a zone in the configured DNS provider, producing "zone could not be found" errors during DNS-01 validation.

Expose two existing lego challenge options through the account API so each account can opt in independently:

  • dns_resolvers: passed to dns01.AddRecursiveNameservers, overriding the host's resolver for SOA and propagation lookups.
  • skip_authoritative_ns_check: appends dns01.DisableAuthoritativeNssPropagationRequirement(), skipping the authoritative-NS propagation gate.

Both default to the previous behavior; accounts written before this change deserialize with zero values and continue to work unchanged. The dnsResolvers and skipAuthoritativeNSCheck fields already existed on the backend struct but were never populated outside of tests; they are preserved as a test-only path and are now overridden per-account when account-level values are set.

abic added 2 commits May 12, 2026 00:38
In split-horizon DNS setups, lego's authoritative-SOA walk can stop at
an internal subdomain that isn't a zone in the configured DNS provider,
producing "zone could not be found" errors during DNS-01 validation.

Expose two existing lego challenge options through the account API so
each account can opt in independently:

- dns_resolvers: passed to dns01.AddRecursiveNameservers, overriding
  the host's resolver for SOA and propagation lookups.
- skip_authoritative_ns_check: appends
  dns01.DisableAuthoritativeNssPropagationRequirement(), skipping the
  authoritative-NS propagation gate.

Both default to the previous behavior; accounts written before this
change deserialize with zero values and continue to work unchanged.
The dnsResolvers and skipAuthoritativeNSCheck fields already existed
on the backend struct but were never populated outside of tests; they
are preserved as a test-only path and are now overridden per-account
when account-level values are set.
The certs/dns-01/{account}/{provider}/{fqdn} read path only ever
requested a single domain from lego, so issued certs carried just
the FQDN as both CN and SAN. Listeners that need a per-host SAN and
a shared service SAN on the same cert (e.g. a backend reachable
both directly as node<N>.example.com and via an LB at
service.example.com) had no way to express that through this
plugin.

Expose an optional alt_names parameter on the cert read path:

- TypeCommaStringSlice; the FQDN remains the CN and the first SAN,
  with alt_names appended.
- Persisted on the stored cert (new AltNames field on the cert
  struct, marshalled with omitempty). Renewal reads supply no
  parameters and reuse the stored list, so the renewer doesn't
  need to know the SAN set.
- Supplying a different alt_names list forces re-issuance even if
  the existing cert is still inside its renewal window. Order is
  ignored when comparing, so rebuilding the list from a set or
  reordering it in inventory doesn't trigger spurious re-issues.

Legacy certs (no AltNames field in storage) deserialize as empty
slice and continue to behave as single-FQDN, so this is a
backward-compatible addition.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant