• База знаний
  • /
  • Блог
  • /
  • Wiki
  • /
+380 (44) 364 05 71

Тюнинг сетевого стека при помощи sysctl

Введение

Тема настройки ядра Linux «на лету», актуальная для многих системных администраторов, уже была освещена нами в статье «Что такое sysctl». В прошлой статье был описан сам принцип настройки ядра с помощью утилиты sysctl, приведены базовые команды и даны примеры некоторых наиболее распространенных параметров ядра Linux.

В этом материале хочется остановиться на конфигурации параметров сетевого стека на базе ОС Linux. Данная статья будет полезна системным администраторам при настройке высоконагруженных серверных ОС для «тяжелых» веб-проектов, а также поможет специалистам в сфере кибербезопасности построить оптимальную защиту от DDoS атак.

Все настройки сетевого стека необходимо внести в конфигурационный файл /etc/sysctl.conf. Также можно изменить опции любого сетевого параметра ядра «на лету» с помощью команды:

sysctl -w "переменная"="значение"

Например, ниже на скриншоте показано, как изменить параметр rp_filter:

Параметр rp_filter

Команда sysctl -p — выводит на экран текущие настройки сетевого параметра из файла /etc/sysctl.conf

Чтобы посмотреть значение одного сетевого параметра, который вас интересует в конкретный момент, нужно выполнить следующую команду, например для ip_forward:

sysctl net.ipv4.ip_forward

Вывод конкретного параметра sysctl

Еще один способ для просмотра параметров ядра Linux — это использование директории /proc/sys и команды cat, о чем вы можете более подробно прочитать в статье на нашем сайте FREEhost.UA.

Для изменения параметров таким способом используется команда ниже (например, вместо 1 указываем нужное значение параметра, на которое мы хотим изменить опцию rp_filter):

echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter

Однако, не все параметры могут быть изменены таким образом, некоторые из них задаются сразу только при загрузке ядра и на лету не меняются.

Например, ниже показано, как вывести на экран (командой cat) конкретные сетевые параметры настроек ядра Ubuntu:

Работа с директорией /proc/sys и командой cat

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

Настройка сетевых параметров ядра Linux

Для начала выведем текущие настройки параметров ядра «по умолчанию» (раздел net). В результате, получим листинг на несколько листов, ниже на скриншоте показана только часть этого списка параметров:

sysctl net

Параметры ядра Linux группы net

Для тюнинга сетевого стека нам нужны не все эти сетевые параметры, а только наиболее важные.

1. Приступим к настройкам, и начнем с группы параметров, которые отвечают за работу протокола 3-го уровня модели OSI — ICMP (Internet Control Message Protocol), которые обычно применяются для «пингования» хоста, т.е. для выполнения команд ping и traceroute. В нашем случае, хакеры могут использовать ICMP-пакеты перенаправления, чтобы изменить таблицы маршрутизации. Поэтому, если вы не занимаетесь настройкой маршрутизатора, то для хоста необходимо выставить значение «0» для следующих параметров ядра Linux:

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

2. Следующим этапом настройки, идет выставление значения параметра tcp_max_orphans, в дословном переводе — это «осиротевшие» (orphan) соединения. Когда параметр достигнет своего порогового значения, такие соединения просто сбрасываются, и система выдает предупреждение. Советуем увеличить пороговое значение этого параметра (каждое «осиротевшее» соединение требует 64 Кбайт unswappable памяти). Правильная настройка данной опции поможет в защите от наиболее простых типов DDoS-атак.

net.ipv4.tcp_max_orphans = 65536

3. Затем необходимо установить правильное значение для параметра tcp_fin_timeout, который обозначает время, в течении которого сокет может быть сохранен в состоянии FIN-WAIT-2, когда локальная сторона осуществила уже его закрытие. Данное соединение может быть вообще не закрыто партнером, поэтому необходимо его закрыть принудительно (когда «тайм-аут» истек). Значение «по умолчанию» для данного параметра — 60 секунд. Можно оставить значения «по умолчанию», но в случае, если вы эксплуатируете какие-то «тяжелые» веб-приложения, будет расходоваться много памяти на поддержку «мертвых соединений». Поэтому следует настроить данный параметр таким образом:

net.ipv4.tcp_fin_timeout = 10

4. Сейчас настроим еще 3 важных параметра:

tcp_keepalive_time — показывает, как часто нужно проверять соединение, в том случае, если оно давно не используется (только для сокетов с флагом SO_KEEPALIVE), «по умолчанию» это значение равно 7200 секунд;

tcp_keepalive_intvl — обозначает интервал передачи проб, значение «по умолчанию» выставлено 75 сек;

tcp_keepalive_probes * tcp_keepalive_intvl = время, после истечения которого, соединение должно быть разорвано (если нет откликов), примерное значение — 11 минут;

tcp_keepalive_probes — показывает значение для передач проб keepalive, после достижения которого, соединение будет разорвано, «по умолчанию» выставлено 9.

Ниже приводятся рекомендуемые значения для данных 3-х параметров*:

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

*Примечание: для параметра tcp_keepalive_time рекомендованные значения от 60 до 300.

5. Следующий важный параметр, который требует нашего внимания — это
tcp_max_syn_backlog, показывающий максимум полуоткрытых соединений, т.е. запоминаемых запросов на соединение, для которых подключающийся клиент не дал подтверждение. Советуем увеличить заданное «по умолчанию» значение, особенно в случае возникновения перезагрузок сервера.

net.ipv4.tcp_max_syn_backlog = 4096

6. На этом шаге настроим параметр tcp_synack_retries, отвечающий за время удержания «полуоткрытых» соединений. Здесь задается количество попыток повтора передачи SYN-ACK пакетов для пассивных соединений TCP, которое не должно быть более 255. «По умолчанию» выставлено число 5 (соответствует 180 сек. времени, выделенного на эти попытки). Рекомендуется уменьшить это время до 9 сек, что будет соответствовать единице.

net.ipv4.tcp_synack_retries=1

7. Параметр tcp_mem описан в виде векторной переменной, которая может принимать три значения, определяющие объем памяти, который может быть использован стеком TCP. Задается параметр в страницах памяти и зависит от архитектуры серверного оборудования, например, для i386 — это будет 4Кб (4096 байт). Три значения переменной (минимальное, значение в режиме нагрузки и максимальное) будут вычислены во время нагрузки. Если значение ниже минимального, то ОС вообще не выполняет никаких действий по управлению памятью, потребляемой сокетами TCP. Работа в режиме нагрузки: при достижении данного значения включается этот режим, и операционная система будет ограничивать выделение памяти. Причем, работа в таком режиме происходит до того момента времени, когда потребление памяти опять не снизится до минимума. И наконец, при достижении максимального значения этой переменной, TCP будет просто «терять» пакеты и соединения, пока объем используемой памяти не начнет снижаться. Для увеличения пропускной способности каналов рекомендуется оптимально настроить сразу 3 переменные tcp_mem, tcp_rmem и tcp_wmem. При настройке этих параметров советуем вам: для более мощных серверов выставлять большие параметры, а для серверов с более слабой конфигурацией — меньшие значения параметров. «По умолчанию» net.ipv4.tcp_mem настроен следующим образом*:

net.ipv4.tcp_mem = 96552 128739 193104

*Примечание: если ресурсы сервера позволяют выделить больше памяти под сеть.

В некоторых источниках рекомендуется выставить такие параметры*:

net.ipv4.tcp_mem = 50576   64768   98152

*Примечание: данные параметры рекомендованы для более слабых серверов.

8. Параметр tcp_wmem также, как и в предыдущем случае, является векторной переменной с 3-мя значениями в виде целых чисел (минимум, значение «по умолчанию», максимальное значение) и задает он размер для буфера передачи TCP сокета. При настройке данных параметров учитывайте конфигурацию и производительность ваших серверов, для более производительных серверов можно брать большие параметры. «По умолчанию», могут быть следующие параметры (можно оставить данные настройки):

net.ipv4.tcp_wmem = 4096 16384 4119648

Для более мощных серверов в некоторых источниках рекомендуется выставить следующие настройки:

net.ipv4.tcp_wmem = 4096 65536 16777216

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

«По умолчанию», этот параметр может быть настроен таким образом:

net.ipv4.tcp_rmem = 4096 87380 4119648

Согласно рекомендациям из специализированных источников, можно настроить эту опцию так (для более производительных серверов):

net.ipv4.tcp_rmem = 4096 87380 16777216

10. Параметры rmem_default, wmem_default служат для описания значений «по умолчанию» для размера буферов приема и передачи данных соответственно, они не могут перекрывать значения переменных tcp_rmem и tcp_wmem (см. пункты выше).

Ниже рекомендованы оптимальные значения для этих параметров:

net.core.rmem_default = 65536
net.core.wmem_default = 65536

11. Параметры rmem_max, wmem_max служат для перекрытия максимальных значений переменных tcp_rmem и tcp_wmem (описания их см. выше), при увеличении нагрузки на сервер, рекомендованы следующие настройки:

net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

12. Параметр tcp_orphan_retries задает величину, определяющую количество неудачных попыток, после достижения которой, происходит уничтожение соединения TCP, уже закрытого на локальной стороне. Закрытые соединения также расходуют ресурсы системы, поэтому советуем поставить 0, см. ниже:

net.ipv4.tcp_orphan_retries = 0

13. «По умолчанию», параметр tcp_syncookies включен (т.е. равен 1), но, чтобы избежать атак типа «SYN-флуда», когда отправляется очень много запросов SYN за короткий срок, советуем данный параметр отключить (поставить значение 0). Однако, предварительно нужно изучить логи сервера, на предмет наличия там такого рода записей, свидетельствующих об атаках «SYN-флуда», также необходимо учитывать настройки параметров tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow.

net.ipv4.tcp_syncookies = 0

14. С помощью переменной tcp_abort_on_overflow можно выставить такой режим, при котором ядро системы будет отвергать все новые соединения, если ОС не в состоянии с ними справиться. Однако, следует быть осторожным с настройкой этого параметра, «по умолчанию» он выключен, т.е. ему присвоено значение «0», для включения этой опции следует поставить «1».

net.ipv4.tcp_abort_on_overflow = 0

15. Этот параметр (ip_conntrack_max) необходим для грамотной настройки механизма определения состояния соединений connection tracking (используется для iptables), в общем, эта опция важна для работы межсетевых экранов. Если выставить очень маленькие значения, то ядро будет отвергать входящие соединения, это можно будет увидеть затем системном логе.

net.ipv4.netfilter.ip_conntrack_max = 16777216

16. Параметр tcp_timestamps предназначен для включения временных меток TCP (см. RFC 1323), для высокоскоростной сети и в условиях высоких нагрузок на сервера, советуем оставить ее включенной:

net.ipv4.tcp_timestamps = 1

17. Опция tcp_sack необходима для разрешения выборочных подтверждений протокола TCP (Selective Acknowledgements — SACK, см. RFC 2883 и RFC 2883). Данная функция будет полезна на неустойчивых соединениях, где возможны обрывы связи. Включенный «по умолчанию» tcp_sack = 1, разрешает произвести передачу повторно лишь отдельных не подтвержденных фрагментов (а не всего окна TCP), работает совместно с опцией tcp_timestamps.

net.ipv4.tcp_sack = 1

18. Параметр tcp_congestion_control позволяет осуществлять контроль за управлением нагрузкой в сетях TCP. Выбор настроек контроля за перегрузкой осуществляется при сборке ядра, доступны следующие режимы: reno (default), cubic:CUBIC-TCP, bic:BIC-TCP, htcp:Hamilton TCP, vegas:TCP Vegas, westwood (для сетей с потерями). Для работы сервера рекомендуется использовать htcp. Значение параметра «по умолчанию» — cubic (однако, есть ошибки в ядре Linux 2.6.18).

net.ipv4.tcp_congestion_control = htcp

19. Эта настройка (tcp_no_metrics_save) не разрешает сохранение результатов изменений TCP соединения в кэше, в случае его закрытия. «По умолчанию», она в выключенном состоянии «0», но рекомендуем ее включить для увеличения производительности:

net.ipv4.tcp_no_metrics_save = 1

20. Параметр net.ipv4.route.flush актуален для ядра версии 2.4, если ваша ОС на этой версии ядра, то включите его:

net.ipv4.route.flush = 1

21. Следующая группа параметров rp_filter предназначена для защиты от спуфинга (подмены адресов), отвечает за включение/выключение reverse path filter (т.е. проверку обратного адреса). Однако, если вы используете таблицы маршрутизации большой сложности, то перед настройкой этого параметра, рекомендуется изучить RFC 1812. В состоянии «по умолчанию» данные параметры выключены (значение «0»), рекомендуем включить в режим «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

22. На этом этапе необходимо настроить запрет маршрутизации от источника (source routing), т.е. группу параметров accept_source_route; «по умолчанию», настройки находятся в состоянии «выключено» (ноль). Эта опция может предоставлять разрешение отправителю для определения пути пакета, который тот проходит по сети для достижения пункта назначения. Для сетевого инженера — это очень удобная опция, однако ей может воспользоваться и злоумышленник, поэтому рекомендуется ее оставить в выключенном состоянии.

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

23. Сейчас требуется настроить опцию ip_local_port_range, отвечающую за диапазон локальных портов, которые нам доступны для установки исходящих подключений. Параметр содержит 2 целых числа, где первое из них служит для задания нижней границы этого диапазона, а второе — устанавливает верхнюю границу. Значения выставляются в зависимости от объема ОЗУ сервера. Рекомендуемый диапазон для высоконагруженных проектов:

net.ipv4.ip_local_port_range = 1024 65535

24. Параметр tcp_tw_reuse служит для разрешения повторного использования сокетов TIME-WAIT, когда это безопасно. Рекомендуется его включить:

net.ipv4.tcp_tw_reuse = 1

25. Для разрешения или запрета масштабирования окна стека TCP необходима настройка параметра tcp_window_scaling (подробно см. RFC 1323). Фактически, разрешая динамическое изменение TCP-окна, можно увеличить размер канала, а также значительно снизить потери пропускной способности.

net.ipv4.tcp_window_scaling = 1

26. Для установления защиты от атак типа TIME_WAIT, стоит включить параметр tcp_rfc1337. Детально смысл этого параметра "TIME-WAIT Assassination Hazards in TCP" изложен в RFC 1337, а сама проблема заключена в том, что устаревшие дубликаты пакетов вносят помехи в новые соединения и тем самым порождают различные проблемы. Но, так как «по умолчанию» эта опция выключена (значение «0»), для сервера нам необходимо ее включить:

net.ipv4.tcp_rfc1337 = 1

27. Чтобы запретить переадресацию пакетов для сервера, необходимо отключить параметр ip_forward. В случае включения ip_forward (значение «1»), операционная система будет вести себя «как маршрутизатор» и работать согласно RFC1812, т.е. перенаправлять пакеты в соответствии с таблицей маршрутизации.

net.ipv4.ip_forward = 0

28. Функция icmp_echo_ignore_broadcasts разрешает (или запрещает) отвечать на запросы ICMP ECHO, которые передаются широковещательными пакетами.

net.ipv4.icmp_echo_ignore_broadcasts = 1

29. Полный запрет ответа на ICMP ECHO запросы (сервер не «пингуется») можно настроить таким образом:

net.ipv4.icmp_echo_ignore_all = 1

30. Настроим запрет ответа на сообщения, которые сформированы ошибочно:

net.ipv4.icmp_ignore_bogus_error_responses = 1

31. Параметр somaxconn необходим для установления значения максимального количества открытых сокетов, которые ожидают соединения. Рекомендуемое значение параметра 15000 (используется для высоконагруженных систем), 65535 — максимальное значение данного параметра, используется в редких случаях:

net.core.somaxconn = 15000

32. Также необходимо настроить параметр netdev_max_backlog, который задает максимальное число пакетов, находящихся в очереди «на обработку», в случае, когда интерфейс получает пакеты гораздо быстрее, чем ядро их обрабатывает. Ниже приведено значение «по умолчанию» (рекомендуемое).

net.core.netdev_max_backlog = 1000

Пример готового файла с настройками

Для удобства мы свели все вышеописанные параметры в один список, который вам необходимо добавить в конец файла /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 = 60
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 = 15000
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

Пример файла sysctl.conf с настройками

Заключение

В этой части статьи мы дали практические рекомендации для системных администраторов, как провести тюнинг сетевого стека при помощи sysctl. Мы привели только основные переменные типа net для ядра Linux, оптимально настроив которые, системные инженеры смогут выстроить грамотную защиту своей сети от атак, а также эффективно эксплуатировать высоконагруженные сервера с «тяжелыми» веб-приложениями.

Однако, перед тем как начать экспериментировать на своем сервере, настоятельно рекомендуем изучить документацию на вашу ОС. Если же вы не уверены в своей компетенции и у вас нет опыта работы с сетевыми настройками ядра Linux, то вы всегда можете обратиться за помощью к системным администраторам компании FREEhost.UA.

Подписывайтесь на наш телеграмм-канал t.me/freehostua, чтоб быть в курсе новых полезных материалов. Смотрите наш Youtube канал по администрированию Linux серверов youtube.com/freehostua

Дата: 19.05.2021
Автор: Евгений
Голосование

Авторам статьи важно Ваше мнение. Будем рады его обсудить с Вами:

comments powered by Disqus
Спасибо, что выбираете FREEhost.UA