ping fails with MTU >= 298
Solution 1:
The fact you have set MTU on the hosts you control means nothing as the packets between them — in theory — might fly through any media with any MTU.
To deal with this issue (besides the IP fragmentation mechanism), the so-called "Path MTU discovery" mechanism exists.
Note that it relies on the ICMP protocol to work properly. Beside other things, it means that if you have tight firewall settings, you must have something like
iptables -t nat -A $CHAIN -m state --state RELATED -j ACCEPT
in your rules for your INPUT
chain (and in the FORWARD
chain if your
firewall also does SNAT for its clients).
The "related" state means that when an ICMP packet of the type 3, code 4 (destination unreachable / fragmentation required) is received, the conntrack subsystem decides which connection it is related to and then passes it further down the netfilter stack. The state of such packet is "RELATED" as known to
iptables
¹ so if you have passing of such packets denied — as often happens when people disable everything wholesale and then punch the minimal holes — P-MTU discovery won't work properly.
Note also that even if you "unbreak" proper support for P-MTU on your sides, it might still be broken somewhere in between.
In order to deal with it, there exists at least two knobs:
- Clamping MSS to MTU in the IP stack.
- Limiting these things on the OpenVPN level by its
tun-mtu
,tun-mtu-extra
andmssfix
knobs.
Note that these settings does affect performance, so use as the last resort.
¹ Because while not a part of an IP exchange, it's clearly related to it.
Solution 2:
I had a very similar issue at home, with SSH connections hanging at (as I recall) the exact same place in the connection setup. For me, tweaking the local MTU setting helped reduce the problem somewhat, but to make the problem go away, I had to turn on TCP MTU probing. After doing so I didn't have any similar problems. Only allowing RELATED
packets through iptables, as discussed in kostix's answer, didn't help.
For Linux, try
sudo sysctl net.ipv4.tcp_mtu_probing=1
The possible values are:
-
0
= disabled -
1
= disabled by default, enabled when an ICMP black hole detected -
2
= always enabled, use initial MSS of tcp_base_mss
Other OSes will be similar and different.
Note that this needs to be done on the client system, not the firewall (so not on the pfSense box) -- unless of course you are initiating your SSH connections from the firewall.
Solution 3:
I had the exact same issue: pinging with size 297 worked, 298 did not.
Our client was configured to not use compression:
comp-lzo no
Changing it to use compression fixed the issue:
comp-lzo yes
I don't understand why this works, but it does.