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 1412. Also, 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.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *