P0-P7 probe ladder on real ends (demo-felhom PVE host <-> throwaway Hetzner). Verdict: GO at H1 — plain host-side WG, box-dials-out to a small public endpoint; Headscale is a separable fleet layer, not a traversal necessity. Line is plain-NAT (not CGNAT) with zero IPv6 — recorded honestly; CGNAT vantage deferred to Peti VM 110. Real 2 GiB worst-case PBS backup over the tunnel at the full home uplink, pin intact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
4.6 KiB
felhom.eu — task reports
Overwrite this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in hub/CHANGELOG.md; the scripts history lives in scripts/CHANGELOG.md.
REPORT — SPIKE: offsite-backup connectivity (WireGuard, home-NAT traversal) (2026-07-03)
Docs-only run; evidence doc: documentation/audits/SPIKE-connectivity-wireguard-2026-07-03.md.
No production code, no Headscale on the real hub, no agent change, no persistent felhom-pve config.
Verdict
GO at the lowest rung (H1): plain WireGuard, host-side, box-dials-out to a small public endpoint. No coordinator, no relay, no mesh. Headscale (P5: 0.29.2 stood up throwaway) is a separable fleet-management layer — TLS control plane + DB + tailscaled-per-box + Tailscale-hosted DERP by default — not a traversal necessity for hub-and-spoke backup.
Probe ladder results (both ends real: demo-felhom PVE host ⟷ throwaway Hetzner CX23)
- P0 — the operator's line is plain single-NAT with a fixed public IPv4
(
37.191.56.193, catv.fixed.one.hu, AS21334), not CGNAT (no 100.64/10 hop; source IP at the server = egress IP). Zero IPv6 (no address, no egress, 15-min RA capture: 0 packets). - P1 (H0 v6-direct) — N/A on this line; keep the production endpoint dual-stack anyway.
- P2 (H1) — plain WG v4 up on the first try; RTT ~30–40 ms; 11.4-min fully-idle hold
(keepalive-only, NAT mapping unmoved, instant ping after); PBS 4.2.2 API through the tunnel with
the exact-cert pin intact (
pin.gomodel) + negative wrong-pin proof;:8007tunnel-only by firewall (public probe: unreachable). - P3 — uplink is the bottleneck: direct 42 Mbit/s up / 200–230 down; tunnel upload ~39 Mbit/s (~5% overhead); PBS TLS benchmark through tunnel 4.94 MB/s = the full uplink; real 2 GiB worst-case (urandom) backup: 4.26 MiB/s sustained, 8 min, zero stalls. First backup 50–100 GB ≈ 3–6 h (overnight window). Oddity recorded: tunnel download (565 Mbit/s, 0 retrans) beat direct TCP (230, 285 retrans) — UDP encapsulation dodges whatever shapes inbound TCP.
- P4 (H2) — outbound UDP fine on 51820 and 443; no TCP/443 fallback machinery needed.
- P6 — plain-WG isolation is topological: per-peer
/32AllowedIPs + forwarding off at the endpoint; only the PBS port admitted from the WG interface. - P7 — hypothesis refuted with evidence: kernel WG link creation succeeds inside the
unprivileged guest (no
/dev/net/tunneeded — that's confirmed absent and only blocks tailscaled). Host placement therefore stands on architecture: backups originate host-side, the tunnel must survive guest death (cloudflared precedent), the guest keeps zero infra creds.
Architecture recommendation (input to the next task — the production spec)
Host-side agent-managed WG service (cloudflared pattern); per-box keypair minted at install → pubkey to hub, private key 0600 in agent state dir + joins the escrowed IdentityBundle for DR; endpoint = small public dual-stack VM (€4–8/mo class), two shapes deferred to the spec: PBS-on-VM vs VM-as-rendezvous-relay with DooPlex PBS dialing out too (both ends outbound-only, ciphertext-only transit — also solves DooPlex's no-public-UDP). Trust model preserved: box only dials out; operator-inbound (B) and game-ingress (C) explicitly out of scope.
Honest caveats
CGNAT traversal is argued from mechanism, not proven on this line (it's plain-NAT); second-ISP confirmation deferred to Peti's VM 110 (currently unreachable). Single ISP/evening; no multi-day hold; no home-IP-rotation event observed; Headscale assessed server-side only (no tailscaled on the production host); no restore-direction PBS run.
Cleanup (verified)
demo-felhom: interface/keys/config/dataset gone (keys shredded), iperf3 purged, WG module
unloaded, /etc/wireguard untouched-empty, guest probe link deleted — residue-free. Hetzner
throwaway: WG + headscale + PBS torn down, secrets shredded, datastore deleted, box powered
off (parked for the Peti follow-up or destruction; jarrs.eu box never touched).
Repo changes (docs-only)
- NEW
documentation/audits/SPIKE-connectivity-wireguard-2026-07-03.md(P0–P7 verbatim + twelve §7 answers + recommendation). documentation/runbooks/day0-install.md— the "LAN-only until Headscale/WireGuard lands" backlog line now points at the spike (decision made; spec is the remaining gate).CONTEXT.md— transport decision recorded; next task = production connectivity spec.scripts/CHANGELOG.md— docs entry.