Настройка Linux для HL и защиты от DDoS

Edit...
OS
Illustrated by Igan Pol

Привет, %username%! Настройки ядра, защита от DDoS, HL и высокие нагрузки. Именно в таких ситуациях думаешь, что пора настраивать параметры через sysctl. Эта инструкция далеко не первая, и уж тем более не последняя.

🔄 Обновлено 2026-05-15: пост писался под ядра 4.x — большая часть параметров до сих пор актуальна, но на ядре 6.x кое-что уже неправильно. Самое важное и быстрое к исправлению:

  • net.ipv4.tcp_syncookies = 0 ниже — не делай этого. С 2019-го рекомендация развернулась: syncookies должны быть включены (= 1), это штатная защита от SYN-flood без побочки;
  • net.ipv4.tcp_congestion_control = htcp ниже — пора менять на bbr. Про CUBIC/BIC-«баги в RedHat-ядрах» уже не актуально, а BBR заметно лучше для типичного HL;
  • net.ipv4.netfilter.ip_conntrack_max — legacy от старого iptables, оставить только net.netfilter.nf_conntrack_max;
  • net.ipv4.route.flush = 1 с комментарием «актуально для ядер 2.4» — можно смело убирать.

Полный апдейт под современные ядра — в разделе «Что обновить в 2026» в конце поста.

Листинг того, что желательно добавить в конец /etc/sysctl.conf

net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.tcp_max_orphans = 65536
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_mem = 50576   64768   98152
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_orphan_retries = 0
net.ipv4.tcp_syncookies = 0
net.ipv4.netfilter.ip_conntrack_max = 16777216
net.netfilter.nf_conntrack_max = 16777216
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_sack = 1
net.ipv4.tcp_congestion_control = htcp
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.route.flush = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.eth0.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rfc1337 = 1
net.ipv4.ip_forward = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_echo_ignore_all = 1
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 1000
net.core.rmem_default = 65536
net.core.wmem_default = 65536
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
fs.inotify.max_user_watches = 16777216

А теперь о каждой опции более детально#

net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.all.send_redirects = 0

Не принимать и не отправлять ICMP-пакеты перенаправления. ICMP-перенаправления могут быть использованы злоумышленником для изменения таблиц маршрутизации. Целесообразно выставить в 0. Единица имеет смысл только для хостов, использующихся в качестве маршрутизаторов.


net.ipv4.tcp_max_orphans = 65536

Целочисленное значение параметра tcp_max_orphans определяет максимальное число допустимых в системе сокетов TCP, не связанных каким-либо идентификатором пользовательского файла (user file handle). При достижении порогового значения “осиротевшие” (orphan) соединения незамедлительно сбрасываются с выдачей предупреждения. Этот порог помогает предотвращать только простые атаки DoS. Не следует уменьшать пороговое значение (скорее увеличить его в соответствии с требованиями системы – например, после добавления памяти. Каждое orphan-соединение поглощает около 64 Кбайт несбрасываемой на диск (unswappable) памяти.


net.ipv4.tcp_fin_timeout = 10

Параметр tcp_fin_timeout определяет время сохранения сокета в состоянии FIN-WAIT-2 после его закрытия локальной стороной. Партнер может не закрыть это соединение никогда, поэтому следует закрыть его по своей инициативе по истечении тайм-аута. По умолчанию тайм-аут составляет 60 секунд. В ядрах серии 2.2 обычно использовалось значение 180 секунд и вы можете сохранить это значение, но не следует забывать, что на загруженных WEB-серверах вы рискуете израсходовать много памяти на сохранение полуразорванных мертвых соединений. Сокеты в состоянии FIN-WAIT-2 менее опасны, нежели FIN-WAIT-1, поскольку поглощают не более 1,5 Кбайт памяти, но они могут существовать дольше.


net.ipv4.tcp_keepalive_time = 1800
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5

tcp_keepalive_time Переменная определяет как часто следует проверять соединение, если оно давно не используется. Значение переменной имеет смысл только для тех сокетов, которые были созданы с флагом SO_KEEPALIVE. Целочисленная переменная tcp_keepalive_intvl определяет интервал передачи проб. Произведение tcp_keepalive_probes * tcp_keepalive_intvl определяет время, по истечении которого соединение будет разорвано при отсутствии откликов. По умолчанию установлен интервал 75 секунд, т.е., время разрыва соединения при отсутствии откликов составит приблизительно 11 минут.


net.ipv4.tcp_max_syn_backlog = 4096

Целочисленное значение в файле tcp_max_syn_backlog определяет максимальное число запоминаемых запросов на соединение, для которых не было получено подтверждения от подключающегося клиента. Если на сервере возникают перегрузки, можно попытаться увеличить это значение.


net.ipv4.tcp_synack_retries = 1

Целочисленное значение (1 байт) tcp_synack_retries определяет число попыток повтора передачи пакетов SYNACK для пассивных соединений TCP. Число попыток не должно превышать 255. Значение 5 соответствует приблизительно 180 секундам на выполнение попыток организации соединения.


net.ipv4.tcp_mem = 50576   64768   98152

Векторная (минимум, режим нагрузки, максимум) переменная в файле tcp_mem cодержит общие настройки потребления памяти для протокола TCP. Эта переменная измеряется в страницах (обычно 4Кб), а не байтах.

Минимум: пока общий размер памяти для структур протокола TCP менее этого количества страниц, операционная система ничего не делает.

Режим нагрузки: как только количество страниц памяти, выделенное для работы протокола TCP, достигает этого значения, активируется режим работы под нагрузкой, при котором операционная система старается ограничивать выделение памяти. Этот режим сохраняется до тех пор, пока потребление памяти опять не достигнет минимального уровня.

Максимум: максимальное количество страниц памяти, разрешенное для всех TCP сокетов.


net.ipv4.tcp_rmem = 4096 87380 16777216

Векторная (минимум, по умолчанию, максимум) переменная в файле tcp_rmem содержит 3 целых числа, определяющих размер приемного буфера сокетов TCP.

Минимум: каждый сокет TCP имеет право использовать эту память по факту своего создания. Возможность использования такого буфера гарантируется даже при достижении порога ограничения (moderate memory pressure). Размер минимального буфера по умолчанию составляет 8 Кбайт (8192).

Значение по умолчанию: количество памяти, допустимое для буфера передачи сокета TCP по умолчанию. Это значение применяется взамен параметра /proc/sys/net/core/rmem_default, используемого другими протоколами. Значение используемого по умолчанию буфера обычно (по умолчанию) составляет 87830 байт. Это определяет размер окна 65535 с заданным по умолчанию значением tcp_adv_win_scale и tcp_app_win = 0, несколько меньший, нежели определяет принятое по умолчанию значение tcp_app_win.

Максимум: максимальный размер буфера, который может быть автоматически выделен для приема сокету TCP. Это значение не отменяет максимума, заданного в файле /proc/sys/net/core/rmem_max. При “статическом” выделении памяти с помощью SO_RCVBUF этот параметр не имеет значения.


net.ipv4.tcp_wmem = 4096 65536 16777216

Векторная переменная в файле tcp_wmem содержит 3 целочисленных значения, определяющих минимальное, принятое по умолчанию и максимальное количество памяти, резервируемой для буферов передачи сокета TCP.

Минимум: каждый сокет TCP имеет право использовать эту память по факту своего создания. Размер минимального буфера по умолчанию составляет 4 Кбайт (4096)

Значение по умолчанию: количество памяти, допустимое для буфера передачи сокета TCP по умолчанию. Это значение применяется взамен параметра /proc/sys/net/core/wmem_default, используемого другими протоколами и обычно меньше, чем /proc/sys/net/core/wmem_default. Размер принятого по умолчанию буфера обычно (по умолчанию) составляет 16 Кбайт (16384)

Максимум: максимальное количество памяти, которое может быть автоматически выделено для буфера передачи сокета TCP. Это значение не отменяет максимум, заданный в файле /proc/sys/net/core/wmem_max. При “статическом” выделении памяти с помощью SO_SNDBUF этот параметр не имеет значения.


net.ipv4.tcp_orphan_retries = 0

Целочисленной значение tcp_orphan_retries определяет число неудачных попыток, после которого уничтожается соединение TCP, закрытое на локальной стороне. По умолчанию используется значение 7, соответствующее приблизительно периоду от 50 секунд до 16минут в зависимости от RTO. На сильно загруженных WEB-серверах имеет смысл уменьшить значение этого параметра, поскольку закрытые соединения могут поглощать достаточно много ресурсов.


net.ipv4.tcp_syncookies = 0

Согласно рекомендациям разработчиков ядра, этот режим лучше отключить.


net.ipv4.netfilter.ip_conntrack_max = 16777216

Максимальное количество соединений для работы механизма connection tracking (используется, например, iptables). При слишком маленьких значениях ядро начинает отвергать входящие подключения с соответствующей записью в системном логе.


net.ipv4.tcp_timestamps = 1

Разрешает временные метки протокола TCP. Их наличие позволяет управлять работой протокола в условиях серьезных нагрузок (см. tcp_congestion_control).


net.ipv4.tcp_sack = 1

Разрешить выборочные подтверждения протокола TCP. Опция необходима для эффективного использования всей доступной пропускной способности некоторых сетей.


net.ipv4.tcp_congestion_control = htcp

Протокол, используемый для управления нагрузкой в сетях TCP. bic и cubic реализации, используемые по умолчанию, содержат баги в большинстве версий ядра RedHat и ее клонов. Рекомендуется использовать htcp.


net.ipv4.tcp_no_metrics_save = 1

Не сохранять результаты измерений TCP соединения в кеше при его закрытии. В некоторых случаях помогает повысить производительность.


net.ipv4.route.flush = 1

Актуально для ядер 2.4. По странной причине в ядрах 2.4, если в рамках TCP сессии произошел повтор передачи с уменьшенным размером окна, все соединения с данным хостом в следующие 10 минут будут иметь именно этот уменьшенный размер окна. Данная настройка позволяет этого избежать.


net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

Активируем защиту от IP-спуфинга.


net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.eth0.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

Запрещаем маршрутизацию от источника.


net.ipv4.ip_local_port_range = 1024 65535

Увеличиваем диапазон локальных портов, доступных для установки исходящих подключений


net.ipv4.tcp_tw_reuse = 1

Разрешаем повторное использование TIME-WAIT сокетов в случаях, если протокол считает это безопасным.


net.ipv4.tcp_window_scaling = 1

Разрешаем динамическое изменение размера окна TCP стека


net.ipv4.tcp_rfc1337 = 1

Защищаемся от TIME_WAIT атак.


net.ipv4.ip_forward = 0

Запрещаем переадресацию пакетов, поскольку мы не роутер.


net.ipv4.icmp_echo_ignore_broadcasts = 1

Не отвечаем на ICMP ECHO запросы, переданные широковещательными пакетами


net.ipv4.icmp_echo_ignore_all = 1

Можно вообще не отвечать на ICMP ECHO запросы (сервер не будет пинговаться)


net.ipv4.icmp_ignore_bogus_error_responses = 1

Не отвечаем на ошибочно сформированные сообщения


net.core.somaxconn = 65535

Максимальное число открытых сокетов, ждущих соединения. Имеет смысл увеличить значение по умолчанию.


net.core.netdev_max_backlog = 1000

Параметр определяет максимальное количество пакетов в очереди на обработку, если интерфейс получает пакеты быстрее, чем ядро может их обработать.


net.core.rmem_default = 65536

Размер буфера приема данных по умолчанию для всех соединений.


net.core.wmem_default = 65536

Размер буфера передачи данных по умолчанию для всех соединений.


net.core.rmem_max = 16777216

Максимальный размер буфера приема данных для всех соединений.


net.core.wmem_max = 16777216

Максимальный размер буфера передачи данных для всех соединений.

Это далеко не всё. Удачи!

P.S.: Количество соединений обычно можно подсчитать с помощью

wc -l /proc/net/ip_conntrack

Хотя для современных ядер правильнее смотреть в /proc/net/nf_conntrack или через conntrack -C из пакета conntrack-tools.

Что обновить в 2026#

С момента публикации поста прошло 7 лет, в индустрии — ~4 LTS-релиза ядра. Что в этом листинге стоит пересмотреть, если ты ставишь это на свежее ядро 6.x (Debian 12/13, Ubuntu 22.04/24.04, Rocky/Alma 9):

Включи syncookies (важно!)#

# было: net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_syncookies = 1

tcp_syncookies — штатная защита от SYN-flood, в современных ядрах включена по умолчанию. Когда listen-очередь переполнена, ядро отвечает зашифрованным cookie вместо хранения half-open-соединения — таблицы не переполняются, легитимные клиенты не страдают. Старые рекомендации «выключи, ломает RFC» в 2026-м не актуальны.

Поставь BBR вместо htcp#

# было: net.ipv4.tcp_congestion_control = htcp
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc           = fq

BBR (от Google, мейнлайн с ядра 4.9) — congestion control на модели пропускной способности, а не на потере пакетов. В реальном инете с buffer-bloat и lossy-соединениями он стабильно даёт лучший throughput и заметно меньший latency-tail. Требует fq qdisc по умолчанию. В свежих ядрах уже есть bbr3 (с 6.4+), который дружелюбнее к остальному трафику.

Проверить, какие алгоритмы доступны на твоём ядре:

sysctl net.ipv4.tcp_available_congestion_control

Добавь tcp_notsent_lowat#

# нового параметра в посте нет — добавь
net.ipv4.tcp_notsent_lowat = 131072

Лимит на «несентенированные» байты в send-buffer’е. Без него write-приложение может набить себе огромный backlog, который сидит в памяти ядра и выдаёт хвосты по latency. С tcp_notsent_lowat = 128KB приложение блокируется на write раньше — память тратится экономнее, latency предсказуемее. Стандартное значение в современных рекомендациях — 131072 (128 KiB).

Включи TCP Fast Open#

net.ipv4.tcp_fastopen = 3

Позволяет передать данные уже в SYN-пакете — экономит один RTT. 3 означает «и server, и client». В мейнлайне стабильно с ядра 3.7, в реальных стеках сейчас почти везде используется (CDN, мобильные клиенты).

Подними backlogs#

Дефолтные значения 2019-го уже малы для современных сетевых карт и нагрузок:

# было: net.core.somaxconn = 65535 — норм, но не у всех приложений Listen-backlog большой
net.core.somaxconn       = 32768
# Был: net.core.netdev_max_backlog = 1000 — мало для 10G+ NIC
net.core.netdev_max_backlog = 250000
# tcp_max_syn_backlog в посте 4096 — можно поднять
net.ipv4.tcp_max_syn_backlog = 8192
# и orphans на серверах с 32+ GB RAM
net.ipv4.tcp_max_orphans = 262144

somaxconn в современных ядрах поднят с 128 до 4096 как дефолт, явное значение можно ставить под нагрузку.

Очисти устаревшее#

Можно убирать:

# Legacy от старого iptables — connection tracking теперь только через nf_conntrack
net.ipv4.netfilter.ip_conntrack_max = ...

# Костыль для ядер 2.4
net.ipv4.route.flush = 1

Пара слов про fs.inotify#

# было: fs.inotify.max_user_watches = 16777216
fs.inotify.max_user_watches = 524288

16 миллионов watch’ей — это сильно с запасом. Современная рекомендация (от тех же VS Code, IntelliJ, watchman) — 524288 (полмиллиона). Этого хватает даже для здорового монорепо.

Не повторяй слепо#

Это всё общие рекомендации, а не cargo-cult. На своём железе под своей нагрузкой обязательно мерь до и после — что у одного сервера хорошо, у другого может сломать конкретный workload. Минимум что стоит проверить:

# текущие congestion + buffer'ы
ss -tin

# заполнение backlog'ов и потери в очередях
ss -lnt
sysctl net.ipv4.tcp_listen_portaddr_hash_shift
sar -n SOFT 1            # softirq за секунду
nstat                    # счётчики TCP

# conntrack — самый частый тихий killer
conntrack -C
cat /proc/sys/net/netfilter/nf_conntrack_count

Если параметр меняешь — фиксируй в /etc/sysctl.d/99-tuning.conf, а не в /etc/sysctl.conf (последний при обновлении пакетов трогать не любят). Применить без ребута — sysctl --system.


Если у тебя есть вопросы, комментарии и/или замечания – заходи в чат , а так же подписывайся на канал .

О способах отблагодарить автора можно почитать на странице “Донаты ”.