Skip to content

fix: WireGuard sessions drop while the tunnel stays up #41

Description

@kazmosahebi

Goal

SSH and RDP sessions over the WireGuard tunnel stay connected as reliably as they do over OpenVPN on the same deployment.

Actual behaviour

On 2026-09-17, SSH and RDP sessions over WireGuard dropped repeatedly. The tunnel itself stayed up throughout: the client showed it connected while the sessions inside it died.

Switching the same Windows client to the OpenVPN config for the same deployment fixed it, with no drops since.

A second user on the same deployment is also on WireGuard and suspects the shared-client handling from #27 is still involved.

Not yet measured: how long a session lasts before it drops, and whether the drops track traffic volume.

Expected behaviour

Long-lived TCP sessions survive over WireGuard. docs/vpn-client-setup.md tells users to try WireGuard first, so it needs to be at least as stable as the OpenVPN fallback.

Reproduction steps

  1. Windows client, one slot file per device as "Using more than one device" in docs/vpn-client-setup.md describes: *-wg-*.conf on the first device, *-wg2-*.conf on the second.
  2. Connect over WireGuard and hold an SSH or RDP session open to a host behind the VPN.
  3. The session drops or freezes while the tunnel still shows connected.

Already ruled out

Two devices loading the same key, which is the failure #27 describes. Each device here loads its own slot file. That leaves a fault in slot issuance or the server peer list, which check 2 covers.

Candidate causes, and the check that settles each

  1. wg_mtu above what the path carries. fix(network): clamp forwarded TCP MSS to the tunnel MTU #32 states that the MSS clamp reads the configured wg_mtu, so it cannot correct a value that is itself too high. Handshakes and keepalives are small and pass, full-size packets are dropped, and that fits a live tunnel with dying sessions. OpenVPN runs on its own tun_mtu and mssfix, which would explain why it is unaffected. Check from a Windows WireGuard client: ping -f -l <size> <host behind the VPN>, stepping <size> down from the configured wg_mtu minus 28 until replies return, then compare the result with CULVERT_WG_MTU.
  2. Slot or peer-list fault on the server. During a drop, run wg show wg0 endpoints and wg show wg0 latest-handshakes for the affected peers. An endpoint that flips between two source addresses means one key is live in two places. wg show wg0 allowed-ips should list each tunnel /32 exactly once.

Environment

  • Client: WireGuard on Windows
  • Protocol affected: WireGuard only. OpenVPN on the same deployment is stable.
  • Device slots: a separate slot file per device

Definition of Done

  • Deployed culvert version, CULVERT_WG_MTU and the network profile recorded on this issue
  • Both checks above run during a drop, with the results recorded here
  • Root cause identified and fixed, or documented as a deployment setting if it turns out to be wg_mtu
  • An SSH session held open over WireGuard for 8 hours without a drop

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions