How can I change MTU size permanently?

Solution 1:

To determine the correct MTU setting, start with all MTU settings = 1500 and VPN = off. (VPN requires different testing).

Note: first remove your mods to /etc/dhcp/dhclient.conf and reboot.

In terminal:

ping [-c count] [-M do] [-s packet_size] [host]

The options used are:

  • c count: number of times to ping
  • M hint: Select Path MTU Discovery strategy. may be either do (prohibit fragmentation, even local one), want (do PMTU discovery, fragment locally when packet size is large), or dont (do not set DF flag).
  • s packet_size: Specifies the number of data bytes to be sent.

You should always start at 1472 and work your way down by 10 each time. Once you get a reply, go up by 1 until you get a fragmented packet. Take that value (last good value) and add 28 to the value to account for the various TCP/IP headers. Eg. let's say that 1452 was the proper packet size (where you first got an ICMP reply to your ping). The actual MTU size would be 1480, which is the optimum for the network we're working with.

ping -c 4 -M do -s 1472 8.8.8.8 # this will probably show fragmentation

ping -c 4 -M do -s 1462 8.8.8.8 # may show fragmentation

ping -c 4 -M do -s 1452 8.8.8.8 # no fragmentation?

ping -c 4 -M do -s 1453 8.8.8.8 # still no fragmentation?

reference: How to determine the proper MTU size with ICMP pings

Update #1:

I would recommend that you remove the 3 extra nameservers that you added to /etc/resolvconf/resolv.conf.d/head and let systemd-resolved properly manage /etc/resolv.conf. That should work better with VPN.

Update #2:

You can also setup a DIFFERENT wired/wireless connection profile, just for VPN, that hardwires the MTU=1200. In terminal, type nm-connection-editor and there you can customize a profile just for VPN with autoconnect and MTU.

enter image description here enter image description here

Solution 2:

You can automate the setting of the mtu for the VPN port when the VPN goes up as suggested in script /etc/NetworkManager/dispatcher.d/01-ifupdown. Scripts in the dispatcher.d folder are called with the port and event as arguments.

So, create a script in folder dispatcher.d with the following contents (if you want mtu 1200):

#!/bin/sh  

#info : pre-up and pre-down are not implemented in network-manager

if [ "$2" = "vpn-up" ]; then  
    /sbin/ifconfig "$1" mtu 1200  
fi  

(The name of the script does not matter.) Then make it executable with chmod +x <script>.

Solution 3:

You could use tracepath ( from the iputils-tracepath package) to determine the Path MTU:

walt@bat:~(0)$ dpkg -S $(type -p tracepath)
iputils-tracepath: /usr/bin/tracepath
walt@bat:~(0)$ tracepath primus.ip4.torontointernetxchange.net
 1?: [LOCALHOST]                                         pmtu 1500
 1:  spark3y                                               0.525ms 
 1:  spark3y                                               0.497ms 
 2:  spark3y                                               0.465ms pmtu 1492
 2:  dsl-xxx-xxx-xxx-xxx.tor.primus.ca                    32.701ms 
 3:  10.201.117.2                                         34.726ms asymm  5 
 4:  bb1.tor.primus.ca                                    39.238ms 
 5:  primus.ip4.torontointernetxchange.net                33.295ms reached
     Resume: pmtu 1492 hops 5 back 4