Situasinya seperti ini:
http client ----> corporate firewall ----> http server
Karena keepalive, server dan klien akan menjaga koneksi TCP tetap terbuka dan klien akan menggunakan kumpulan koneksi untuk permintaan HTTP.
Firewall memiliki aturan untuk "membunuh" koneksi TCP lama setelah 1 jam. Masalahnya adalah bahwa klien HTTP kami tidak akan mendeteksi bahwa koneksi TCP hancur dan ia mencoba untuk menggunakan kembali koneksi yang pada dasarnya mati yang di pihak kami tampak seperti klien "digantung" setelah jangka waktu tertentu. Permintaan akan hang, maka yang berikutnya akan berfungsi, mungkin karena koneksi baru dibuat.
Pertanyaannya di sini adalah mekanisme apa yang digunakan firewall untuk mematikan koneksi TCP dengan cara yang tidak dapat dideteksi oleh klien HTTP kami. Saya mencoba mereproduksi perilaku ini secara lokal dalam beberapa cara:
- Bunuh koneksi TCP pada router vyos kami, Wireshark di sisi klien menangkap TCP FIN-ACK. baik
- Membunuh sisi klien koneksi TCP di TCPView pada Windows, Wireshark mendeteksi TCP RST di sisi klien. baik
- Memblokir port setelah koneksi terjalin ke firewall sisi klien, menghasilkan pengecualian reset soket. baik
Saya memiliki dump Wireshark di sisi server dan saya mencoba mencari tahu apakah firewall mengirim FIN atau RST dengan ip.dst==serverip && (tcp.flags.reset==1 || tcp.flags.fin==1)
tetapi tidak ada yang muncul.
Selain itu, penangkapan Wireshark di sisi klien menunjukkan masalah ketika permintaan HTTP keluar, diikuti oleh selusin transmisi ulang TCP, akhirnya tidak ke mana-mana.
Klien HTTP adalah klien Java asli dan / atau HTTP HTTP (mencoba keduanya), keduanya gagal mendeteksi koneksi TCP yang mati. Saya ingin mereproduksi perilaku secara lokal tetapi saya tidak dapat mencari tahu dengan cara apa firewall mematikan koneksi, oleh karena itu mencari kemungkinan jawaban.
Jawaban:
Anda tidak menyebutkan jenis firewallnya, tetapi saya menduga sebagian besar hanya menjatuhkan paket.
Yang cenderung mengkonfirmasi ini.
sumber
Kemungkinan besar firewall baru saja menjatuhkan paket tanpa mengirim paket RST, mungkin setelah memukul semacam sesi timeout. Ini biasanya merupakan perilaku yang dapat dikonfigurasi.
Saya pribadi lebih suka mengirim paket RST secara tepat karena membantu klien berperilaku normal, tetapi saya telah mendengar argumen yang menyatakan bahwa ini tidak boleh dilakukan pada firewall yang menghadap ke luar untuk menghindari memberikan umpan balik apa pun kepada penyerang potensial.
Saya telah melihat penyebab ini beberapa masalah karena klien biasanya tidak menangani skenario seperti ini dengan sangat elegan. Pada dasarnya, mereka terus mencoba kembali melalui sesi TCP asli (yang sekarang sudah mati) dan tidak pernah mencoba untuk membangun kembali yang baru. Akhirnya batas waktu sisi klien memicu dan pengguna mendapat pesan kesalahan yang tidak menyenangkan. Menyiapkan HTTP keepalive dengan tepat untuk aplikasi dapat membantu memperbaikinya.
sumber
@Ron Trunk persis benar, hampir pasti koneksi terbuka sedang dihapus baik secara aktif (aturan ditolak dimasukkan) atau secara pasif (dihapus dari koneksi yang dikenal dan tidak diizinkan untuk dibuat kembali tanpa sinkronisasi). Salah satu komentar menyarankan untuk mencobanya sendiri. Berikut adalah resep untuk melakukannya dengan menggunakan ruang nama jaringan linux. Ini mengasumsikan bahwa penerusan ip diaktifkan di kernel host Anda, Anda root, dan mungkin hal-hal lain.
Anda kemudian membutuhkan tiga windows / shells / layar / terminal. Jalankan setiap perintah di bawah ini di terminal yang berbeda:
ip netns exec three socat TCP-LISTEN:5001 STDIO
ip netns exec one socat STDIO TCP:3.3.3.3:5001
Perhatikan bahwa setelah menjalankan perintah ini, semua yang Anda ketikkan dalam satu jendela akan tercermin di jendela lainnya, dan sebaliknya (setelah kembali). Jika itu tidak benar, Anda mungkin perlu mengaktifkan penerusan ip.
ip netns exec two iptables -I FORWARD -j DROP
Maka apa pun yang Anda ketik tidak akan diizinkan masuk.
Anda dapat mensimulasikan metode penurunan yang kurang aktif dengan aturan penerusan (yang belum diuji) seperti:
Lihat /unix/127081/conntrack-tcp-timeout-for-state-stablished-not-working dan https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl .txt untuk informasi tentang cara mengatur batas waktu - meskipun tidak jelas bagi saya bahwa iptables secara native mendukung masa koneksi maksimum; Saya percaya semua timeout adalah timeout idle.
Bersihkan dengan
ip netns del one; ip netns del two; ip netns del three
sumber
Firewall dapat mengirim paket ICMP yang menunjukkan bahwa target tidak dapat dijangkau. Untuk apa pun selain TCP, itulah satu-satunya indikasi kesalahan yang mungkin terjadi, misalnya mengirim paket ke port UDP yang tertutup akan menghasilkan pesan "destination unreachable" dengan kode alasan yang diatur ke "port unreachable".
Dimungkinkan juga untuk mengirim pesan "port unreachable" sebagai respons terhadap paket TCP, ini juga mengakhiri koneksi, tetapi siapa pun yang menganalisis dump paket akan melihat bahwa ini tidak biasa, karena konvensi TCP adalah untuk mengindikasikan port tertutup dengan RST.
Pengirim diharapkan memetakan paket kesalahan ICMP yang diterima kembali ke koneksi asal dan menanganinya dengan tepat, sehingga paket kesalahan yang dihasilkan firewall juga dapat digunakan untuk mengakhiri koneksi TCP. Paket ICMP berisi salinan tajuk paket yang menyinggung untuk memungkinkan pemetaan ini.
sumber