Mengapa firewall kami (Ubuntu 8.04) menolak paket akhir (FIN, ACK, PSH) dengan RST

20

Latar belakang, untuk waktu yang lama kami memiliki masalah dengan firewall kami yang terkadang membuat permintaan HTTP menggantung sebagian dimuat hingga TCP habis.

Setelah melacak lalu lintas di firewall saya perhatikan bahwa itu terjadi hanya selama kondisi waktu tertentu, misalnya ketika server web telah mengirim seluruh respons sebelum klien mengirim ACK keduanya pada payload. [SYN, SYN / ACK, ACK] telah ditukar, PERMINTAAN telah dikirim dan ACK'ed dan paket RESPONS pertama telah diterima dan ACK'ed, kemudian server web mengirimkan sisa badan respons dalam satu kesempatan (8 paket) termasuk FIN terakhir, PSH) dan sebelum klien telah ACK'ed salah satu dari mereka, Firewall MENOLAK dengan RST menuju server web dan membuat klien menggantung tak terbatas.

Inilah seluruh jejak wireshark dengan paket-paket dari kedua sisi firewall. 192.168.126.161 adalah alamat IP NAT'et pribadi klien. 172.16.1.2 adalah IP server web (tidak menunjukkan IP publik sebenarnya) dan 10.1.1.1 adalah IP eksternal firewall (tidak menunjukkan IP publik nyata)

2105 0.086275 192.168.126.161  172.16.1.2       TCP 37854 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSV=89375083 TSER=0
2106 0.000066 10.1.1.1         172.16.1.2       TCP 37854 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSV=89375083 TSER=0
2107 0.002643 172.16.1.2       10.1.1.1         TCP http > 37854 [SYN, ACK] Seq=0 Ack=1 Win=32768 Len=0 MSS=1460
2108 0.007705 172.16.1.2       192.168.126.161  TCP http > 37854 [SYN, ACK] Seq=0 Ack=1 Win=32768 Len=0 MSS=1460
2109 0.006301 192.168.126.161  172.16.1.2       TCP 37854 > http [ACK] Seq=1 Ack=1 Win=5840 Len=0
2110 0.000025 10.1.1.1         172.16.1.2       TCP 37854 > http [ACK] Seq=1 Ack=1 Win=5840 Len=0
2111 0.000007 192.168.126.161  172.16.1.2       HTTP GET /test/style.css HTTP/1.1 
2112 0.000015 10.1.1.1         172.16.1.2       HTTP GET /test/style.css HTTP/1.1 
2113 0.001536 172.16.1.2       10.1.1.1         TCP http > 37854 [ACK] Seq=1 Ack=111 Win=32658 Len=0
2114 0.000014 172.16.1.2       192.168.126.161  TCP http > 37854 [ACK] Seq=1 Ack=111 Win=32658 Len=0
2115 0.002274 172.16.1.2       10.1.1.1         HTTP HTTP/1.1 200 OK  (text/css)
2116 0.000025 172.16.1.2       192.168.126.161  HTTP HTTP/1.1 200 OK  (text/css)
2117 0.005689 192.168.126.161  172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=1461 Win=8760 Len=0
2118 0.000024 10.1.1.1         172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=1461 Win=8760 Len=0
2119 0.001536 172.16.1.2       10.1.1.1         HTTP Continuation or non-HTTP traffic
2120 0.000026 172.16.1.2       192.168.126.161  HTTP Continuation or non-HTTP traffic
2121 0.000007 172.16.1.2       10.1.1.1         HTTP Continuation or non-HTTP traffic
2122 0.000023 172.16.1.2       192.168.126.161  HTTP Continuation or non-HTTP traffic
2123 0.000313 172.16.1.2       10.1.1.1         HTTP Continuation or non-HTTP traffic
2124 0.000030 172.16.1.2       192.168.126.161  HTTP Continuation or non-HTTP traffic
2125 0.000007 172.16.1.2       10.1.1.1         HTTP Continuation or non-HTTP traffic
2126 0.000023 172.16.1.2       192.168.126.161  HTTP Continuation or non-HTTP traffic
2127 0.000009 172.16.1.2       10.1.1.1         HTTP Continuation or non-HTTP traffic
2128 0.000023 172.16.1.2       192.168.126.161  HTTP Continuation or non-HTTP traffic
2129 0.001108 172.16.1.2       10.1.1.1         HTTP Continuation or non-HTTP traffic
2130 0.000035 172.16.1.2       192.168.126.161  HTTP Continuation or non-HTTP traffic
2131 0.000008 172.16.1.2       10.1.1.1         HTTP Continuation or non-HTTP traffic
2132 0.000022 172.16.1.2       192.168.126.161  HTTP Continuation or non-HTTP traffic
2133 0.000007 172.16.1.2       10.1.1.1         HTTP Continuation or non-HTTP traffic
REJECT-->
2134 0.000089 10.1.1.1         172.16.1.2       TCP 37854 > http [RST] Seq=111 Win=0 Len=0
CLIENT FIRST ACK-->
2135 0.002421 192.168.126.161  172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=2921 Win=11680 Len=0
2136 0.000033 10.1.1.1         172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=2921 Win=11680 Len=0
2137 0.000007 192.168.126.161  172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=4381 Win=14600 Len=0
2138 0.000014 10.1.1.1         172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=4381 Win=14600 Len=0
2139 0.000008 192.168.126.161  172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=5841 Win=17520 Len=0
2140 0.000014 10.1.1.1         172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=5841 Win=17520 Len=0
2141 0.000007 192.168.126.161  172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=7301 Win=20440 Len=0
2142 0.000013 10.1.1.1         172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=7301 Win=20440 Len=0
2143 0.000007 192.168.126.161  172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=8761 Win=23360 Len=0
2144 0.000015 10.1.1.1         172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=8761 Win=23360 Len=0
2145 0.000007 192.168.126.161  172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=10221 Win=26280 Len=0
2146 0.000013 10.1.1.1         172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=10221 Win=26280 Len=0
2147 0.001059 192.168.126.161  172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=11681 Win=29200 Len=0
2148 0.000018 10.1.1.1         172.16.1.2       TCP 37854 > http [ACK] Seq=111 Ack=11681 Win=29200 Len=0

Saya telah menggali dan mencatat paket traversal sesuai dengan bagan ini dan tampaknya paket yang masuk terakhir 2133 berhasil melewati mentah-PREROUTING, conntrack, mangle-PREROUTING tetapi kemudian hilang. Saya tidak memiliki aturan TOLAK di iptables saya, saya mencatat semua aturan DROP dan tidak ada satupun yang menunjukkan di mana paket 2133 hilang.

Saya ingin menggunakan target TRACE pada filter yang masuk, tetapi sayangnya ubuntu 8.04 tidak dikirimkan dengan dukungan untuk target TRACE.

Jadi saya percaya bahwa beberapa aturan routing / conntrack / mangling implisit internal berlaku untuk beberapa alasan yang mengatur ulang koneksi. Mungkin traffic memicu beberapa perlindungan DOS, tapi saya tidak tahu di mana mengkonfigurasi / menganalisis itu. Yang paling membuat frustrasi adalah bahwa sebuah paket ditolak dan tidak ada yang dicatat ...

Juga meminta file ini berfungsi 100% dari host windows, tetapi gagal pada host Linux tertentu dan 99,9% dari semua permintaan bisa melalui tetapi kadang-kadang waktu paket memicu perilaku ini di firewall kami.

EDIT Ok, sekarang saya telah menambahkan banyak logging di iptables dan sepertinya yang berikut terjadi (masih tidak tahu kenapa!)

Untuk paket yang berhasil melintasi firewall langkah-langkah berikut diambil, tabel / langkah referensi dari sini

Table 3-3 step

2     raw-pre
      conntrack
3     mangle-pre
4     [nat-pre]
5     routing-decision -> destination forward
6     mangle-fwd
7     filter-fwd
8     mangle-post
9     [nat-post]

Paket 2133 yang ditolak melewati langkah-langkah ini:

Table 3-1 steps for the incoming FIN,ACK packet 2133
2     raw-pre
      conntrack
3     mangle-pre
4     [nat-pre]
5     routing-decision -> destination local
6     mangle-input
7     filter-input
8     local process emits RST -> webserver

Table 3-2 steps for the outgoing RST packet 2134 in response to 2133
1     raw-out
2     routing decision
      conntrack
3     mangle-out
      reroute-check
4     [nat-out]
5     filter-out
6     mangle-post
7     nat-post

Hal yang aneh adalah bahwa keputusan routing untuk paket 2133 dalam langkah 5 sekarang berbeda dari keputusan routing untuk paket lainnya. Saat menganalisis permintaan yang berfungsi, mis. Tidak macet, bahkan FIN terakhir akan dialihkan dengan benar. Sepertinya ada bug di kernel atau keputusan routingnya stateful dalam beberapa cara.

EDIT

Satu hal yang dapat menyebabkan masalah ini adalah kenyataan berikut, lalu lintas diarahkan antara firewall dan LAN lokal, sehingga LAN klien tidak terhubung langsung ke firewall melalui L2.

                +---------------------------+       +------------------+                         +------------------------+
                |                           |       |      Router      |   (   Lab network    )  |                        |
( Internet ) -- + eth1                 eth0 +-------+                  +-- (                  ) -+ Client 192.168.126.161 |
                | 10.1.1.1   192.168.60.254 |       |                  |   ( 192.168.126.0/24 )  |                        |
                +---------------------------+       +------------------+                         +------------------------+

Dalam gambar ini, 10.1.1.1 mewakili alamat IP eksternal firewall, semua alamat lainnya adalah alamat IP asli yang digunakan.

Berikut adalah tabel perutean pada firewall:

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.1.1.0        0.0.0.0         255.255.255.240 U     0      0        0 eth1
192.168.126.0   0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.60.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
0.0.0.0         10.1.1.15       0.0.0.0         UG    0      0        0 eth1

Perhatikan bahwa 10.1.1.0 dan default gw 10.1.1.15 dibuat, sisanya persis sama dengan yang digunakan. Saya harus secara manual menambahkan rute 192.168.126.0/24 untuk mencapai jaringan lab dari eth0 (192.168.60.254).

Berikut adalah beberapa log ekstensif pada paket traversal untuk paket terakhir 2133 yang ditolak karena dirutekan ke host lokal (mis. Firewall).

[16406874.374588] raw pre IN=eth1 OUT= MAC=00:02:b3:b9:ff:b5:00:90:1a:10:06:88:08:00 SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=13739 DF PROTO=TCP SPT=80 DPT=53497 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0 
[16406874.374625] mangle pre IN=eth1 OUT= MAC=00:02:b3:b9:ff:b5:00:90:1a:10:06:88:08:00 SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=13739 DF PROTO=TCP SPT=80 DPT=53497 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0 
[16406874.374667] mangle in IN=eth1 OUT= MAC=00:02:b3:b9:ff:b5:00:90:1a:10:06:88:08:00 SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=13739 DF PROTO=TCP SPT=80 DPT=53497 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0 
[16406874.374699] filter in IN=eth1 OUT= MAC=00:02:b3:b9:ff:b5:00:90:1a:10:06:88:08:00 SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=13739 DF PROTO=TCP SPT=80 DPT=53497 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0 
[16406874.374780] mangle out IN= OUT=eth1 SRC=10.1.1.1 DST=172.16.1.2 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=53497 DPT=80 WINDOW=0 RES=0x00 RST URGP=0 
[16406874.374807] mangle post IN= OUT=eth1 SRC=10.1.1.1 DST=172.16.1.2 LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=53497 DPT=80 WINDOW=0 RES=0x00 RST URGP=0 
[16406874.378813] mangle pre IN=eth0 OUT= MAC=00:02:b3:b9:ff:b4:00:90:1a:10:0c:dd:08:00 SRC=192.168.126.161 DST=172.16.1.2 LEN=40 TOS=0x00 PREC=0x00 TTL=63 ID=35424 DF PROTO=TCP SPT=53497 DPT=80 WINDOW=11680 RES=0x00 ACK URGP=0 
[16406874.378863] mangle fwd IN=eth0 OUT=eth1 SRC=192.168.126.161 DST=172.16.1.2 LEN=40 TOS=0x00 PREC=0x00 TTL=62 ID=35424 DF PROTO=TCP SPT=53497 DPT=80 WINDOW=11680 RES=0x00 ACK URGP=0 

Sekali lagi, IP eksternal kami telah diganti dengan 10.1.1.1 dan ip server web di luar jaringan NAT'ed diganti dengan 172.16.1.2

EDIT Breaking News!

Ok percobaan terakhir adalah untuk MENGHENTIKAN paket RST, sangat sangat menarik, saya menambahkan aturan iptables yang menjatuhkan semua paket RST yang ditujukan ke server web kami memiliki masalah meminta file dari. Dan kemudian itu bekerja misalnya FIN, ACK, paket PSH 2133 terakhir di log di atas dihapus, tetapi karena RST dijatuhkan server web memiliki waktu untuk mendapatkan semua semut ACK kemudian memutuskan untuk mentransmisikan kembali paket terakhir, paket 2133 sekali lagi, dan sekarang ia melewati firewall karena modul contrack sekarang telah melihat ACK kembali dari klien dan memungkinkan ACK terakhir, paket FIN dengan muatan terakhir.

Jadi ini jelas merupakan masalah waktu / jendela, file khusus ini, dengan waktu ACK dari klien, memicu sesuatu dalam conntrack yang menolak paket akhir dari server web.

Sejauh ini, googling dan membaca Kernel doc tidak mengungkapkan apa pun yang dapat menyebabkan perilaku ini, langkah selanjutnya adalah membaca kode sumber kernel untuk modul routing / conntrack.

MASALAH DISELESAIKAN

Yah, setidaknya sekarang kita tahu persis apa yang terjadi dan memiliki solusi yang menyelesaikan masalah.

Sergey menunjuk ke -m negara yang sangat berharga - aturan pencocokan INVALID negara yang banyak membantu dalam debugging, saya sekarang menyadari bahwa pengaturan iptables tanpa aturan eksplisit untuk paket INVALID tidak lengkap sehingga perilaku aneh kadang-kadang terjadi.

Ketika mengaktifkan logging dalam modul conntrack untuk apa yang menyebabkan paket tidak valid, apa yang terjadi cukup jelas dan saya curiga mengenai hal ini.

[16659529.322465] nf_ct_tcp: SEQ is over the upper bound (over the window of the receiver) IN= OUT= SRC=172.16.1.2 DST=10.1.1.1 LEN=1004 TOS=0x00 PREC=0x00 TTL=55 ID=40874 DF PROTO=TCP SPT=80 DPT=55498 SEQ=658735108 ACK=1194081763 WINDOW=5840 RES=0x00 ACK PSH FIN URGP=0 

Sekali lagi, 172.16.1.2 adalah server web eksternal (yang berperilaku tidak benar) dan 10.1.1.1 adalah alamat eksternal firewall.

Server web mendorong lebih banyak data melalui kabel daripada yang diiklankan klien di jendela terima (conntrack adalah negara penuh dan memverifikasi ini), tampaknya itu ketika paket FIN tiba yang menghubungkan jaminan karena jendela penerima sebenarnya melebihi banyak sebelumnya.

Saya percaya bahwa itu mungkin disebabkan oleh salah TCP offloading di kartu jaringan di server web. Ketika saya mulai menganalisis ini, saya mengambil tangkapan pada server web dan menurut jejak jumbo frame tcpdump / wireshark ditulis oleh lapisan TCP di kernel yang kemudian disegmentasi ke dalam frame yang lebih kecil dengan MTU = 1500 oleh kartu jaringan. Jadi jelas ini perlu ditekankan di server web karena perilaku TCP yang tidak benar untuk mengirim lebih banyak data daripada penerima memiliki iklan di jendela terima.

Baik Polinomial maupun Sergey memberikan input yang berharga, tetapi Sergey menunjukkan kepada saya perilaku yang tepat dari modul conntrack / NAT terkait paket traversal.

ernelli
sumber
Apakah Anda memiliki pernyataan TOLAK di konfigurasi iptables Anda? Jika demikian, lihat apakah Anda dapat menggunakan pencatatan untuk mencari tahu aturannya.
Ladadadada
Tidak, tidak ada aturan tolak, sepertinya REJECT terjadi di luar iptablesm, itu terjadi selama keputusan routing
ernelli
Apakah mungkin firewall tidak mendukung jendela geser? Bagaimana tangkapan dari klien yang bekerja dibandingkan dengan yang ini?
joeqwerty
Ketika berhasil, terlepas dari semua paket yang diteruskan dengan benar ke klien dan tidak ada paket RST yang dikembalikan, klien mengirimkan ACK sebelum FIN akhir dari server. Saya telah memeriksa dump dari file besar (300k) dan kemudian tidak ada masalah. Jejak dari file kecil juga berfungsi, paket final dengan FIN diteruskan. Bisakah Anda menjelaskan lebih lanjut tentang "firewall tidak mendukung jendela geser"
ernelli
Bisakah Anda memperluas koneksi antara router dan klien lab? Anda memiliki / 24 netmasks pada 60 dan 126 sehingga tidak jelas bagaimana klien lab dapat mengirimkan lalu lintas? Apakah netmask mereka bukan / 24? Apakah semacam proxy arp sedang terjadi? Apakah ada alias pada eth0: 1 untuk 126.0 / 24?
polinomial

Jawaban:

9

Situasi serupa dijelaskan di http://www.spinics.net/lists/netfilter/msg51408.html : beberapa paket yang seharusnya diproses oleh NAT entah bagaimana ditandai sebagai INVALID dan bukannya ESTABLISHED, dan pergi ke rantai INPUT. Anda harus menambahkan beberapa aturan dengan -m state --state INVALIDuntuk memeriksa ini, dan jawabannya di http://www.spinics.net/lists/netfilter/msg51409.html menunjukkan bahwa paket INVALID tersebut harus selalu DIHENTIKAN, karena NAT tidak dijalankan dengan benar , oleh karena itu alamat di dalamnya mungkin salah.

Jika paket Anda yang bermasalah benar-benar ditandai sebagai INVALID, menambahkan iptables -I INPUT -m state --state INVALID -j DROPmungkin akan mengatasi masalah (paket yang rusak tidak akan sampai ke proses lokal dan tidak akan menyebabkan respons RST, maka TCP akan pulih dari paket yang hilang setelah batas waktu). Kemudian Anda dapat mencoba men-debug masalah lebih lanjut, seperti dijelaskan dalam http://www.spinics.net/lists/netfilter/msg51411.html :

echo 255 >/proc/sys/net/netfilter/nf_conntrack_log_invalid

(Dalam kasus khusus itu masalahnya disebabkan oleh beberapa perangkat keras jaringan yang rusak di sepanjang jalan, mungkin dikombinasikan dengan beberapa kerusakan TCP checksum offload.)

Sergey Vlasov
sumber
4

Saya telah melihat perilaku ini pada tipe firewall lain dan perilaku itu sangat identik saya pikir saya akan membuangnya di sana.

Masalah yang saya miliki adalah bahwa firewall sedang menuju ke ruang yang sama dengan port fana di kotak. Ini akan menyebabkan perilaku yang tepat ini jika keduanya bertabrakan karena kernel sekarang berasumsi koneksi dimaksudkan untuk mesin lokal. Untuk tujuan ini ada beberapa hal yang dapat Anda periksa. Pertama, Anda menentukan konfigurasi port keluar di iptables (menggunakan --to-ports)? Atau sudahkah Anda mengubah rentang port sementara pada mesin:

$ cat /proc/sys/net/ipv4/ip_local_port_range

Untuk mendiagnosis Anda dapat mengatur penangkapan Anda dan melihat apakah Anda melihat permintaan lain menggunakan ip fw eksternal yang sama, kombo port dalam waktu 3 * MSL sebelum RST (~ saya kira 180-an).

Meskipun saya belum yakin bahwa itu adalah jawabannya, jika saya berada dalam situasi ini, saya akan mengesampingkannya terlebih dahulu dan kemudian melihat beberapa hal lainnya.

Apakah ini mudah direproduksi? Apakah mungkin untuk mendapatkan lebih banyak diagnostik dari kotak firewall dan melihat masalah terjadi? Saya akan mencoba menangkap:

$ netstat -anp
$ cat /proc/net/ip_conntrack

setiap detik saat mencoba mereproduksi dan melihat apakah ada sesuatu yang mengikat secara lokal ke port dan seperti apa meja topeng yang terlihat selama masalah.

Jika Anda firewall keluar RST apakah ACK akhirnya dari klien internal menyebabkan koneksi berhasil?

Hal terakhir, apakah Anda melihat semua log? Sudahkah Anda memeriksa dmesg? Sudahkah Anda mengatur *. * Pada kotak firewall di konfigurasi syslog ke file untuk memastikan?

Beri tahu saya apa yang Anda temukan! Saya sangat menghargai jumlah informasi yang Anda berikan dalam pertanyaan, terima kasih.

jumlahnya banyak
sumber
Terima kasih atas usaha Anda, saya dapat mereproduksi kesalahan 100%, semua permintaan melalui firewall berfungsi kecuali sangat sedikit. Mereka yang tidak bekerja tampaknya mengalami masalah ukuran / waktu yang tepat. Saya dapat menambahkan beberapa jejak Wireshark untuk permintaan yang lebih besar / lebih kecil antara klien / server web yang sama melalui firewall yang semuanya berfungsi, tetapi jejak di atas adalah yang macet. Saya telah menambahkan info baru di atas yang mungkin bisa menjelaskan masalah ini.
ernelli
/ proc / sys / net / ipv4 / ip_local_port_range diatur ke [32768 61000] netstat tidak menunjukkan port yang terikat secara lokal. ip_conntrack menunjukkan koneksi sebagai establised, mis. percaya bahwa itu masih terbuka sejak FIN terakhir belum diteruskan ke klien. Statusnya adalah paket = 10 byte = 12084 tanda [TERJAMIN] = 0 secmark = 0 use = 1
ernelli