Pourquoi iptables rejette-t-il le deuxième et les fragments suivants d'un paquet autorisé?


9

J'ai deux hôtes qui tentent d'établir une connexion IPSec l'un avec l'autre. Pour cela, ils doivent communiquer sur les ports UDP 500 et 4500, alors je les ai ouverts dans les pare-feu aux deux extrémités (illustrés dans la partie pertinente):

-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

Cependant, l'échange de clés ne réussit jamais. Chaque côté continue d'essayer de retransmettre les paquets UDP encore et encore, sans entendre de réponse, jusqu'à ce qu'ils abandonnent enfin.

J'ai commencé tcpdumpà une extrémité et j'ai observé que le paquet UDP était fragmenté et qu'un port ICMP inaccessible était retourné après l'entrée du deuxième fragment.

Un exemple d'un tel échange échoué (aseptisé pour votre protection):

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]

Le pare-feu a consigné les informations suivantes concernant ce paquet:

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

J'avais l'impression que Linux réassemblait automatiquement les fragments avant de les transmettre au filtre de paquets. Alors pourquoi ces fragments ne sont-ils pas réassemblés et donc le deuxième fragment est-il rejeté par la suite?


En remarque, IME, vous devez également autoriser ESP:iptables -A INPUT -p esp -j ACCEPT
fukawi2

@ fukawi2 Oui, mais ce n'est pas pertinent pour cette question.
Michael Hampton

Réponses:


14

Le code netfilter ne réassemble les fragments pour vous avant le filtrage des paquets que si vos règles de pare-feu utilisent le suivi de connexion (c'est-à-dire que la règle de pare-feu est avec état et utilise -m conntrackou obsolète -m state) ou NAT. Sinon, tous les fragments sont traités séparément et vous obtenez des problèmes comme celui-ci.

Cela rend la résolution du problème facile et évidente (rétrospectivement, de toute façon). Ajoutez simplement le suivi des connexions aux règles de pare-feu en 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

Ou pour les systèmes Linux plus anciens (par exemple RHEL 5 et versions antérieures):

-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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.