Perché iptables rifiuta il secondo e i successivi frammenti di un pacchetto consentito?


9

Ho due host che stanno tentando di stabilire una connessione IPSec tra loro. Per questo devono comunicare sulle porte UDP 500 e 4500, quindi le ho aperte nei firewall su entrambe le estremità (mostrato nella parte relativa):

-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

Tuttavia, lo scambio di chiavi non ha mai successo. Ogni parte continua a tentare di ritrasmettere ripetutamente i pacchetti UDP, senza mai sentire una risposta, fino a quando non si arrendono.

Ho iniziato tcpdumpda un lato e ho osservato che il pacchetto UDP era frammentato e che una porta ICMP irraggiungibile veniva restituita dopo l'arrivo del secondo frammento.

Un esempio di tale scambio fallito (sterilizzato per la tua protezione):

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]

Il firewall ha registrato quanto segue per quanto riguarda questo pacchetto:

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

Avevo l'impressione che Linux riassemblasse automaticamente i frammenti prima di passarli al filtro pacchetti. Quindi perché questi frammenti non vengono riassemblati e quindi il secondo frammento viene successivamente respinto?


Come nota a iptables -A INPUT -p esp -j ACCEPT
margine

@ fukawi2 Sì, ma non è rilevante per questa domanda.
Michael Hampton,

Risposte:


14

Il codice netfilter ricompone i frammenti per te solo prima del filtraggio dei pacchetti se le regole del firewall utilizzano il tracciamento della connessione (ovvero la regola del firewall è stateful e utilizza -m conntracko è obsoleta -m state) o NAT. Altrimenti tutti i frammenti vengono elaborati separatamente e si ottengono problemi come questo.

Ciò rende la risoluzione del problema semplice e ovvia (a posteriori, comunque). Aggiungi semplicemente il tracciamento della connessione alle regole del firewall in questione.

-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

O per sistemi Linux meno recenti (ad esempio RHEL 5 e precedenti):

-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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.