Mengapa iptables menolak fragmen kedua dan selanjutnya dari paket yang diizinkan?

9

Saya memiliki dua host yang mencoba mengatur koneksi IPSec satu sama lain. Untuk ini mereka harus berkomunikasi pada port UDP 500 dan 4500, jadi saya membukanya di firewall di kedua ujungnya (ditunjukkan pada bagian yang relevan):

-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

Namun, pertukaran kunci tidak pernah berhasil. Masing-masing pihak terus berusaha untuk mengirim ulang paket UDP berulang kali, tanpa pernah mendengar jawaban, sampai mereka akhirnya menyerah.

Saya mulai tcpdumpdari satu sisi dan mengamati bahwa paket UDP sedang terfragmentasi, dan bahwa port ICMP yang tidak terjangkau dikembalikan setelah fragmen kedua masuk.

Contoh dari pertukaran yang gagal tersebut (disterilkan untuk perlindungan Anda):

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]

Firewall mencatat hal-hal berikut sehubungan dengan paket ini:

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

Saya mendapat kesan bahwa Linux secara otomatis memasang kembali fragmen sebelum meneruskannya ke packet filter. Jadi mengapa fragmen-fragmen ini tidak dirakit kembali dan karenanya fragmen kedua kemudian ditolak?

Michael Hampton
sumber
Sebagai catatan, IME Anda juga harus mengizinkan ESP:iptables -A INPUT -p esp -j ACCEPT
fukawi2
@ fukawi2 Ya, tapi itu tidak relevan dengan pertanyaan ini.
Michael Hampton

Jawaban:

14

Kode netfilter hanya menyusun kembali fragmen untuk Anda sebelum penyaringan paket jika aturan firewall Anda menggunakan pelacakan koneksi (yaitu aturan firewall stateful dan menggunakan -m conntrackatau tidak digunakan lagi -m state) atau NAT. Kalau tidak, semua fragmen diproses secara terpisah dan Anda mendapatkan masalah seperti ini.

Ini membuat penyelesaian masalah menjadi mudah dan jelas (kalau dipikir-pikir lagi). Cukup tambahkan pelacakan koneksi ke aturan firewall yang dimaksud.

-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

Atau untuk sistem Linux yang lebih lama (mis. RHEL 5 dan sebelumnya):

-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
sumber