WireGuard MTU fixes
I live in a country where internet access is severely limited. We cannot access Wikipedia, Imgur, and many other websites. So I have to use a permanent VPN at home and on my mobile devices to overcome this issue. Until recently, I was using OpenVPN but then I came upon a great new technology by Jason A. Donenfeld called WireGuard, which blew my mind as I read about it.
It is incredibly fast to connect, very easy to implement and uses minimal resources on a modern computer. My home gateway is on a Debian server with VMWare Fusion, installed on a Mac mini 2018 as I write this post. The home gateway passes all traffic to the VPN server so that all traffic at my home is encrypted and restriction free.
I also use WireGuard as an on demand VPN for cellular networks on my iPhone and iPad and the battery impact is minimal. It is really something to configure and forget about, just perfect.
There are many how-tos about installing and configuring WireGuard on the internet, so I will not cover that. What I will cover is, how to fix problems if you are connecting to the internet using PPPoE, for example on an ADSL connection.
I had problems with connection drops, timeouts or other weird issues when I first installed WireGuard on Debian (The mobile devices had no problems whatsoever, so this was an issue with the home gateway). Some sites behaved normally, others had intermittent problems, and some were just not working. After searching for hours and trying many options I came to a perfectly working configuration. So I decided to write it as a future reference to people who will most probably have the same problems on PPPoE.
Server configuration (VPN server):
[Interface] PrivateKey = SERVER_PRIVATE_KEY Address = 10.88.88.1/24 SaveConfig = true PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -A FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -D FORWARD -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT ListenPort = 51820 [Peer] PublicKey = CLIENT_PUBLIC_KEY PresharedKey = PRESHARED_KEY AllowedIPs = 10.88.88.2/32, 192.168.10.0/24
Client configuration (Home gateway):
[Interface] PrivateKey = CLIENT_PRIVATE_KEY Address = 10.88.88.2/24 MTU = 1412 PostUp = ip route add SERVER_PUBLIC_IP/32 via 192.168.10.1 dev eth0; iptables -A FORWARD -i wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu PostDown = ip route del SERVER_PUBLIC_IP/32 via 192.168.10.1 dev eth0; iptables -D FORWARD -i wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -D FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu [Peer] PublicKey = SERVER_PUBLIC_KEY PresharedKey = PRESHARED_KEY Endpoint = SERVER_PUBLIC_IP:51820 AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 15
So, what makes this configuration work? First, on PPPoE connections, the maximum MTU is generally
1492 instead of widely used
1500, so the default MTU of WireGuard which is
1420, needs to be corrected to
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu added on
PostUp to the client configuration is the magical setting here that fixes the remaining issues. With it, the client tells the server to use the correct MTU when sending packets to it.
Other noteworthy items with this configuration: The VPN tunnel uses
10.88.88.0/24 block for its internal communication and
192.168.10.0/24 block (change this to your local IP address range) is added to the IP addresses behind the client, which lets local machines connect directly to the server without any extra NAT configuration. On OpenVPN I had to use double NAT, first on the home gateway, then on the server, resulting in a slower connection. With WireGuard, only the server hides IP addresses behind it using NAT. A much simpler configuration.