In this recipe, we will use the low-level ping
command to determine the optimal Maximum Transfer Unit (MTU) size for our OpenVPN setup. Finding the right MTU size can have a tremendous impact on performance, especially, when using satellite links, or even some cable/ADSL providers. Especially, broadband connections using the PPPoE (PPP over Ethernet) protocol often have a non-standard MTU size. In a regular LAN setup, it is hardly ever required to optimize the MTU size, as OpenVPN's' default settings are close to optimal.
Make sure the client and the server computers are connected over a network. For this recipe, the server computer was running CentOS 6 Linux. The client was running Fedora 22 Linux, but instructions for a Windows client are given as well.
[client]$ ping -c 2 <openvpn-server-ip>
This will send two ICMP ping packets to the server and two replies should be returned. If not, then a firewall or iptables
rule is blocking ICMP traffic. Ensure that the server can be reached using ping
before proceeding.
Don't Fragment
(DF) bit set. Strangely enough, on Linux, this is done using the parameter -M do
.[client]$ ping -c 2 -M do -s 1600 <openvpn-server-ip>
Normally, this command is not successful:
From 172.30.0.128 icmp_seq=1 Frag needed and DF set (mtu =
1500)
The maximum size of a packet that can be sent from this interface is 1500 bytes. From this, the Ethernet headers (normally 28 bytes) need to be subtracted, which means that the maximum size of an ICMP packet is 1472 bytes:
[client]$ ping -c 2 -M do -s 1472 <openvpn-server-ip> PING 172.30.0.128 (172.30.0.128) 1472(1500) bytes of data. 1480 bytes from 172.30.0.128: icmp_seq=1 ttl=128 time=0.630 ms 1480 bytes from 172.30.0.128: icmp_seq=2 ttl=128 time=0.398 ms
ping
command is slightly different:[winclient]C:> ping -f -l 1600 <openvpn-server-ip> Packet needs to be fragmented but DF set.
And:
[winclient]C:> ping -f -l 1472 <openvpn-server-ip> Pinging 172.30.0.1 with 1472 bytes of data: Reply from 172.30.0.1: bytes=1472 time<1ms TTL=64
The payload size of 1472 bytes is actually the regular size for an Ethernet-based network, even though this recipe was performed over a cable connection.
A good initial value for OpenVPN's' tun-mtu
setting is the maximum payload size plus the 28 bytes that were subtracted earlier. However, it does not mean this is the optimal value, as we will see in the later recipes.
The ICMP protocol which the ping
command uses has the option to set a flag Don't Fragment
(DF). With this bit set, an ICMP packet may not be broken up into separate pieces before it reaches its destination. If the packet were needed to be broken up by a router before it could be transmitted, it is dropped and an ICMP error code is returned. This provides a very easy method to determine the largest packet that can be transmitted to the server and vice versa. In particular, in high-latency networks, for example, when a satellite link is used, it is very important to limit the number of packets and to maximize the size of each packet.
By smartly using the ping
command, the maximum packet size can be determined. This size can then be used to further optimize the OpenVPN performance.
In some network setups, ICMP traffic is filtered, rendering this recipe useless. If it is possible to reach the OpenVPN server, then the tunnel can also be used to find the maximum payload size.
Start the OpenVPN server with the extra flags:
cipher none auth none
Do the same for the OpenVPN client. Make sure compression is turned off (or simply not specified) and that the fragment
option is not used. This will start a clear-text tunnel over which we can send ICMP packets of various sizes.
Ping the remote end's VPN IP address, for example:
[client]$ ping -c 2 -M do -s 1472 10.200.0.1
When the ICMP packet becomes too large, the traffic will be dropped by an intermittent router. Lower the ICMP packet size until the ping returns successfully. From that value, the MTU size can be derived.
18.191.218.187