v0.42.1: wildcard cert via controller route (entrypoint domains don't issue)

Empirically (staging on 9201): traefik v3 issues a cert from a router-level
tls.domains but NOT from the entrypoint http.tls.domains. So the wildcard moves
to RenderControllerRoute (the always-present anchor): when DNS-01 ACME is
configured it carries tls.certResolver+domains *.<domain>+apex, and every other
router serves that wildcard by SNI (no per-app labels). Reverts v0.42.0's dead
entrypoint-domains + TraefikData.Domain.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 18:04:39 +02:00
parent 84c3e84641
commit e61e7dd8fc
5 changed files with 66 additions and 44 deletions
+13 -10
View File
@@ -1,21 +1,24 @@
## Changelog
### v0.42.0 — real Let's Encrypt cert: wildcard proactive issuance (2026-06-11)
### v0.42.1 — real Let's Encrypt cert: wildcard proactive issuance via the controller route (2026-06-11)
The base-infra traefik obtained **no** real cert (acme.json empty) — both routers relied on the
websecure entrypoint-default `certResolver`, which does not trigger proactive DNS-01 issuance, so
everything ran on traefik's self-signed default (masked externally by the tunnel's `noTLSVerify`).
This blocks LAN-direct (a LAN client TLS-handshakes straight to traefik and needs the real cert).
- **`internal/infra/templates/traefik.yml.tmpl`** — the websecure entrypoint's `http.tls` now declares
`domains: [{main: "*.<domain>", sans: ["<domain>"]}]` so traefik **proactively obtains the wildcard
`*.<domain>` + apex at startup** (via Cloudflare DNS-01). Every router then serves the real cert by
SNI match — no per-app `certresolver` labels to forget, cert ready before the first client connects.
Gated on `.CFAPIToken` (wildcards require DNS-01; HTTP-01 can't issue them).
- **`infra.TraefikData`** gains a `Domain` field; **`stacks.ensureTraefik`** now wires
`Domain: cfg.Customer.Domain` into `RenderTraefik` (previously unset).
- Validated staging→prod on guest 9201 (Fake LE → real LE), then GATE: `felhom.<domain>` +
`files.<domain>` return `200 0` (real cert, TLS verify OK) from a real LAN host.
- **`infra.RenderControllerRoute(domain, wildcardTLS)`** — the always-present controller route is now
the **wildcard-issuance anchor**: when DNS-01 ACME is configured it carries router-level
`tls.certResolver: letsencrypt` + `tls.domains: [{main: "*.<domain>", sans: ["<domain>"]}]`, so
traefik **proactively obtains `*.<domain>` + apex at startup** via Cloudflare DNS-01. Every other
router (filebrowser, future apps) then serves that one wildcard by SNI match — **no per-app
certresolver labels**, real cert ready before the first client connects. `stacks.wireController`
passes `wildcardTLS = (CFAPIToken != "" && Email != "")`.
- **Empirically established (staging on 9201):** traefik v3 issues from a **router-level** `tls.domains`
but **NOT** from the entrypoint-level `http.tls.domains` (acme.json stayed empty with the latter). The
v0.42.0 attempt (entrypoint `domains` + `TraefikData.Domain`) was reverted accordingly.
- Validated staging→prod on guest 9201 (Fake LE wildcard → real LE wildcard), then GATE: `felhom.<domain>`
+ `files.<domain>` return `200 0` (real wildcard cert, TLS verify OK) direct-to-guest from a real LAN host.
### v0.41.2 — fix controller-route auto-connect + dead dashboard cross-drive block (2026-06-11)