Вопрос: Почему iptables отклоняет второй и последующие фрагменты разрешенного пакета?


У меня есть два хоста, которые пытаются настроить соединение IPSec друг с другом. Для этого они должны общаться на портах UDP 500 и 4500, поэтому я открыл их в брандмауэрах на обоих концах (показано в соответствующей части):

-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

Однако обмен ключами никогда не преуспевает. Каждая сторона продолжает повторять передачу UDP-пакетов снова и снова, никогда не слыша ответ, пока они, наконец, не сдадутся.

я начал tcpdump с одной стороны, и заметил, что UDP-пакет фрагментирован и что недопустимый порт ICMP возвращается после того, как появился второй фрагмент.

Пример такого неудачного обмена (дезинфицированный для вашей защиты):

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]

Брандмауэр зарегистрировал следующее в отношении этого пакета:

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

У меня создалось впечатление, что Linux автоматически повторно собрал фрагменты, прежде чем передавать их на фильтр пакетов. Итак, почему эти фрагменты не собираются повторно, и поэтому второй фрагмент впоследствии отвергнут?


8
2017-08-26 04:53


Источник


В качестве примечания, IME, вы также должны разрешить ESP: iptables -A INPUT -p esp -j ACCEPT - fukawi2
@ fukawi2 Да, но это не относится к этому вопросу. - Michael Hampton♦


Ответы:


Код netfilter восстанавливает только фрагменты для вас до фильтрации пакетов если в правилах брандмауэра используется отслеживание соединений (т. е. правило брандмауэра имеет статус stateful и использует -m conntrack или устаревшие -m state) или NAT. В противном случае все фрагменты обрабатываются отдельно, и вы получаете такие проблемы, как этот.

Это позволяет решить проблему легко и очевидно (в ретроспективе, во всяком случае). Просто добавьте отслеживание соединений в соответствующие правила брандмауэра.

-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

Или для более старых систем Linux (например, RHEL 5 и более ранних версий):

-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

13
2017-08-26 04:53