ProtonVPN WireGuard support #152
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Deferred past the current release by design: OpenVPN import (#33/#146) is the headline feature and the WireGuard tunnel path hasn't been exercised at all yet, even with a manual config.
What it takes, roughly in order:
gen_wg_key, protocol tables, the WireGuard branch in tunnel.py, Mullvad's WG-only import) but none of it has been tested live. A manual WG config from any provider is the cheapest smoke test.Durationthe API grants a third-party session; if it's short, renewal machinery is required, which makes #147's persisted-session/refresh-token work a hard prerequisite (a scheduled renewal can't solve a CAPTCHA, same as auto-update)./vpn/logicalsalready carries per-physical-serverX25519PublicKey; WG entries would double the imported server count, which raises the stakes on the server-navigation UX work and touches the multi-entry-per-type groundwork from #138.🤖 Generated with Claude Code
Step 1 (validate the WG plumbing live) is done, and it found a real bug: a manual ProtonVPN config connects fine (no credentials needed — the private key in the config is the credential, already bound to the account at download time), but bypass leaked. wg-quick's mangle-level
mark = ctmarkrule runs after aqomui's PREROUTING bypass marking and erases the fwmark from all forwarded UDP — gluetun's whole outer flow double-tunneled through the WG session.PR #186 replaces wg-quick with manual wg(8)/ip(8) bring-up (def1 routes + endpoint pin, same routing model as the OpenVPN path), which removes the rule that wipes the mark and the old post-up fwmark reshuffle hack with it.
Design decisions from the follow-up discussion, for the record:
up(role)/down()/dev/dns/alive()implemented by an OpenVPN and a WireGuard class, held by composition in the tunnel thread. Role-specific routing (main/hop/bypass) stays shared policy outside the classes — role is a parameter, never per-protocol methods.alive()is the one legitimate protocol asymmetry: process liveness for OpenVPN, handshake age for WG — relevant to #123.Status: step 1 is complete and hardened — WG plumbing validated live (#186 manual bring-up replacing wg-quick, #189 protocol class + conf codec, both merged). Step 4's config generation now exists as wireguard.generate_conf, so native support reduces to steps 2–3: certificate/key registration against the authenticated endpoint (hard prerequisite: #147 persisted sessions) and the logicals server model.
ProtonVPN WireGuard is live: import (#182), manual bring-up replacing wg-quick so bypass survives (#186), protocol seam + conf codec (#189), and alt-DNS/teardown-status parity (#193). All live-verified including split-horizon DNS and network-change reconnect. Mullvad WG template support exists but stays unverified until an account is around; WG doublehop is #176.