docs: FrankBook-Pro active-tunnel reality (PA-12, 6881 retirement, qB wiring + save-path convention)
This commit is contained in:
@@ -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=<from the Proton .conf>
|
||||
WIREGUARD_ADDRESSES=<from the Proton .conf>
|
||||
WIREGUARD_PUBLIC_KEY=utqNH4P+C0fA1wTgIUaIfhm1b7ai0iEGvXyiw4KC3Fs=
|
||||
WIREGUARD_ENDPOINT_IP=149.102.254.77
|
||||
WIREGUARD_PUBLIC_KEY=<that server's pubkey>
|
||||
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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user