From 94d9d249a1898450f2cf07f885eb71a1fd99eba7 Mon Sep 17 00:00:00 2001 From: Frank Date: Tue, 1 Sep 2026 16:32:16 -0700 Subject: [PATCH] docs: FrankBook-Pro active-tunnel reality (PA-12, 6881 retirement, qB wiring + save-path convention) --- .../Infrastructure/FrankBook-Pro.md | 102 ++++++++++-------- serverAppConfigs-docs/log.md | 27 +++++ 2 files changed, 83 insertions(+), 46 deletions(-) diff --git a/serverAppConfigs-docs/Infrastructure/FrankBook-Pro.md b/serverAppConfigs-docs/Infrastructure/FrankBook-Pro.md index 122b283..4741b75 100644 --- a/serverAppConfigs-docs/Infrastructure/FrankBook-Pro.md +++ b/serverAppConfigs-docs/Infrastructure/FrankBook-Pro.md @@ -22,55 +22,35 @@ stack and qBittorrent inside a **podman machine** VM (Fedora CoreOS-style - Grab-only stack: the arrs never auto-import; nothing writes to the entropy volume. Completed files land in `/Volumes/COMPLETE/Finished Torrents`. -## WireGuard gate (gluetun) +## WireGuard gate (gluetun) — ACTIVE qBittorrent downloads through gluetun (netns share); the arrs run without it. -Until `/home/core/Containers/gluetun/env` contains the WireGuard credentials -(a second Proton WireGuard config for the Mac — running two hosts on -Dankclaw's config would bounce the server-side endpoint and kill SearXNG), -`deploy_frankbook_stack` **skips** gluetun and qbittorrent -with instructions and deploys the five arrs anyway. The qB WebUI port stays -unpublished by design; the e2e torrent test waits on the credentials. +Provisioned 2026-09-01 with a **second Proton WireGuard config** (server +`PA-12`; the downloaded `.conf` lives in `~/Downloads/FrankBook-Pro-PA-12.conf` +on Dankware). One config = one keypair — reusing Dankclaw's would bounce the +server-side endpoint and kill SearXNG. The Seattle server the plan originally +assumed is equally valid; only endpoint + server pubkey must match the +chosen config. Egress verified from inside the VM: `curl ifconfig.me` shows +the Proton PA exit (never the residential IP), ~19 MB/s sustained on a live +torrent. -### Mac provisioning (2026-09-01 — one dashboard action, then mine) - -The endpoint is a **ProtonVPN Seattle WireGuard server**, not a -self-administered box: RDAP says `149.102.254.77` is CDNEXT-CG-SEA -(Datacamp Limited, Proton's Seattle hosting partner) and Dankclaw's own -tunnel v6 `2a07:b944::2:2` sits in CH-PROTONVPN-20160719. There is no -peer-registration step on any server of ours — Dankclaw's credentials are a -dashboard-generated Proton WG config pasted into gluetun's `custom` profile, -and the Mac needs exactly the same thing, generated fresh: - -1. In the Proton dashboard, create a second WireGuard config (e.g. named - `frankbook`) on the Seattle server and download the `.conf`. One config = - one keypair; reusing Dankclaw's would make the server bounce the endpoint - between the two hosts. -2. Hand the values over (the file itself or its fields — the private key - never enters the repo): - - `PrivateKey` → `WIREGUARD_PRIVATE_KEY` - - `Address` (v4 + v6, e.g. `10.2.0.3/32, 2a07:b944::2:3/128`) → - `WIREGUARD_ADDRESSES` - - `PublicKey` → `WIREGUARD_PUBLIC_KEY` (Seattle server key: - `utqNH4P+C0fA1wTgIUaIfhm1b7ai0iEGvXyiw4KC3Fs=`, same as Dankclaw's) - - `Endpoint` = `149.102.254.77:51820`; gluetun ignores the `.conf` DNS line. - -Then `/home/core/Containers/gluetun/env` (0600) inside the VM: +`/home/core/Containers/gluetun/env` (0600, inside the VM): VPN_SERVICE_PROVIDER=custom VPN_TYPE=wireguard WIREGUARD_PRIVATE_KEY= WIREGUARD_ADDRESSES= - WIREGUARD_PUBLIC_KEY=utqNH4P+C0fA1wTgIUaIfhm1b7ai0iEGvXyiw4KC3Fs= - WIREGUARD_ENDPOINT_IP=149.102.254.77 + WIREGUARD_PUBLIC_KEY= + WIREGUARD_ENDPOINT_IP=51.179.177.2 WIREGUARD_ENDPOINT_PORT=51820 WIREGUARD_ALLOWED_IPS=0.0.0.0/0,::/0 WIREGUARD_PERSISTENT_KEEPALIVE_INTERVAL=25s -Deploy with `./scripts/deploy.sh frankbook-pro --service gluetun --service -qbittorrent`, then verify egress from the VM (`podman exec gluetun curl -s -ifconfig.me` must NOT show the residential IP) before declaring the -BitTorrent port usable. +The private key is hashed into the VM env file and never enters the repo. +NAT-PMP inbound forwarding is available on Proton (gluetun supports it via +`FIREWALL_INPUT_PORTS` + `NATPMP=true`) — deliberately deferred: the e2e +gate passes outbound-only, and swarm peers needing an inbound port is a +seeding-era concern, not a grab-only one. ## Deploy flow @@ -85,21 +65,51 @@ health-checks its published port on Mac loopback. gvproxy forwards published ports to Mac loopback only. LaunchAgents (`local.fwd.*` in `~/Library/LaunchAgents`) run socat forwarders binding the -LAN IP (192.168.0.112) for arr UIs (9696/8989/7878/8686/8787), the qB WebUI -(8080, inert until the tunnel is up), and the BitTorrent port 6881 tcp+udp. +LAN IP (192.168.0.112) for arr UIs (9696/8989/7878/8686/8787) and the qB +WebUI (8080). The two **6881 tcp+udp agents were retired**: gvproxy binds a +wildcard `*:6881/udp` listener (dual-stack; Go sets `SO_REUSEADDR` on TCP but +not UDP), so the socat-specific bind collides at every boot — delete the +agents; swarm inbound (if ever needed) is the Proton NAT-PMP path, not the +LAN one. Note macOS's application firewall still filters gvproxy inbound +from non-local sources (stealth mode drops unsolicited packets), so +cross-host reachability of 8080 from other LAN boxes may need +`socketfilterfw` allowlisting of gvproxy — Mac-local use and swarm egress +are unaffected. -## qBittorrent seed (first boot, inside the VM) +## qBittorrent runtime + wiring (2026-09-01) -- `WebUI\Password` is a **PBKDF2** `@ByteArray(salt:hash)` +- `WebUI\Password_PBKDF2` is a **PBKDF2** `@ByteArray(salt:hash)` (PBKDF2-HMAC-SHA512, 100k iterations, 64 bytes) — qB ≥ 4.2 ignores plaintext. The plaintext lives in `/home/core/Containers/qbittorrent/env` - (mode 600, VM-local) for Prowlarr wiring. + (mode 600, VM-local) for the arr wiring. The first seed wrote the hash + under the legacy `WebUI\Password` key (silently ignored → every client + got `Unauthenticated`); the live conf was patched and + `scripts/deploy-remote.sh` fixed to write the `_PBKDF2` key. - `HostHeaderValidation=false` + `ServerDomains=*`: the socat forwarder preserves the LAN `Host` header, which would otherwise be rejected. -- `categories.json` pre-creates `Finished Torrents`, `lidarr`, `radarr`, - `tv-sonarr` with save_path `/Volumes/COMPLETE/Finished Torrents`. -- `Session\DefaultSavePath=/Volumes/COMPLETE`, - `Session\TempPath=/Volumes/INCOMPLETE/incomplete` (two-disk layout). +- **Save-path convention**: `Session\DefaultSavePath=/Volumes/COMPLETE/ + Finished Torrents`, `Session\TempPath=/Volumes/INCOMPLETE/incomplete` + (two-disk layout: partials on INCOMPLETE, qB moves on completion). + qB 5.2 API adds with a category do **not** inherit the category save + path (no auto-TMM), so the default itself points at `Finished Torrents`: + every grab lands there regardless of client behavior; human review moves + files onward; nothing writes to the entropy volume. +- Categories seeded: `Finished Torrents`, `lidarr`, `radarr`, `readarr`, + `tv-sonarr` (all → `Finished Torrents`). +- **Download clients** (gateway `10.88.0.1:8080`, user `admin`): sonarr + (`tv-sonarr`), radarr, lidarr created via API, live tests pass. Readarr's + was transplanted by direct `readarr.db` row insert (app stopped): its EOL + validator (last release 2023) rejects qB ≥ 5's `204` empty login success + as "Authentication failure", so an API create can never pass; runtime + cookie auth is unaffected. Treat readarr as best-effort. +- **Prowlarr Applications** push to sonarr/radarr/lidarr (`fullSync`, + gateway ports). Readarr deliberately omitted: prowlarr's indexer-push + test to readarr's `/api/v1/indexer/test` 500s (EOL schema drift). + Legacy `Prowlarr-*` indexer rows carried in the migrated dankserver DBs + pointed at the unresolvable hostname `prowlarr:9696` and were deleted; + the current `*(Prowlarr)` entries test OK. +- **E2E proven**: qB fetched a `.torrent` through the tunnel, downloaded at + ~19 MB/s, completed into `Finished Torrents`. # Citations diff --git a/serverAppConfigs-docs/log.md b/serverAppConfigs-docs/log.md index bf2e60c..1f1129c 100644 --- a/serverAppConfigs-docs/log.md +++ b/serverAppConfigs-docs/log.md @@ -11,6 +11,33 @@ timestamp: 2026-09-14 # Bundle Change Log +## 2026-09-01 (late) — FrankBook-Pro stack completed: tunnel live, qB wired into the arrs +- WireGuard credentials provisioned (second Proton config, server `PA-12`, + endpoint `51.179.177.2:51820`) → `/home/core/Containers/gluetun/env` + (0600, VM-local); `deploy.sh frankbook-pro --service gluetun --service + qbittorrent` brought both up; egress verified (Proton PA exit, ~19 MB/s + on a live torrent). The `.conf` stays in `~/Downloads`; the private key + never enters the repo. +- gvproxy binds wildcard `*:6881/udp` (Go sets `SO_REUSEADDR` on TCP but not + UDP) → the socat 6881 tcp+udp LaunchAgents collided at every boot and + were retired; swarm inbound (if ever needed) is the Proton NAT-PMP path. + macOS application firewall still filters gvproxy inbound from non-local + sources (stealth mode) — cross-host 8080 needs `socketfilterfw` allow. +- qB wiring: first-seed bug (hash under legacy `WebUI\Password` key, ignored + by qB ≥ 4.2) fixed live (`WebUI\Password_PBKDF2`) and in + `scripts/deploy-remote.sh`; `DefaultSavePath` repointed to + `/Volumes/COMPLETE/Finished Torrents` — qB 5.2 API adds with a category + do not inherit the category save path (no auto-TMM); download clients + created in all four arrs (sonarr/radarr/lidarr via API, tests pass; + readarr by direct `readarr.db` insert — its EOL validator rejects qB 5's + `204` login as auth failure); Prowlarr Applications sync sonarr/radarr/ + lidarr (readarr omitted: prowlarr's indexer push 500s on EOL schema). + Legacy `Prowlarr-*` indexer rows (hostname `prowlarr:9696`, unresolvable + on the Mac default network) deleted. E2E: Sintel fetched + downloaded + through the tunnel at ~19 MB/s, completed into `Finished Torrents`. +- Docs: [[FrankBook-Pro]] rewritten to the active-tunnel reality. + + ## 2026-09-01 - WG endpoint identified as ProtonVPN Seattle; Mac gate is a second dashboard config - RDAP: `149.102.254.77` = CDNEXT-CG-SEA (Datacamp Limited, Proton's Seattle hosting partner); Dankclaw's tunnel v6 `2a07:b944::2:2` sits in