fix(caddy): the *arr stack and qBittorrent are LAN-only at the edge
Frank's ask was "get those off porkbun". Measured answer: they were never on
Porkbun — the zone holds 20 A records and not one of them is prowlarr., radarr., lidarr., readarr. or qbittorrent., and there is no wildcard. But
the reason they were reachable anyway is worse than a DNS record, so this PR
closes the actual gate.
Why a missing record was never the gate
Caddy issues one certificate per name, and every issuance is published in
Certificate Transparency logs. crt.sh for %.franksdank.cloud returns 31 names,
including the whole *arr stack, qbittorrent., hermes., hermesadmin., pihole. and the retired sonarr./comfyui./chat.. Caddy also answers any
Host it knows, so a stranger who names a vhost reaches it; the only thing that
was stopping them was not knowing the name — and the name is public.
Proof the edge accepts them today: curl --resolve radarr.franksdank.cloud:443:…
reaches the upstream (the answer is the upstream's 502 right now, because
FrankBook-Pro is asleep — the gate is what answers, not the vhost list).
The change
Each of the five vhosts now carries a source gate:
remote_ip sees the true client because the G36 DNATs the 80/443 forward
straight to Caddy with no proxy hop. LAN clients are unaffected; anything from
the internet gets 404. The same block is documented in AGENTS.md (External
Exposure Policy) as the required shape for a household-only service, so the next
"no public record = internal" claim is not believed again.
Verification
caddy validate on the rendered config inside the running container: Valid
configuration.
./tests/run.sh: 841 ok.
The gate's split is provable without waiting for a WAN client once deployed: a
LAN request must reach the upstream (a dead upstream still proves it passed the
gate — its 502, not the gate's 404), and an external fetcher must get 404.
Deploy note
dankclaw/Caddyfile is in the FrankBook e2e blast radius, so the [3/3] gate will
pull in 19-frankbook.spec.ts — and FrankBook-Pro (192.168.0.112) is powered off
right now (ARP FAILED, no MAC on record to wake it), so that project cannot
pass regardless of this change. Run the deploy when the Mac is back, or accept --skip-e2e for this one and re-run the project afterwards.
# fix(caddy): the *arr stack and qBittorrent are LAN-only at the edge
Frank's ask was "get those off porkbun". Measured answer: **they were never on
Porkbun** — the zone holds 20 A records and not one of them is `prowlarr.`,
`radarr.`, `lidarr.`, `readarr.` or `qbittorrent.`, and there is no wildcard. But
the reason they were reachable anyway is worse than a DNS record, so this PR
closes the actual gate.
## Why a missing record was never the gate
Caddy issues **one certificate per name**, and every issuance is published in
Certificate Transparency logs. `crt.sh` for `%.franksdank.cloud` returns 31 names,
including the whole *arr stack, `qbittorrent.`, `hermes.`, `hermesadmin.`,
`pihole.` and the retired `sonarr.`/`comfyui.`/`chat.`. Caddy also answers any
Host it knows, so a stranger who names a vhost reaches it; the only thing that
was stopping them was not knowing the name — and the name is public.
Proof the edge accepts them today: `curl --resolve radarr.franksdank.cloud:443:…`
reaches the upstream (the answer is the upstream's `502` right now, because
FrankBook-Pro is asleep — the gate is what answers, not the vhost list).
## The change
Each of the five vhosts now carries a source gate:
```
radarr.franksdank.cloud {
@lan remote_ip 127.0.0.1/32 ::1/128 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12
handle @lan {
reverse_proxy 192.168.0.112:7878
}
handle {
respond 404
}
}
```
`remote_ip` sees the true client because the G36 DNATs the 80/443 forward
straight to Caddy with no proxy hop. LAN clients are unaffected; anything from
the internet gets `404`. The same block is documented in `AGENTS.md` (External
Exposure Policy) as the required shape for a household-only service, so the next
"no public record = internal" claim is not believed again.
## Verification
- `caddy validate` on the rendered config inside the running container: **Valid
configuration**.
- `./tests/run.sh`: 841 ok.
- The gate's split is provable without waiting for a WAN client once deployed: a
LAN request must reach the upstream (a dead upstream still proves it passed the
gate — its `502`, not the gate's `404`), and an external fetcher must get `404`.
## Deploy note
`dankclaw/Caddyfile` is in the FrankBook e2e blast radius, so the [3/3] gate will
pull in `19-frankbook.spec.ts` — and FrankBook-Pro (192.168.0.112) is powered off
right now (ARP `FAILED`, no MAC on record to wake it), so that project cannot
pass regardless of this change. Run the deploy when the Mac is back, or accept
`--skip-e2e` for this one and re-run the project afterwards.
---
cwd: /home/blank/.omp/wt/wt-20261104-104444-6d1fc1f · session: 01a1a7eb-c584-72d3-9d7e-c02d981cd662
A missing Porkbun record was never the gate: Caddy issues one certificate per
name and every one is in public CT logs, so the *arr hostnames were discoverable
and the edge accepted them. Each of the five vhosts now carries a remote_ip
source gate (LAN proxies through, everything else gets 404) - the posture the
Sonarr comment already claimed. AGENTS.md records the LAN-gate shape as the
required form of internal-only, and Caddy.md records why DNS secrecy is fiction.
dank
merged commit a3ddb4c65a into main2026-11-04 13:49:34 -08:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
fix(caddy): the *arr stack and qBittorrent are LAN-only at the edge
Frank's ask was "get those off porkbun". Measured answer: they were never on
Porkbun — the zone holds 20 A records and not one of them is
prowlarr.,radarr.,lidarr.,readarr.orqbittorrent., and there is no wildcard. Butthe reason they were reachable anyway is worse than a DNS record, so this PR
closes the actual gate.
Why a missing record was never the gate
Caddy issues one certificate per name, and every issuance is published in
Certificate Transparency logs.
crt.shfor%.franksdank.cloudreturns 31 names,including the whole *arr stack,
qbittorrent.,hermes.,hermesadmin.,pihole.and the retiredsonarr./comfyui./chat.. Caddy also answers anyHost it knows, so a stranger who names a vhost reaches it; the only thing that
was stopping them was not knowing the name — and the name is public.
Proof the edge accepts them today:
curl --resolve radarr.franksdank.cloud:443:…reaches the upstream (the answer is the upstream's
502right now, becauseFrankBook-Pro is asleep — the gate is what answers, not the vhost list).
The change
Each of the five vhosts now carries a source gate:
remote_ipsees the true client because the G36 DNATs the 80/443 forwardstraight to Caddy with no proxy hop. LAN clients are unaffected; anything from
the internet gets
404. The same block is documented inAGENTS.md(ExternalExposure Policy) as the required shape for a household-only service, so the next
"no public record = internal" claim is not believed again.
Verification
caddy validateon the rendered config inside the running container: Validconfiguration.
./tests/run.sh: 841 ok.LAN request must reach the upstream (a dead upstream still proves it passed the
gate — its
502, not the gate's404), and an external fetcher must get404.Deploy note
dankclaw/Caddyfileis in the FrankBook e2e blast radius, so the [3/3] gate willpull in
19-frankbook.spec.ts— and FrankBook-Pro (192.168.0.112) is powered offright now (ARP
FAILED, no MAC on record to wake it), so that project cannotpass regardless of this change. Run the deploy when the Mac is back, or accept
--skip-e2efor this one and re-run the project afterwards.cwd: /home/blank/.omp/wt/wt-20261104-104444-6d1fc1f · session: 01a1a7eb-c584-72d3-9d7e-c02d981cd662