WireGuard MTU fixes

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. So I 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):

Address =
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

PresharedKey = PRESHARED_KEY
AllowedIPs =,

Client configuration (Home gateway):

Address =
MTU = 1412
PostUp = ip route add SERVER_PUBLIC_IP/32 via 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 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

PresharedKey = PRESHARED_KEY
Endpoint = SERVER_PUBLIC_IP:51820
AllowedIPs =
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 block for its internal communication and 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...

11 Responses

  1. I had my own Wireguard VPN server in my home and clients on my mobile phone and laptop set up with MTU=1420 and it worked fine but then I realised my mobile network has MTU less than 1400! So how was it working? I don’t know exactly, but clearly Wireguard doesn’t mind. In fact you can setup the Wireguard VPN with MTU=1500 and it just works, with 1500 byte packets going through the tunnel! I guess it must be slightly less efficient that way though. Certainly avoids all the weird problems you get with other UDP based VPNs if you miscalculate the MTU. Wireguard is THE BEST VPN.

  2. Chris says:

    If you are not accessing wireguard directly (e.g. from a VM through a Linux server that routes to wireguard), I had to use this:

    iptables -t mangle -A POSTROUTING -p tcp –tcp-flags SYN,RST SYN -o eth0 -j TCPMSS –clamp-mss-to-pmtu


    • Chris says:

      Sorry, that should be -o wg0 not eth0

      • Harald Reindl says:

        just remove the interface, it will help you in case some idiotic router in your path has a MTU of 1480 for evereything else

        Chain POSTROUTING (policy ACCEPT 39M packets, 37G bytes)
        num pkts bytes target prot opt in out source destination
        1 87694 5327K TCPMSS tcp — * * tcp flags:0x06/0x02 TCPMSS clamp to PMTU

  3. Raman says:

    Thank you, I ran into this issue with TLS handshake timeouts over the Wireguard VPN. Using

    PostUp = iptables -I FORWARD -p tcp –tcp-flags SYN,RST SYN -j TCPMSS –clamp-mss-to-pmtu
    PostDown = iptables -D FORWARD -p tcp –tcp-flags SYN,RST SYN -j TCPMSS –clamp-mss-to-pmtu

    on the “server” peer fixed the problem by avoiding pMTU discovery entirely. See https://www.tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.cookbook.mtu-mss.html.

    • Harald Reindl says:

      are you aware that this is only for TCP while more and more stuff goes over UDP like HTTP3/CUBIC? so without lower the MTU you may run into issues here and there and MTU troubles are miracles by their nature not to be always visible? lower the wireguard MTU to 1400 to be on the safe side, after doing so speedtest.net to different ISPs from my smartphone over the comany tunnel no longer died

Leave a Reply

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