Jawaban:
TCP ACK dasar mengatakan "Saya menerima semua byte hingga X." ACK selektif memungkinkan Anda untuk mengatakan "Saya menerima byte XY, dan VZ."
Jadi, misalnya, jika sebuah host mengirimi Anda 10.000 byte dan byte 3000-5000 hilang dalam perjalanan, ACK akan mengatakan "Saya mendapatkan semuanya hingga 3000." Ujung lainnya harus mengirim byte 3001-10000 lagi. SACK bisa mengatakan "Saya mendapat 1000-2999, dan 5001-10000" dan tuan rumah hanya akan mengirim 3000-5000.
Ini sangat bagus untuk bandwidth tinggi, link lossy (atau delay tinggi). Masalahnya adalah itu dapat menyebabkan masalah kinerja yang parah dalam keadaan tertentu. ACK TCP normal akan membuat server memperlakukan bandwidth tinggi, koneksi lossy dengan sarung tangan anak (kirim 500 byte, tunggu, kirim 500 byte, tunggu, dll). SACK memungkinkannya beradaptasi dengan penundaan tinggi karena ia tahu persis berapa banyak paket yang benar - benar hilang.
Di sinilah hal-hal buruk dapat terjadi. Seorang penyerang dapat memaksa server Anda untuk menyimpan antrian pengiriman ulang besar-besaran untuk waktu yang lama, kemudian memproses seluruh masalah sialan itu berulang-ulang. Ini dapat mematok CPU, memakan RAM, dan mengkonsumsi bandwidth lebih dari yang seharusnya. Singkatnya, sistem yang ringan dapat memulai DoS terhadap server yang lebih besar.
Jika server Anda kuat dan tidak melayani file besar, Anda cukup terisolasi ini.
Jika Anda sebagian besar melayani pengguna intranet atau kelompok latensi rendah lainnya, SACK tidak membeli apa pun dan dapat dimatikan karena alasan keamanan tanpa kehilangan kinerja.
Jika Anda menggunakan tautan bandwidth rendah (katakanlah 1Mbps atau kurang sebagai aturan praktis yang sepenuhnya arbitrer), SACK dapat menyebabkan masalah dalam operasi normal dengan menjenuhkan koneksi Anda dan harus dimatikan.
Pada akhirnya, terserah Anda. Pertimbangkan apa yang Anda layani, kepada siapa, dari apa, dan timbang tingkat risiko Anda terhadap efek kinerja SACK.
Ada ikhtisar besar tentang SACK dan kerentanannya di sini.
Alasan lain mengapa TCP SACK sering dinonaktifkan adalah karena ada banyak sekali peralatan jaringan di luar sana yang gagal menangani opsi ini dengan benar. Kami melihat ini sepanjang waktu dengan produk transfer file berkecepatan tinggi yang kami sediakan yang menggunakan TCP. Masalah yang paling umum adalah perangkat gateway yang melakukan hal-hal seperti mengacak nomor urut untuk paket-paket TCP yang transit melalui perangkat dari jaringan internal ke eksternal, tetapi itu tidak "mengacak-acak" opsi TCP SACK yang mungkin dikirim dari jarak jauh. akhir. Jika nilai SACK aktual tidak diterjemahkan kembali ke nilai yang tepat oleh perangkat ini, maka sesi TCP tidak akan pernah lengkap dalam menghadapi hilangnya paket ketika ujung jarak jauh mencoba menggunakan SACK untuk mendapatkan manfaat ACK selektif.
Mungkin ini akan menjadi sedikit masalah jika orang lebih agresif menerapkan pemeliharaan perangkat lunak pencegahan untuk gigi ini, tetapi mereka cenderung tidak.
Saya dapat mengkonfirmasi dari pengalaman pahit bahwa tcp_sack = 1 menyebabkan transfer data terhenti di atas sftp / rsync / scp dll dengan file lebih dari sekitar 12mb saat menggunakan peralatan firewall Cisco ASA tertentu.
SETIAP Waktu itu akan terhenti.
Kami mentransfer melalui tautan 100mbps khusus antara host A dan host B di dua pusat data yang berbeda, keduanya menggunakan cisco firewall dan mengganti perangkat keras dengan centos.
Ini agak dapat dikurangi dengan memodifikasi ukuran buffer - misalnya saya tidak bisa mentransfer file 1GB melalui sftp dari host A ke host B kecuali jika saya mengatur buffer sftp ke 2048, tetapi saya bisa mengabaikan apakah host B menarik file dari A.
Eksperimen dengan file yang sama menggunakan rsync dan penyetelan kirim / terima buffer memungkinkan saya untuk bangun sekitar 70mb dari file 1GB yang didorong dari A ke B.
Namun, jawaban utamanya adalah untuk menonaktifkan tcp_sack pada host A. Awalnya dengan menetapkan tcp_sack = 0 di kernel on-the-fly - tetapi pada akhirnya - saya menambahkannya ke /etc/sysctl.conf saya