Why is iptables rejecting the second and subsequent fragments of an allowed packet?

Solution 1:

The netfilter code only reassembles fragments for you prior to packet filtering if your firewall rules use connection tracking (i.e. the firewall rule is stateful and uses -m conntrack or the deprecated -m state) or NAT. Otherwise all the fragments are processed separately and you get issues like this one.

This makes resolving the issue easy and obvious (in retrospect, anyway). Just add connection tracking to the firewall rules in question.

-A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 500 -j ACCEPT
-A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 4500 -j ACCEPT

Or for older Linux systems (e.g. RHEL 5 and earlier):

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 500 -j ACCEPT
-A INPUT -m state --state NEW -m udp -p udp --dport 4500 -j ACCEPT