Warum lehnt iptables das zweite und nachfolgende Fragment eines zulässigen Pakets ab?

9

Ich habe zwei Hosts, die versuchen, eine IPSec-Verbindung miteinander herzustellen. Dazu müssen sie über die UDP-Ports 500 und 4500 kommunizieren, daher habe ich sie an beiden Enden in den Firewalls geöffnet (siehe entsprechenden Teil):

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -m udp -p udp --dport 500 -j ACCEPT
-A INPUT -m udp -p udp --dport 4500 -j ACCEPT
#.....
-A INPUT -j REJECT --reject-with icmp6-port-unreachable

Der Schlüsselaustausch ist jedoch nie erfolgreich. Jede Seite versucht immer wieder, die UDP-Pakete erneut zu übertragen, ohne eine Antwort zu hören, bis sie schließlich aufgeben.

Ich begann tcpdumpan einem Ende und stellte fest, dass das UDP-Paket fragmentiert wurde und dass ein nicht erreichbarer ICMP-Port zurückgegeben wurde, nachdem das zweite Fragment eingegangen war.

Ein Beispiel für einen solchen fehlgeschlagenen Austausch (zu Ihrem Schutz bereinigt):

04:00:43.311572 IP6 (hlim 51, next-header Fragment (44) payload length: 1240) 2001:db8::be6b:d879 > 2001:db8:f:608::2: frag (0x5efa507c:0|1232) ipsec-nat-t > ipsec-nat-t: NONESP-encap: isakmp 2.0 msgid 00000001 cookie 55fa7f39522011ef->f8259707aad5f995: child_sa  ikev2_auth[I]: [|v2e] (len mismatch: isakmp 1596/ip 1220)
04:00:43.311597 IP6 (hlim 51, next-header Fragment (44) payload length: 384) 2001:db8::be6b:d879 > 2001:db8:f:608::2: frag (0x5efa507c:1232|376)
04:00:43.311722 IP6 (hlim 64, next-header ICMPv6 (58) payload length: 432) 2001:db8:f:608::2 > 2001:db8::be6b:d879: [icmp6 sum ok] ICMP6, destination unreachable, length 432, unreachable port[|icmp6]

Die Firewall hat in Bezug auf dieses Paket Folgendes protokolliert:

Aug 26 04:00:43 grummle kernel: iptables: REJECT IN=eth0 OUT= MAC=############### SRC=2001:0db8:0000:0000:0000:0000:be6b:d879 DST=2001:0db8:000f:0608:0000:0000:0000:0002 LEN=424 TC=0 HOPLIMIT=51 FLOWLBL=0 OPT ( FRAG:1232 ID:5efa507c ) PROTO=UDP

Ich hatte den Eindruck, dass Linux Fragmente automatisch wieder zusammensetzt, bevor sie an den Paketfilter weitergeleitet werden. Warum werden diese Fragmente nicht wieder zusammengesetzt und daher das zweite Fragment anschließend verworfen?

Michael Hampton
quelle
Als Randnotiz, IME müssen Sie auch ESP zulassen:iptables -A INPUT -p esp -j ACCEPT
fukawi2
@ fukawi2 Ja, aber das ist für diese Frage nicht relevant.
Michael Hampton

Antworten:

14

Der Netfilter-Code setzt Fragmente vor der Paketfilterung nur dann wieder zusammen, wenn Ihre Firewall-Regeln die Verbindungsverfolgung verwenden (dh die Firewall-Regel ist statusbehaftet und verwendet -m conntrackoder veraltet -m state) oder NAT. Andernfalls werden alle Fragmente separat verarbeitet und Sie erhalten Probleme wie dieses.

Dies macht die Lösung des Problems einfach und offensichtlich (jedenfalls im Nachhinein). Fügen Sie den betreffenden Firewall-Regeln einfach die Verbindungsverfolgung hinzu.

-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

Oder für ältere Linux-Systeme (zB RHEL 5 und früher):

-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
Michael Hampton
quelle