how to change tcp mss in linux to solve MTU issue

Andy
2 min readApr 12, 2020

--

the MSS value of TCP segment by default it is 1460 which 1500–40. if there is a node on your way to destination where MTU is not 1500. some of the website will facing problem. as the TCP segment can be mistakely fragmented.

for example in below case

client — — -gateway — — vpn — — -vpn_server — — — internet — — packages.cloud.google.com

in above example. the minimal path mtu is 1380 instead of default 1500 due to the VPN used as nexthop .

root@i-baytrail:/etc/wireguard# ping -M do packages.cloud.google.com -s 1380 -4
PING www3.l.google.com (216.58.220.206) 1380(1408) bytes of data.
ping: local error: Message too long, mtu=1380
ping: local error: Message too long, mtu=1380
^C

for most of website, it still will work although packet will be fragmented. however, for some of website , it wont will, it may stuck as the TLS phase like below. it hangs on TLS handshake.

root@kind-control-plane:/# curl -vvv https://www.google.com
* Trying 172.217.174.196:443...
* TCP_NODELAY set
* Connected to www.google.com (172.217.174.196) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):

we can change the advertised mss to force use MSS which to match the MTU . in this case, we have to advertise MSS = MTU-40 which is 1340. you can add specific route or just use default router. below I just added route to point to one of the google host.

ip route add 216.58.197.100/32 via 172.17.0.1 advmss 1340

after that. you can reach 216.58.197.100

root@kind-control-plane:/# curl  -I 216.58.197.100
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Sun, 12 Apr 2020 11:48:53 GMT
Expires: Tue, 12 May 2020 11:48:53 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN

--

--