From cf0d6c6beb08f4bd1f692b9d82097c0568a5c768 Mon Sep 17 00:00:00 2001 From: Keith Jackson Date: Fri, 18 Sep 2026 20:56:29 -0500 Subject: [PATCH] =?UTF-8?q?docs:=20verified=20=E2=80=94=20internal=20servi?= =?UTF-8?q?ces=20are=20gone=20from=20public=20DNS,=20split-horizon=20works?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Confirmed at the authority, not a cache: all six internal names absent publicly, all five public names untouched, and Pi-hole answering for the six internally. The R-DNS-03 disclosure is closed for that tier. Records a correction to my own sequencing: I insisted this could not land before the DHCP repoint, but the router returns nothing for those six names, so the records served nobody and the dependency I asserted did not exist. One query would have shown it. Also records the operator's clarifications — Pi-hole is DNS only with the router still doing DHCP, reverse proxy by hostname rather than a second IP, and Minecraft staying open — plus the unencrypted-secret fix. Co-Authored-By: Claude Opus 5 --- DECISIONS-LOG.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) 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.