Some time ago, I was dealing with an interesting problem – certain programs running inside a QEMU/KVM virtual machine with Linux as the guest OS were either not able to connect to certain Internet hosts at all, or were able to connect only after numerous timeouts or manual retries. Notably, the dnf and pip package managers were exhibiting this weird behaviour, whereas web browsers were not. In addition, this problem seemed to be present only when the host was connected to a VPN.

After a bit of digging, I discovered that the libvirt-managed virtual network bridge interface on the host OS had the usual MTU of 1500 bytes, whereas the VPN interface, to which packets from the VPN were forwarded, had a far smaller MTU – only 1280 bytes. At this point, it was apparent that there was some kind of issue with Path MTU Discovery.

At the end, I fixed the problem by using the technique of TCP MSS Clamping, which is supported by the Linux kernel and can be activated by an iptables rule, on both the VM host and the VPN concentrator:

# For IPv4:
iptables -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

# For IPv6:
ip6tables -t mangle -A FORWARD -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

If you are to use these commands, keep in mind that iptables rules are NOT persistent across reboots by default, and the way of making them persistent differs from distribution to distribution!