Тонкая настройка протокола TCP
Что такое тонкая настройка протокола TCP, какие параметры доступны и как их установить.
Что такое
Тонкая настройка протокола TCP — изменение параметров сетевого соединения, по которому Application Delivery Controller общается с клиентом и upstream-сервером.
Зачем нужна
Тонкая настройка позволяет адаптировать параметры TCP под специфику вашего трафика. Например:
-
задать лимиты подключений, которые система удерживает в очереди до начала обработки;
-
управлять объёмом памяти для приёма и отправки данных в каждом соединении;
-
ускорить освобождение ресурсов и портов после закрытия старых сессий (состояние TIME_WAIT);
-
настроить реакцию TCP на потери и переупорядочивание пакетов;
-
настроить защиту от SYN-флуда и аномального трафика;
-
настроить частоту контрольных запросов (keep-alive) и переотправку данных для зависших сессий.
Как работает
Application Delivery Controller работает в среде Linux, где за установку и поддержку TCP-сессий отвечает ядро системы. Чтобы изменить логику обработки трафика, нужно передать ядру новые параметры через утилиту sysctl.
Процесс выглядит так:
-
вы подключаетесь к консоли сервера по SSH;
-
передаёте ядру новое значение нужного параметра (например, увеличиваете размер очереди);
-
ядро применяет настройки и начинает обрабатывать трафик по новым правилам;
-
данные поступают и передаются через обновлённый сетевой стек.
Где хранятся параметры
Значения параметров задаются в конфигурационных файлах. Это либо основной файл /etc/sysctl.conf, либо отдельные файлы с расширением .conf в одном из системных каталогов:
| Каталог | Назначение | Приоритет |
|---|---|---|
|
Для настроек системного администратора |
Высший |
|
Для временных конфигураций, создаваемых во время работы системы |
Средний |
|
Для настроек, поставляемых с пакетами дистрибутива |
Низший |
В файлах уже содержатся параметры, необходимые для оптимальной работы Application Delivery Controller. Если параметра в файлах нет, ядро использует значение по умолчанию.
При перезагрузке системы или принудительном применении настроек, ядро обрабатывает все эти файлы по двум правилам:
-
Приоритет каталогов. Для файлов с одинаковым именем, расположенных в разных каталогах, приоритет такой:
/etc/ > /run/ > /usr/lib/. Файл из более приоритетного каталога переопределяет одноимённый файл из менее приоритетного. Так файл50-balancer.confв/etc/sysctl.d/переопределит файл50-balancer.confв/usr/lib/sysctl.d/. -
Лексикографический порядок. Файлы с разными именами обрабатываются в алфавитном порядке. Если один параметр указан в нескольких файлах, итоговое значение берётся из файла, имя которого идёт последним по алфавиту. Так файл
99-balancer.confпереопределит10-balancer.conf, даже если оба лежат в одном каталоге.
Как посмотреть текущие параметры
Чтобы проверить, какие настройки использует ваша система, воспользуйтесь следующими командами:
Для просмотра одного параметра
sysctl net.ipv4.tcp_sack
Для просмотра группы параметров
sysctl net.ipv4.tcp_*
Команда выводит все параметры, имена которых начинаются с указанного префикса.
Как установить параметры
Временная установка
Параметры записываются напрямую в оперативную память ядра. После перезагрузки системы значения вернутся к тем, что указаны в конфигурационном файле.
Чтобы изменить один параметр, выполните команду:
sudo sysctl -w net.ipv4.tcp_fin_timeout=30
Чтобы изменить несколько параметров одной командой, перечислите их через пробел:
sudo sysctl -w net.core.somaxconn=65535 net.ipv4.tcp_max_syn_backlog=8192
Постоянная установка
Параметры фиксируются в конфигурационном файле. Система считывает и применяет указанные значения при каждом запуске.
Внесите изменения в нужный конфигурационный файл или создайте под свои настройки отдельный файл с расширением .conf. Каждый параметр пишется в отдельной строке в формате имя = значение.
Пример настроек:
net.ipv4.tcp_max_tw_buckets = 100
net.ipv4.tcp_keepalive_time = 15
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl = 3
net.ipv4.tcp_fin_timeout = 5
Чтобы применить параметры только из редактируемого файла, используйте команду:
sudo sysctl --load=файл.conf
Чтобы перезагрузить параметры из всех файлов и увидеть применённую иерархию, используйте:
sudo sysctl --system
Параметры sysctl
Глобальные лимиты и очереди
| Параметр | Описание | Тип | Значение по умолчанию | Допустимое значение |
|---|---|---|---|---|
|
Максимальное число соединений в очереди слушающего сокета |
integer |
4096 |
От 128 до 65535 |
|
Число пакетов в очереди на обработку ядром до передачи в стек |
integer |
— |
От 1 до 65535 |
Управление памятью и буферами
| Параметр | Описание | Тип | Значение по умолчанию | Допустимое значение |
|---|---|---|---|---|
|
Размер буфера сокета на приём для всех протоколов |
integer |
— |
От 2304 до 2147483647 |
|
Размер буфера сокета на отправку для всех протоколов |
integer |
— |
От 4608 до 2147483647 |
|
Максимальный размер буфера на приём, который система может запросить через |
integer |
— |
От 2304 до 2147483647 |
|
Максимальный размер буфера на отправку, который система может запросить через |
integer |
— |
От 4608 до 2147483647 |
|
Автоподстройка буфера приёма |
array |
4096 87380 4194304 |
Три целых числа (минимум, дефолт и максимум) |
|
Автоподстройка буфера отправки |
array |
4096 16384 4194304 |
Три целых числа (минимум, дефолт и максимум) |
|
Лимиты памяти для всего TCP-стека в страницах (обычно 4 КБ) |
array |
196608 262144 393216 |
Три целых числа:
|
|
Максимальное число осиротевших (не связанных ни с одним процессом) TCP-сокетов |
integer |
65536 |
От 16384 до 262144 |
|
Число попыток закрыть соединение на стороне сервера перед его принудительным разрывом |
integer |
7 |
От 0 до 255 |
|
Максимальный размер буфера для служебной информации сокета (опции, фильтры) |
integer |
— |
От 1 до 2147483647 |
|
Коэффициент для расчёта доли буфера сокета под TCP-окно и данные системы |
integer |
2 |
От -31 до 31 |
|
Количество байт в приёмном буфере сокета, зарезервированных под TCP-окно |
integer |
31 |
От 0 до 31 |
|
Автоподстройка буфера приёма под текущую скорость сети, чтобы сгладить нагрузку на память |
boolean |
— |
0 (выкл), 1 (вкл) |
|
Начальное значение MSS для расчёта размера сегментов, если не удаётся определить MTU пути |
integer |
— |
— |
|
Минимальный разрешённый MSS для отправки. Ограничивает уменьшение сегментов при работе с малыми MTU (например, в туннелях) |
integer |
— |
— |
|
Максимальный объём неподтверждённых данных в очереди на отправку (борьба с Bufferbloat) |
integer |
4194304 |
— |
|
Автоматическая склейка мелких сегментов в крупные для более эффективного использования сети |
boolean |
— |
0 (выкл), 1 (вкл) |
Очереди и состояние TIME_WAIT
| Параметр | Описание | Тип | Значение по умолчанию | Допустимое значение |
|---|---|---|---|---|
|
Диапазон портов для исходящих соединений (например, от ADC к бэкенду) |
array |
32768 60999 |
Два целых числа (от 1024 до 65535) |
|
Разрешает повторно использовать сокеты в состоянии TIME_WAIT для новых соединений, если это безопасно для протокола |
integer |
2 |
0 (выкл), 1 (вкл), 2 (только для loopback) |
|
Утилизацию сокетов в состоянии TIME_WAIT |
boolean |
0 |
0 (выкл), 1 (вкл) |
|
Время ожидания в состоянии FIN-WAIT-2 для «осиротевших» соединений перед их принудительным закрытием |
integer |
60 |
— |
|
Максимальное число сокетов, которые могут одновременно находиться в состоянии TIME_WAIT |
integer |
180000 |
— |
|
Размер очереди для соединений, которые получили SYN, но ещё не прислали ACK. Работает вместе с |
integer |
1024 |
— |
Поведение протокола и восстановление
| Параметр | Описание | Тип | Значение по умолчанию | Допустимое значение |
|---|---|---|---|---|
|
Поддержка TCP-окон больше 64 КБ (RFC 1323) для работы на высокоскоростных каналах с большой задержкой |
boolean |
1 |
0 (выкл), 1 (вкл) |
|
Добавление временных меток в каждый TCP-сегмент (RFC 1323). Обязательно для работы |
boolean |
1 |
0 (выкл), 1 (вкл) |
|
Использование селективных подтверждений (Selective Acknowledgements) для повторной отправки только потерянных сегментов |
boolean |
1 |
0 (выкл), 1 (вкл) |
|
Использование дублирующих подтверждений (Duplicate SACK) для определения ложных потерь и предотвращения лишних повторных отправок |
boolean |
1 |
0 (выкл), 1 (вкл) |
|
Использование механизма быстрого открытия (TCP Fast Open) для передачи данных на этапе установки соединения |
integer |
0x1 |
Битовая маска: 0x1 (клиент), 0x2 (сервер), 0x4 (TFO без cookie), 0x400 (все слушатели) |
|
Выбор алгоритма для контроля скорости передачи данных и реакции на потери в сети |
string |
cubic |
cubic, bbr, reno |
|
Использование алгоритма RACK для быстрого обнаружения потерь и устойчивости к переупорядочиванию пакетов |
integer |
0x1 |
Битовая маска: 0x1 (RACK), 0x2 (статичное окно), 0x4 (без DUPACK) |
|
Порог неотправленных данных в буфере записи, по достижении которого ядро уведомляет систему через |
integer |
— |
— |
|
Защита от «фантомных» пакетов (RFC 1337). Игнорирует RST-пакеты в состоянии TIME_WAIT, чтобы старые копии пакетов не закрыли новое соединение |
boolean |
0 |
0 (выкл), 1 (вкл) |
|
Защита от SYN-флуда через механизм SYN-кук при переполнении очереди |
boolean |
— |
0 (выкл), 1 (вкл) |
|
Принудительный сброс новых соединений, если система не успевает их обрабатывать |
boolean |
0 |
0 (выкл), 1 (вкл) |
|
Эмуляция ошибки протокола для совместимости со старым железом. Повторная отправка полных пакетов без разделения |
boolean |
1 |
0 (выкл), 1 (вкл) |
|
Использование интерпретации указателя срочности (Urgent Pointer) согласно RFC 1122 вместо режима BSD |
boolean |
0 |
0 (выкл), 1 (вкл) |
|
Сброс размера окна в долгоживущих соединениях после простоя |
boolean |
1 |
0 (выкл), 1 (вкл) |
|
Обнаружение MTU пути на уровне TCP |
integer |
— |
0 (выкл), 1 (выкл по умолчанию, вкл при обнаружении ICMP black hole), 2 (всегда включено с использованием MSS из |
|
Размер хеш-таблицы установленных соединений для дочерних сокетов |
integer |
— |
0 (автоопределение) или 2^n (где n от 0 до 24) |
|
Число записей в основной хеш-таблице установленных сокетов (только для чтения) |
integer |
— |
— |
|
Максимальный уровень допустимого переупорядочивания пакетов в TCP-потоке |
integer |
— |
— |
|
Алгоритм восстановления RTO в прямом направлении (F-RTO) для повышения эффективности повторной передачи |
integer |
— |
0 (выкл), 1 (базовый), 2 (улучшенный) |
|
Лимит повторных передач на ранней стадии (Early Retransmit) в ожидании данных SACK |
integer |
— |
— |
|
Использование линейных тайм-аутов (вместо экспоненциальных) для потоков с малым объёмом данных (менее 4 пакетов) |
boolean |
— |
0 (выкл), 1 (вкл) |
|
Начальный уровень допустимого переупорядочивания пакетов. Стек может динамически изменять его в пределах от этого значения до |
integer |
— |
— |
|
Запрет на сохранение метрик маршрута (RTT, окно перегрузки) после закрытия соединения |
boolean |
— |
0 (выкл), 1 (вкл) |
|
Отключает сохранение метрик порога медленного старта (ssthresh) в кэше маршрутов |
boolean |
— |
0 (выкл), 1 (вкл) |
|
Совместимость с некорректными TCP-стеками, которые ошибочно воспринимают окно как знаковое (signed) число. Если опция выключена, ядро считает удалённый стек исправным, даже если масштабирование не поддерживается |
boolean |
— |
0 (выкл), 1 (вкл) |
|
Уменьшение объявленного окна приёма, если система медленно считывает данные из буфера |
boolean |
— |
0 (выкл), 1 (вкл) |
|
Копирование значения DSCP из входящего SYN-пакета в исходящие. Поддерживает одинаковый QoS в обоих направлениях |
boolean |
— |
0 (выкл), 1 (вкл) |
|
Размер окна (в сегментах) для вычисления минимального RTT. Используется в алгоритмах управления перегрузкой (например, BBR) |
integer |
— |
От 0 до 86400 |
|
Уведомление о перегрузке (Explicit Congestion Notification) на маршруте |
integer |
— |
0 (выкл), 1 (для входящих), 2 (для исходящих), 3 (в обе стороны) |
|
Автоматическое отключение ECN для хоста, если первая попытка соединения привела к сбросу пакетов на пути |
boolean |
— |
0 (выкл), 1 (вкл) |
|
Интервал в секундах между проверками (зондами) состояния TCP |
integer |
— |
— |
|
Минимальный размер окна, при котором разрешена отправка проверочного зонда |
integer |
— |
— |
|
Лимит количества Challenge ACK в секунду для защиты от атак на «слепое окно» (RFC 5961) |
integer |
— |
— |
|
Интервал между отправкой дублирующих ACK в ответ на некорректные пакеты (вне окна или ошибка PAWS) |
integer |
— |
— |
|
Время блокировки механизма Fast Open (TFO) после неудачной попытки соединения |
integer |
— |
— |
|
Разрешение на перенос входящих запросов между слушающими сокетами для балансировки нагрузки (при использовании SO_REUSEPORT) |
boolean |
0 |
0 (выкл), 1 (вкл) |
|
Ограничение приёма соединений рамками того VRF или сетевого пространства, в котором создан сокет |
boolean |
0 |
0 (выкл), 1 (вкл) |
|
Использование файрвольных маркеров (fwmark) для фильтрации входящих соединений |
boolean |
0 |
0 (выкл), 1 (вкл) |
Оптимизация отправки
| Параметр | Описание | Тип | Значение по умолчанию | Допустимое значение |
|---|---|---|---|---|
|
Определяет максимальную долю окна перегрузки, которую может занять один TSO-кадр |
integer |
— |
— |
|
Корректировка размеров пакетов TSO (Segmentation Offload) на основе минимального времени отклика (min_rtt) |
integer |
— |
— |
|
Минимальное количество сегментов в одном кадре TSO |
integer |
— |
— |
|
Коэффициент контроля темпа отправки (pacing) для поиска пропускной способности в фазе предотвращения перегрузки |
integer |
— |
— |
|
Коэффициент контроля темпа отправки в режиме медленного старта для безопасного тестирования высоких скоростей |
integer |
— |
— |
Информационные параметры
| Параметр | Описание | Тип | Значение по умолчанию | Допустимое значение |
|---|---|---|---|---|
|
Список всех алгоритмов управления перегрузкой, которые загружены и доступны в системе |
string |
— |
— |
|
Список алгоритмов управления перегрузкой, которые разрешено использовать непривилегированным процессам (обычно совпадает с available) |
string |
— |
— |
|
Список доступных протоколов верхнего уровня (ULP), таких как |
string |
— |
— |
Таймеры Keep-Alive и повторные попытки
| Параметр | Описание | Тип | Значение по умолчанию | Допустимое значение |
|---|---|---|---|---|
|
Время неактивности в секундах, после которого отправляется первая проверка Keep-Alive |
integer |
7200 сек (2 часа) |
— |
|
Число проверок Keep-Alive без ответа, после которого соединение считается разорванным |
integer |
9 |
— |
|
Интервал между повторными проверками Keep-Alive, если на предыдущую не пришёл ответ |
integer |
75 |
— |
|
Количество попыток отправки SYN-пакета при установлении нового соединения |
integer |
5 |
< 255 |
|
Максимальное число попыток повторной отправки SYN-ACK в ответ на входящий SYN-запрос |
integer |
5 |
< 255 |
|
Количество попыток переотправки данных, после которого ядро передаёт ошибку на сетевой уровень для возможной смены маршрута |
integer |
3 |
— |
|
Лимит попыток повторной передачи данных, до превышения которого соединение считается разорванным |
integer |
15 |
— |