Linux – IPsec transport mode and MTU

ipseclinuxlinux-networkingmtunetworking

[Similar to Right way to set the MTU of an IPsec Client (Linux/Racoon), but different in that there is no router on the responder side]

I have a setup where machines in a local network need to talk to a Linux server in a datacenter. The router for the local network has a static external IP address, so I've configured a policy on both the router and the server to use IPsec in transport mode to speak to each other.

This works fine for small packets, however the server cannot accurately determine the MTU for outgoing packets, leading to connection hangs.

What is the best way to avoid these issues?

Ideas so far:

  1. limit the MTU in the routing table. This requires a static route on the server and basically works, but breaks for mobile ("roadwarrior") clients when I introduce them in two weeks.

  2. use iptables to modify the TCPMSS setting on incoming packets. This appears to have no real effect, and would not work for UDP.

Best Answer

This is a bug in the Linux kernel IPsec. It fails to account for the size of the transport-mode ESP encapsulation when deciding whether to fragment the outgoing packet; it's then dropped on output as it exceeds the interface MTU. I don't know whether this has been fixed in newer kernels.

Related Topic