UPDATE: I researched a little more on this. ipv6 connections require
1280 as the minimum MTU and most router configurations expect to see some standardized MTU. So instead of
1412 as I wrote below, I now recommend
1280 for MTU. While it is smaller and will generate more packets, I think it will encounter fewer configuration problems across different sites.
I live in a country where internet access is severely censored. Wikipedia and Imgur access were just recently restored, and access to many other websites are blocked for various reasons. Due to the incompetence of our censors, sometimes sites with necessary knowledge get blocked too. So I use a 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.
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.1.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.1.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.1.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 (I recommend setting the MTU to
1280, see my update on the top of the post for my reasoning). 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.1.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.