MTU – MSS – Kernel Compile and Networking Gem

Unbelievably, this is still a problem across the internet!

If your connection through to the internet is less than 1500 (bytes) MTU, or if the destination you wish to connect to is less than 1500 MTU, and there is a “brain dead” ‘block all ICMP‘ at that far end or anywhere else along the route breaking the Path MTU Discovery, then you will suffer lost or failed connections…

Unfortunately, such is the paranoia for some systems about blocking everything with a firewall… :-(

If your host/server is behind a modem-router, your machine’s MTU can be 1500 to the modem-router whereas the restricting internet connection MTU may well be somewhat smaller…

Hence, from the Linux kernel compile config:

CONFIG_NETFILTER_XT_TARGET_TCPMSS:

This option adds a `TCPMSS’ target, which allows you to alter the MSS value of TCP SYN packets, to control the maximum size for that connection (usually limiting it to your outgoing interface’s MTU minus 40).

This is used to overcome criminally braindead ISPs or servers which block ICMP Fragmentation Needed packets. The symptoms of this problem are that everything works fine from your Linux firewall/router, but machines behind it can never exchange large packets:

  1. Web browsers connect, then hang with no data received.
  2. Small mail works fine, but large emails hang.
  3. ssh works fine, but scp hangs after initial handshaking.

Workaround:

Activate this option and add a rule to your firewall configuration like:

iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

To compile it as a module, choose M here. If unsure, say N.

Unfortunately, although that is a good workaround that usually works, it is not a “fix all” panacea… For ICMP blocked links over tunnels, or multiply encapsulated data packets, or for just simply bad equipment, you may need to instead explicitly set the MSS with:

iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss nnnn

where “nnnn” is for example 1460 for PPPoE, or 1412 for ppp (typical for ADSL modems), or it can be made to be smaller if you are still having problems for an even more constrained link over a tunnel or whatever. (The MSS should be at least 40 bytes smaller than the MTU to avoid packet fragmentation. The MSS can be safely set smaller than actually needed, the only penalty is the overhead of needing respectively more data packets for large chunks of data.)

There is a good explanation on: “How to Setup a Linux Firewall with PPPoE/NAT/iptables“.

Good luck!

Leave a Reply