Я смотрел параметры настройки Linux и видел некоторые конфигурации, в которых SACK отключен. Кто-нибудь может это объяснить?
Это будет настройка для загруженного веб-сервера.
Базовый TCP ACK говорит: «Я получил все байты до X». Селективный ACK позволяет сказать «Я получил байты X-Y и V-Z».
Так, например, если хост отправил вам 10 000 байтов, а байты 3000-5000 были потеряны при передаче, ACK скажет: «Я получил все до 3000». Другой конец должен снова послать байты 3001-10000. SACK мог сказать: «Я получил 1000–2999 и 5001–10000», и хост просто отправит 3000–5000.
Это отлично подходит для связи с высокой пропускной способностью, потерями (или высокой задержкой). Проблема в том, что при определенных обстоятельствах это может вызвать серьезные проблемы с производительностью. Обычные TCP ACK заставят сервер обрабатывать высокоскоростное соединение с потерями с помощью детских перчаток (отправить 500 байтов, ждать, отправить 500 байтов, ждать и т. Д.). SACK позволяет ему адаптироваться к высокой задержке, потому что он точно знает, сколько пакетов было фактически потерянный.
Вот где могут случиться плохие вещи. Злоумышленник может заставить ваш сервер поддерживать огромную очередь на повторную передачу в течение длительного времени, а затем обрабатывать эту чертову штуку снова и снова. Это может привести к перегрузке процессора, потреблению оперативной памяти и увеличению пропускной способности, чем следовало бы. Короче говоря, облегченная система может инициировать DoS против более мощного сервера.
Если ваш сервер надежен и не обслуживает большие файлы, вы хорошо защищены от этого.
Если вы в основном обслуживаете интрасеть или другую группу пользователей с низкой задержкой, SACK ничего вам не покупает и может быть отключен по соображениям безопасности без потери производительности.
Если вы используете канал с низкой пропускной способностью (скажем, 1 Мбит / с или меньше, как совершенно произвольное практическое правило), SACK может вызвать проблемы при нормальной работе, насыщая ваше соединение, и его следует отключить.
В конечном итоге решать только вам. Подумайте, что вы обслуживаете, кому, от чего, и взвесьте степень вашего риска с влиянием SACK на производительность.
Есть отличный обзор SACK и его уязвимостей. Вот.
Другая причина, по которой TCP SACK часто отключается, заключается в том, что существует огромное количество сетевого оборудования, которое не может правильно обработать эту опцию. Мы постоянно наблюдаем это с помощью предоставляемого нами продукта для высокоскоростной передачи файлов, использующего TCP. Наиболее распространенной проблемой является проблема устройств шлюза, которые делают такие вещи, как рандомизацию порядковых номеров для пакетов TCP, проходящих через устройство из внутренних сетей во внешние, но которые не "не рандомизируют" параметры TCP SACK, которые могут быть отправлены с удаленного устройства. конец. Если фактические значения SACK не преобразуются обратно в правильные значения этими устройствами, то сеанс TCP никогда не будет завершен перед лицом потери пакетов, когда удаленный конец пытается использовать SACK для получения преимуществ выборочного ACK.
Возможно, это было бы меньшей проблемой, если бы люди стали более агрессивно применять профилактическое обслуживание программного обеспечения к этому оборудованию, но они, как правило, не делают этого.
Я могу подтвердить из горького опыта, что tcp_sack = 1 вызывает остановку передачи данных через sftp / rsync / scp и т. Д. С файлами размером более 12 МБ при использовании определенных устройств межсетевого экрана Cisco ASA.
КАЖДЫЙ раз он останавливался.
Мы передавали по выделенному каналу 100 Мбит / с между хостом A и хостом B в двух разных центрах обработки данных, используя брандмауэр cisco и коммутируемое оборудование с centos.
Это можно несколько смягчить, изменив размеры буфера - например, Я не мог передать файл размером 1 ГБ через sftp с хоста A на хост B, если я не установил буфер sftp на 2048, но я мог бы независимо от того, извлекал ли хост B файл из A.
Эксперименты с одним и тем же файлом с использованием rsync и настройки буфера отправки / получения позволили мне получить около 70 МБ файла размером 1 ГБ, перемещенного из A в B.
Однако окончательным ответом было отключить tcp_sack на хосте A. Первоначально, установив tcp_sack = 0 в ядре на лету, но в конечном итоге я добавил его в свой /etc/sysctl.conf