diff --git a/DECISIONS-LOG.md b/DECISIONS-LOG.md index 210b760..c961d04 100644 --- a/DECISIONS-LOG.md +++ b/DECISIONS-LOG.md @@ -4183,3 +4183,49 @@ restarting, since a restart may silently restore DHCP and destroy the evidence. The README's dev-era addressing was corrected throughout (VIP `.1.54`→`192.168.2.21`, pool and Gateway, device subnet, node name) along with several stale factual claims, since it doubles as the rebuild runbook. + +--- + +## 2026-09-18 — VERIFIED: internal services no longer advertise themselves publicly + +The R-DNS-03 disclosure is closed for the `internal` tier. Confirmed at the authority +(`betty.ns.cloudflare.com`, not a cache): + +| name | public DNS | via Pi-hole `.23` | +|---|---|---| +| sonarr, radarr, qbittorrent, jackett, semaphore, pihole | **GONE** | 192.168.2.20 | +| plex, gitea, seerr, keycloak, nextcloud | 192.168.2.20 (untouched, as designed) | — | + +So split-horizon now genuinely exists: the names resolve internally and are absent externally, which +is what `docs/09-dns-and-ingress.md` specified all along. The internal subnet, the Gateway VIP and six +service names are no longer publicly enumerable, and the DNS-rebind primitive is gone for those six. + +**A correction to my own sequencing.** I had insisted this could not land until the operator repointed +DHCP, on the grounds that removing public records would break LAN resolution. That was wrong, and +measuring it took one command: the SOHO router at 192.168.2.1 returns **nothing** for all six names, so +the public records were serving nobody on the LAN. The dependency I asserted did not exist. Landing it +early closed a security finding a day sooner than my own plan allowed. + +**Operator clarifications recorded** (theirs, 2026-09-18): +1. Pi-hole is **DNS only** — the SOHO router remains the DHCP server. Nothing in the Pi-hole change + touches DHCP; it exposes udp/53 and tcp/53 and no DHCP feature is enabled. The remaining action is + on the router: hand out `192.168.2.23` as the DNS server, ideally with a public resolver secondary + so a Pi-hole outage degrades to "internal names stop resolving" rather than "the LAN loses DNS". +2. **Reverse proxy by hostname is the accepted design; a separate IP is overkill.** So no second + Gateway and no second LoadBalancer address — the existing Gateway already distinguishes by Host/SNI. + Per-service public DNS targeting, if wanted, therefore goes through `DNSEndpoint` objects plus the + `crd` source rather than a second Gateway carrying a target annotation. +3. Minecraft stays open with no whitelist — accepted. + +**Still open, and it is a fact about the WAN, not a repo decision.** The five `public` services have no +working public path at all: `136.51.115.252` returns **HTTP 403** for `gitea.home.keithjackson.dev` and +presents a placeholder certificate (`CN=%D`), so nothing reverse-proxies these names from outside today. +Either the WAN forwards 80/443 to the Gateway at `192.168.2.20` — in which case their records should +point at the WAN address — or those five should be re-declared `internal`, because `exposure: public` +currently asserts something untrue. + +**Also fixed:** `apps/vms/unifi/unifi-uos-installer.sops.yaml` had been committed **unencrypted** with +both fields as literal `REPLACE-ME`, unlike every other `*.sops.yaml` here. `sops ` would have +failed with "sops metadata not found", and Flux would have created the Secret containing the +placeholder strings. Encrypted in place, round-trip verified. Both fields need setting, not just the +password — I had omitted `installer-url` from the operator instructions.