GNU/Linux >> Belajar Linux >  >> Linux

Masalah antrian TIME_WAIT

Baru-baru ini, Kami menjelaskan cara mengkonfigurasi server Anda untuk beban tinggi dan pencegahan DDoS. Hari ini, Kami akan berbicara tentang masalah antrian time_wait. Mereka yang mengembangkan layanan yang secara aktif bekerja dengan jaringan dapat menginjak fitur protokol TCP:transisi banyak (atau semua port gratis) ke status TIME_WAIT. Ada banyak informasi dangkal di Internet dan banyak informasi yang tidak sepenuhnya benar. Kami akan mempertimbangkan situasi ini dan menentukan kemungkinan jalan keluarnya.

Protokol TCP:koneksi ditutup

Berikut ini adalah diagram siklus hidup koneksi TCP:

Skema seumur hidup TCP

Kami tidak akan mempertimbangkannya secara keseluruhan tetapi fokus pada bagian terpenting bagi kami – menutup koneksi. Pihak yang memprakarsai penutupan koneksi disebut "aktif", dan yang kedua - adalah "pasif". Dan tidak masalah siapa di antara mereka yang memulai koneksi.

Dari sisi "pasif", semuanya sederhana. Setelah menerima paket FIN, sistem harus menanggapinya dengan paket ACK yang sesuai tetapi memiliki hak untuk melanjutkan pengiriman data. Sejak menerima paket FIN, koneksi di sisi pasif dalam keadaan CLOSE_WAIT. Saat siap, paket FIN respons dikirim, setelah itu pihak menunggu paket ACK ke sana. Setelah menerima ACK ke FIN respons, koneksi untuk sisi pasif ditutup.

Dari sudut pandang sisi "aktif", semuanya agak lebih rumit. Setelah mengirimkan paket FIN, sisi aktif masuk ke FIN_WAIT_1. Selanjutnya, tiga situasi mungkin terjadi:

  1. Menerima ACK pada paket FIN. Status ini ditunjukkan oleh FIN_WAIT_2, data dapat dikirim ke samping, setelah itu paket respons FIN diharapkan, di mana sisi aktif merespons dengan ACK dan menempatkan koneksi ke status TIME_WAIT.
  2. Jika sisi pasif siap untuk menutup sesi, maka respons FIN dapat diterima dengan ACK simultan ke paket FIN asli. Dalam hal ini, sisi aktif merespons dengan ACK dan mentransfer koneksi ke TIME_WAIT, melewati FIN_WAIT_2.
  3. Situasi mungkin terjadi ketika para pihak secara bersamaan memulai penutupan. Dalam hal ini, kedua sisi "aktif", di kedua sisi koneksi masuk ke status TIME_WAIT.

Seperti yang dapat dilihat dari diagram dan deskripsi, sisi aktif mengirimkan paket terakhir dalam sesi (ACK ke FIN pasif). Karena dia tidak dapat mengetahui apakah paket ini diterima, statusnya adalah TIME_WAIT. Dalam keadaan ini, koneksi harus 2 * MSL (masa pakai paket maksimum):waktu pengiriman paket ke sisi pasif + waktu pengiriman paket respons yang mungkin kembali. Dalam prakteknya, saat ini, timer TIME_WAIT disetel ke 1 – 2 menit. Setelah penghitung waktu ini berakhir, koneksi dianggap ditutup.

masalah TIME_WAIT untuk koneksi keluar

Koneksi dalam sistem operasi diidentifikasi oleh empat parameter:IP lokal, port lokal, IP jarak jauh, port jarak jauh. Misalkan kita memiliki klien yang secara aktif menghubungkan/memutuskan sambungan ke layanan jarak jauh. Karena IP dan port jarak jauh tetap tidak berubah, port lokal baru dialokasikan untuk setiap koneksi baru. Jika klien adalah sisi aktif dari akhir sesi TCP, maka koneksi ini akan diblokir untuk sementara waktu dalam status TIME_WAIT. Jika koneksi dibuat lebih cepat daripada karantina port, maka saat koneksi dicoba berikutnya, klien akan menerima kesalahan EADDRNOTAVAIL (errno =99).

Bahkan jika aplikasi mengakses layanan yang berbeda dan kesalahan tidak terjadi, antrian TIME_WAIT akan bertambah, mengambil sumber daya sistem. Koneksi dalam status TIME_WAIT dapat dilihat melalui netstat, lebih mudah untuk melihat informasi umum dengan utilitas ss (dengan kunci -s).

Apa yang bisa dilakukan:

  • Interval TIME_WAIT Linux tidak dapat diubah tanpa mengkompilasi ulang kernel. Di Internet, Anda dapat menemukan referensi ke parameter net.ipv4.tcp_fin_timeout dengan kata-kata "di beberapa sistem, itu mempengaruhi TIME_WAIT". Namun, apa sistem ini tidak jelas. Menurut dokumentasi, parameter menentukan waktu tunggu maksimum untuk paket FIN respons, yaitu membatasi waktu yang dihabiskan oleh koneksi di FIN_WAIT_2, tetapi tidak TIME_WAIT.
  • Buka lebih sedikit koneksi. Kesalahan paling sering diamati selama interaksi jaringan dalam cluster. Dalam hal ini, menggunakan Keep-Alive akan menjadi keputusan yang bijaksana.
  • Saat mendesain layanan, mungkin masuk akal untuk menggeser TIME_WAIT ke sisi lain, yang karenanya kita harus menahan diri untuk tidak memulai penutupan koneksi TCP jika memungkinkan.
  • Jika sulit untuk mengurangi jumlah koneksi, maka masuk akal untuk memulai layanan jarak jauh pada beberapa port dan mengaksesnya secara bergantian.
  • Parameter kernel “net.ipv4.ip_local_port_range” menetapkan kisaran port yang digunakan untuk koneksi keluar. Jangkauan lebih luas – lebih banyak koneksi tersedia untuk satu layanan jarak jauh.
  • Cara yang sulit dan sangat berbahaya:kurangi nilai parameter net.ipv4.tcp_max_tw_buckets ke nilai yang lebih kecil dari jumlah IP dalam rentang dari ip_local_port_range. Parameter ini menetapkan ukuran maksimum antrian TIME_WAIT dan digunakan untuk melindungi dari serangan DOS. "Trik" ini dapat digunakan sementara sampai solusi yang tepat dikembangkan.
  • Aktifkan parameter net.ipv4.tcp_tw_reuse. Parameter ini memungkinkan penggunaan koneksi dalam status TIME_WAIT untuk koneksi keluar.
  • Aktifkan parameter net.ipv4.tcp_tw_recycle.
  • Gunakan mode SO_LINGER (diatur melalui setsockopt). Dalam hal ini, sesi TCP tidak akan ditutup (pertukaran paket FIN) tetapi dibuang. Pihak yang ingin melakukan reset mengirimkan paket RST. Setelah menerima paket ini, koneksi dianggap dihentikan. Namun, menurut protokol, pengiriman paket RST harus dilakukan hanya jika terjadi kesalahan (menerima data yang jelas-jelas tidak terkait dengan koneksi ini).

TIME_WAIT di server

Bahaya utama dari perluasan antrian TIME_WAIT di server adalah kehabisan sumber daya.

Namun demikian, mungkin ada insiden yang tidak menyenangkan saat bekerja dengan klien NAT (ketika sejumlah besar klien server berada di belakang satu IP). Dalam kasus waktu karantina port kecil di Firewall, kemungkinan besar server akan menerima permintaan koneksi dari port yang sama, koneksi yang belum ditutup (terletak di TIME_WAIT). Dalam hal ini, dua-tiga skenario dimungkinkan:

  • Pelanggan (tidak mungkin) akan menebak nomor SEQ, yang sangat tidak mungkin. Dalam hal ini, perilaku tidak ditentukan.
  • Klien akan mengirim paket dengan paket yang salah (dari sudut pandang server, nomor SEQ), yang akan ditanggapi oleh server dengan paket ACK terakhir, yang tidak lagi dipahami klien. Klien biasanya mengirimkan RST ke ACK ini dan menunggu beberapa detik sebelum upaya koneksi baru. Jika parameter “net.ipv4.tcp_rfc1337” dinonaktifkan di server (dinonaktifkan secara default), upaya baru akan berhasil. Namun, terutama karena batas waktu, penurunan kinerja akan terlihat.
  • Jika, dalam situasi yang dijelaskan di hal.2, parameter net.ipv4.tcp_rfc1337 diaktifkan, server akan mengabaikan paket RST klien. Upaya berulang untuk menyambung ke server dari port yang sama akan gagal. Untuk klien, layanan tidak akan tersedia.

Apa yang bisa dilakukan di sisi server.

  1. Coba alihkan inisiasi penutupan koneksi ke klien. Dengan demikian, batas waktu yang wajar harus ditetapkan.
  2. Hati-hati dengan parameter net.ipv4.tcp_max_tw_buckets. Menyetelnya terlalu besar akan membuat server rentan terhadap serangan DOS.
  3. Gunakan SO_LINGER untuk kueri yang jelas salah. Jika klien terhubung dan mengirim "omong kosong", maka kemungkinan ada serangan yang lebih baik menghabiskan jumlah sumber daya minimum.
  4. Aktifkan net.ipv4.tcp_tw_recycle jika Anda yakin klien tidak melalui NAT. Penting untuk dicatat bahwa net.ipv4.tcp_tw_reuse tidak mempengaruhi pemrosesan koneksi yang masuk.
  5. Dalam beberapa kasus, masuk akal untuk tidak "melawan" antrean, tetapi mendistribusikannya dengan benar. Secara khusus, resep berikut dapat membantu:
    • Saat menggunakan penyeimbang L7, semua paket berasal dari IP yang sama, yang memicu "hit" dalam koneksi TIME_WAIT, tetapi dalam kasus ini, Anda dapat mengaktifkan tcp_tw_recycle dengan aman.
    • Saat menggunakan penyeimbang L3, server melihat alamat IP sumber. Penyeimbangan IP-HASH, pada saat yang sama, akan meneruskan semua koneksi untuk satu NAT ke satu server, yang juga meningkatkan kemungkinan tabrakan. Round-Robin lebih dapat diandalkan dalam hal ini.
    • Hindari penggunaan NAT di dalam jaringan jika memungkinkan. Jika perlu, lebih baik memilih terjemahan 1-in-1.
    • Anda dapat meningkatkan jumlah koneksi yang tersedia dengan menghosting layanan di beberapa port. Misalnya, untuk server WEB, beban dapat diseimbangkan tidak pada satu port ke-80, tetapi pada kumpulan port.
  6. Jika masalah disebabkan oleh NAT di dalam jaringan, Anda dapat mengatasi situasi tersebut dengan mengkonfigurasi ulang terjemahan pada perangkat jaringan:perlu untuk memastikan bahwa waktu "karantina" port pada NAT lebih lama dari TIME_WAIT. Namun dalam kasus ini, risiko kehabisan port pada penerjemah NAT meningkat (sebagai opsi, terjemahan tidak ke satu IP, tetapi ke kumpulan).

Parameter kernel net.ipv4.tcp_tw_reuse dan net.ipv4.tcp_tw_recycle

Ada dua parameter di kernel Linux yang memungkinkan Anda melanggar persyaratan protokol TCP, membebaskan koneksi dari TIME_WAIT lebih cepat dari jadwal. Kedua opsi ini didasarkan pada stempel waktu TCP ekstensi (menandai paket dengan stempel waktu relatif).

net.ipv4.tcp_tw_reuse memungkinkan Anda menggunakan koneksi pada TIME_WAIT untuk koneksi keluar baru. Dalam hal ini, stempel waktu koneksi TCP baru harus urutan besarnya lebih besar dari nilai terakhir di sesi sebelumnya. Dalam hal ini, server akan dapat membedakan paket "terlambat" dari koneksi sebelumnya dari koneksi saat ini. Menggunakan parameter aman dalam banyak kasus. Masalah dapat muncul jika ada firewall "pelacakan" di sepanjang jalur yang memutuskan untuk tidak melewatkan paket dalam koneksi, yang seharusnya dalam TIME_WAIT.

net.ipv4.tcp_tw_recycle mengurangi waktu koneksi dalam antrian TIME_WAIT ke nilai RTO (Re-Transmission Time-Out), yang dihitung berdasarkan Round-Trip-Time (RTT) dan penyebaran nilai ini. Pada saat yang sama, nilai stempel waktu TCP terakhir disimpan di kernel, dan paket dengan nilai lebih rendah dibuang begitu saja. Opsi ini akan membuat layanan tidak tersedia untuk klien di belakang NAT jika stempel waktu TCP dari klien "dilewati" selama penerjemahan (jika NAT menghapusnya atau menggantinya dengan milik mereka, tidak akan ada masalah). Karena tidak mungkin untuk memprediksi pengaturan perangkat eksternal, opsi ini sangat tidak disarankan untuk dimasukkan pada server yang dapat diakses dari Internet. Selain itu, pada server “internal” di mana tidak ada NAT (atau opsi 1-in-1 digunakan), opsi ini aman.


Linux
  1. Ssh – Menggunakan Saluran Ssh yang Sudah Ada?

  2. Linux – Mendeteksi Koneksi/Pemutusan Headphone Di Linux?

  3. Bagaimana Memantau Koneksi Serial @ 250000 Baud?

  1. Kegagalan Koneksi RDP:Sertifikat yang Ditandatangani Sendiri Kedaluwarsa

  2. Contoh perintah koneksi iSCSI (Lembar Cheat)

  3. Bagaimana cara menghapus koneksi soket CLOSE_WAIT

  1. nyamuk-klien mendapatkan koneksi yang ditolak

  2. Bagaimana cara keluar dari koneksi SSH?

  3. 2 Printer 1 Antrian