MTU headaches between tunnel endpoints
The classic symptom: a TCP connection from a client to a tunnel endpoint works, but
a TLS connection stalls at exactly 300 seconds. The MTU is set to 1450
on the client side, but the path to the tunnel's peer has a 1300-byte hard limit.
Why 1450 fails
On Ethernet, the maximum packet size is 1500 bytes. When you add the
tunnel's GRE/UDP/IP overhead (usually 50 bytes), you get 1450. The
path's bottleneck link (a 3G/4G modem or a satellite link) has a hard MTU of 1300.
The client's TCP stack sends packets sized to 1450, the first 500 packets pass, and
the 501st packet is fragmented at 1300. If the path's DF bit is set,
the packet is dropped. The TCP stack sees 1200 bytes of data, then 1200, then
1200 again, until the window shrinks and the connection stalls.
The 57-byte clue
Check the path's MTU with traceroute -M or mtr -m 1500.
If the last hop is a PPPoE link or a PPPoE over 3G modem,
the MTU is often 1300. If the client is behind a NAT gateway that
rewrites the GRE header to a 57-byte tunnel header (a common pattern in
openvpn or wireguard), the 57 bytes are added to the path's
1243-byte limit, giving 1299 — one byte short. The client's TCP stack sends a 1300-byte
packet, the path drops it, and the 57-byte header is the culprit.
Fixes
On the client, set the tunnel's MTU to 1200. If the path's MTU is 1243, you can
set it to 1243. The client's OS will then fragment packets to fit the path's limit.
On the server side, tun0 devices need their own MTU set to the same
value. A 57-byte difference is common, so start with 1200 and bump to 1243 if you
see fragmentation on the server's tcpdump.
Rule of thumb: if a tunnel's client-side MTU is 1450, the path's MTU is likely 1300.