The problem
A few days ago, I travelled via train and wanted to use my laptop with its WireGuard based VPN tunnel. But this time it was impossible to establish a connection to any machine outside the scope of localhost
. Many Restarts, traceroutes and nslookups later, I found the culprit: The MTU parameter of WireGuard.
The MTU (short for Maximum Transmission Unit) basically describes the maximum size of a data package, before it gets segmented into a new package. In Ethernet networks, this size is usually defined at 1500 bytes. As VPNs (and further possible trickery) encapsulate these packages, the actual payload of the package has to shrink, to accommodate for the larger introduced overhead.
As I was using the WiFi service on a long distance train, the link to the internet was aggregated from the cell services of multiple mobile carriers on the backhaul. This meant, that the TCP package sizes – and thus the MTU – were under the scrutiny of the public WiFis router.
The solution
Set the MTU to the highest – but yet functioning – value.
An example WireGuard configuaration could look like this:
[Interface]
PrivateKey = <PRIVKEY-OF-LOCAL-PEER>
Address = <YOUR-VPN-INTERNAL-IP>/<YOUR-NETMASK>
DNS = <YOUR-DNS-SERVER-IP>
MTU = 1400
[Peer]
PublicKey = <PUBKEY-OF-VPN-SERVER>
AllowedIPs = <ALLOWED-IPS>/<YOUR-NETMASK>
Endpoint = <IP-OF-VPN-SERVER>:<PORT-OF-VPN-SERVER>
PersistentKeepalive = <KEEPALIVE-IN-SECONDS>
As WireGuards default MTU of 1420 bytes seemed to be too large, I stepped down my MTU size in the steps of 10 bytes. I ended up settling on a value of 1400 bytes, when my networking instantly started working again.
Please be aware to test out this “down stepping” on your own, as your internal network is most definitely different, as mine was.
Also check out the WireGuard benchmark by nitred on GitHub where different MTUs were tested against their throughput performance.