There are a number of approaches, none of which are 100% satisfying
### --compress
-
This is not as magic as we hope it to be - for some packets ("ping packet filled with 0") it will do a good job in making the resulting OpenVPN packet actually *smaller* than the incoming ICMP packet (avoiding outside fragmentation). For the packets normally seen on a VPN, which are like "compressed pictures downloaded by a web browser", compression will actually *add* a bit of overhead, so it is not fixing the fragmentation problem - and it adds its own problems. Do not use `--compress` these days.
+
This is not as magic as we hope it to be - for some packets ("ping packet filled with 0") it will do a good job in making the resulting OpenVPN packet actually *smaller* than the incoming ICMP packet (avoiding outside fragmentation). For the packets normally seen on a VPN, which are like "compressed pictures downloaded by a web browser", compression will actually *add* a bit of overhead, so it is not fixing the fragmentation problem - and it adds its own problems.
+
Do not use `--compress` these days.
### --fragment
This is a switch to OpenVPN (`--fragment 1300`) which adds a *middle fragment* layer to the already-complicated picture.
@@ 156,7 157,7 @@
This does work, but it is not supported if using kernel offloading (DCO), because it would require adding all the `--fragment` handling code (+reassembly) to the kernel layer - and the intent of the kernel implementations is "implement only the most common use cases, to keep the code size and complexity low".
The benefit of this is that there is no dealing with "outside fragments", so all the firewall/rate-limiting reasons for dropping are no longer a problem - but the extra overhead for fragment reassembly on the receiving end is still valid (reassembly in openvpn userland instead of kernel IP handler, but the same principle - energy, memory, CPU).
-
### tun-mtu
+
### --tun-mtu
Running OpenVPN with `--tun-mtu 1400` (e.g.) will create a "tun" interface with an interface MTU of less-than 1500 bytes - in this case, 1400 bytes. So no inside packets larger than 1400 byte can happen, because the IP stack *before* OpenVPN takes care of this (and `ping -s 1452` would actually see 2 inside packets in this scenario, one 1400 byte fragment and one with the rest).
The actual overhead "how many bytes will be added by OpenVPN to the inside packet?" depends on a number of factors - cipher and auth hash used, IPv4 or IPv6 transport on the outside, but as a rule of thumb it's something like 24+8+40 for "AES-GCM, UDP, IPv6" = 72 byte.
@@ 180,7 181,7 @@
Also, `tun-mtu` is not going to work if you want ethernet briding (tap mode) where you need the tap interface MTU to be the same as the LAN interface (no "packet too big" handling on the ethernet layer). This is somewhat of a niche use case, but it is something where OpenVPN can come in handy - and we need to be aware of the limitations.
-
### mssfix
+
### --mssfix
If `tun-mtu` can not be changed, or does not work correctly due to ICMP packet too big getting lost, there is another feature in OpenVPN which makes it "work for most cases", `--mssfix`, for example setting `--mssfix 500 mtu`. What this does is to look at TCP SYN and SYN-ACK packets passing through OpenVPN, and modifying the "MSS value" in there