change: WireGuard bring-up moves from wg-quick to manual plumbing #186
Loading…
Reference in a new issue
No description provided.
Delete branch "wg-manual-bringup"
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?
Problem
The first live WireGuard run (#152 step 1, manual ProtonVPN config) leaked bypass traffic into the tunnel. wg-quick installs a mangle-level prerouting rule (
meta l4proto udp meta mark set ct mark) that runs after aqomui's PREROUTING bypass marking and erases the fwmark from every forwarded UDP packet — gluetun's entire outer flow (all of qbittorrent's seeding) double-tunneled through the WireGuard session. The existing post-up fwmark-rule reshuffle in tunnel.py ("Necessary, otherwise bypass mode breaks - need to investigate") was a symptom of the same root cause: wg-quick's Table=auto machinery assumes it is the host's only routing manager.Fix
New
aqomui/wireguard.pymodule does the bring-up with plain wg(8)/ip(8) plumbing; wg-quick is gone:0.0.0.0/1+128.0.0.0/1, v6 mirror) plus an endpoint host-route pin via the physical link — the same model OpenVPN redirect-gateway tunnels already have, so the bypass machinery needs no WireGuard-specific handling. The pin is main-table-only: kernel WireGuard never inherits the inner packet's fwmark (unlike ovpn-dco), so the bypass table is never consulted for outer packets.firewall.check_ipv6()so::/0in AllowedIPs doesn't abort bring-up on a v6-disabled host.wireguard.down()) is idempotent, reads the endpoint back from the conf in ROOTDIR, deletes the pin with aproto 111selector so it can never match a bypass tunnel's pin, and runs in the service startup sweep next tobypass.flush_stale_routes()(#78 pattern).wg().Verification
pytest: 449 passed (the pre-existingtest_mgmt.pysocket failures are my sandbox, pass on a normal shell); newtests/test_wireguard.pycovers conf splitting, the full bring-up command sequence, v6 gating, narrow AllowedIPs, mid-failure teardown, pin-delete proto selector, and idempotent down.ruff,compileall) clean locally.packaging/arch/build-branch-and-install.sh, confirm handshake + traffic, then check bypass withip route show table 11,nft list ruleset | grep -c wg-quick(expect 0), and watch that gluetun seeding upload rides the physical link, notwg_aqomui.🤖 Generated with Claude Code
Live verification on the real system (build installed via
build-branch-and-install.sh, connected to the ProtonVPN WG server from the #152 smoke test):wg_aqomuiup; def1 pair (0.0.0.0/1,128.0.0.0/1) on the device; physical default untouched; endpoint pin154.47.22.90 via 192.168.0.1 dev enp5s0(proto 111) presentip ruleclean: only32765: fwmark 0xb lookup 11beside the standard three — none of wg-quick's catch-all/suppress rules existip route get 1.1.1.1→wg_aqomui;ip route get 1.1.1.1 mark 11→via 192.168.0.1 dev enp5s0 table 11~.)