Настройка ядра Linux для тяжелых проектов и защиты от DDOS
Процесс пошел, подумал я, и выйдя из «анабиозного» состояния раздолбая, я понял что нужно работать дальше…
Сейчас речь пойдет о том, как можно настроить ядро Linux сервера, чтобы он смог переваривать большое количество запросов, а так же DDos. Все будет кратко с небольшим описанием.
Много материалов я вычитал, для того чтобы понять какие значения оптимальны, так же прилично всего перепробовал, и некоторые решения помогли мне уйти от той высокой нагрузки на сервере. Так же грамотная настройка ядра сервера позволит вам защититься от SYN flood. Ладно, начнем..
Каждый параметр подробненько…
rp_filter
— параметр который включает фильтр обратного пути, проще говоря активируется защита от подмены адресов (спуфинга).
По умолчанию он отключен:
cat /proc/sys/net/ipv4/conf/all/rp_filter 0
Рекомендуется включить в «строгий режим» проверки (значение 2 включает «свободный режим» проверки), причем включить его можно на всех интерфейсах:
sysctl -w net.ipv4.conf.all.rp_filter=1
Так проверку можно включить на определенном интерфейсе:
sysctl -w net.ipv4.conf.eth0.rp_filter=1
accept_source_route
— запрет маршрутизации от источников.
По умолчанию эта опция отключена:
cat /proc/sys/net/ipv4/conf/all/accept_source_route 0
Но если она у вас почему-то включена — отключите, желательно на всех интерфейсах:
sysctl -w net.ipv4.conf.all.accept_source_route=0 sysctl -w net.ipv4.conf.lo.accept_source_route=0 sysctl -w net.ipv4.conf.eth0.accept_source_route=0 sysctl -w net.ipv4.conf.default.accept_source_route=0
accept_redirects, secure_redirects, send_redirects
— этими тремя параметрами мы запрещаем принимать и отправлять ICMP пакеты перенаправления. ICMP-перенаправления могут быть использованы злоумышленником для изменения таблиц маршрутизации.
По умолчанию все эти параметры включены:
cat /proc/sys/net/ipv4/conf/all/accept_redirects 1 cat /proc/sys/net/ipv4/conf/all/secure_redirects 1 cat /proc/sys/net/ipv4/conf/all/send_redirects 1
Но, так как наш сервер не маршрутизатор, в них нет необходимости:
sysctl -w net.ipv4.conf.all.accept_redirects=0^C sysctl -w net.ipv4.conf.all.secure_redirects=0^C sysctl -w net.ipv4.conf.all.send_redirects=0
icmp_echo_ignore_broadcasts
— отключаем ответ на ICMP ECHO запросы, переданные широковещательными пакетами.
По умолчанию включено, т.е. broadcast icmp запросы приходить не будут:
cat /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts 1
Так и рекомендуется отставить:
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1
icmp_ignore_bogus_error_responses
— игнорируем ошибочные ICMP запросы.
По умолчанию:
cat /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses 1
Так и рекомендуется отставить:
sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1
icmp_echo_ignore_all
— отключаем ответ на ICMP запросы (сервер не будет пинговаться)
По умолчанию:
cat /proc/sys/net/ipv4/icmp_echo_ignore_all 0
На ваше усмотрение, можно отключить:
sysctl -w net.ipv4.icmp_echo_ignore_all=1
tcp_syncookies
— по умолчанию данный параметр обычно включен. Если количество SYN пакетов забивает всю очередь, включается механизм Syn cookies.
Как проверить, включен ли он у нас:
cat /proc/sys/net/ipv4/tcp_syncookies 1
Если выдает 1, то включен, 0 — значит отключен. Для отключения «на лету» достаточно воспользоваться следующей командой:
sysctl -w net.ipv4.tcp_syncookies=0
Естественно поставив в конце «1» — механизм будет снова включен.
Таким образом, как описано выше, мы получаем неплохую защиту от syn флуда и терпим небольшую нагрузку на ЦП..
Но согласно описанию, включать генерацию syncookies на высоконагруженных серверах, для которых этот механизм срабатывает, при большом количестве легальных соединений, не следует. Если в логах есть предупреждения о SYN-флуде, при этом это вполне нормальные соединения, нужно настраивать другие параметры: tcp_max_syn_backlog, tcp_synack_retries, tcp_abort_on_overflow.
tcp_max_syn_backlog
— параметр который определяет максимальное число запоминаемых запросов на соединение, для которых не было получено подтверждения от подключающегося клиента (полуоткрытых соединений). По умолчанию:
cat /proc/sys/net/ipv4/tcp_max_syn_backlog 512
Если на сервере возникают перегрузки, можно попытаться увеличить это значение, например до 4096:
sysctl -w net.ipv4.tcp_max_syn_backlog=4096
tcp_synack_retries
— время удержания «полуоткрытых» соединений.
По умолчанию:
cat /proc/sys/net/ipv4/tcp_synack_retries 5
Это значение имеет смысл уменьшить, например до 1 (это будет 9 секунд):
sysctl -w net.ipv4.tcp_synack_retries=1
tcp_max_orphans
— определяет максимальное число «осиротевших» TCP пакетов.
По умолчанию:
cat /proc/sys/net/ipv4/tcp_max_orphans 262144
Рекомендуется установить 65536, а далее увеличивать, по мере необходимости:
sysctl -w net.ipv4.tcp_max_orphans=65536
tcp_fin_timeout
— время ожидания приема FIN до полного закрытия сокета.
По умолчанию:
cat /proc/sys/net/ipv4/tcp_fin_timeout 60
Рекомендуется поменять на 10 секунд:
sysctl -w net.ipv4.tcp_fin_timeout=10
tcp_keepalive_time
— проверять TCP-соединения, с помощью которой можно убедиться в том что на той стороне легальная машина, так как она сразу ответит.
По умолчанию 2 часа:
cat /proc/sys/net/ipv4/tcp_keepalive_time 7200
Рекомендуется каждую минуту:
sysctl -w net.ipv4.tcp_keepalive_time=60
tcp_keepalive_intvl
— интервал подачи проб…
По умолчанию:
cat /proc/sys/net/ipv4/tcp_keepalive_intvl 75
Рекомендуется поставить:
sysctl -w net.ipv4.tcp_keepalive_intvl=15
tcp_keepalive_probes
— Количество проверок перед закрытием соединения.
По умолчанию:
cat /proc/sys/net/ipv4/tcp_keepalive_probes 9
Рекомендуется поставить:
sysctrl -w net.ipv4.tcp_keepalive_probes=5
netdev_max_backlog
— Параметр определяет максимальное количество пакетов в очереди на обработку, если интерфейс получает пакеты быстрее, чем ядро может их обработать.
По умолчанию:
cat /proc/sys/net/core/netdev_max_backlog 1000
Рекомендуется так и оставить:
sysctl -w net.core.netdev_max_backlog=1000
somaxconn
— Максимальное число открытых сокетов, ждущих соединения.
По у молчанию:
cat /proc/sys/net/core/somaxconn 1024
Рекомендуется установить значения в районе 15000-20000:
sysctl -w net.core.somaxconn=15000
tcp_mem
— векторная (минимум, режим нагрузки, максимум) переменная которая cодержит общие настройки потребления памяти для протокола TCP
По умолчанию:
cat /proc/sys/net/ipv4/tcp_mem 96552 128739 193104
Можно поставить эти же значения.увеличивать имеет смысл в случае увеличения нагрузки.
tcp_rmem
— векторная (минимум, режим нагрузки, максимум) переменная которая cодержит 3 целых числа, определяющих размер приемного буфера сокетов TCP.
По умолчанию:
cat /proc/sys/net/ipv4/tcp_rmem 4096 87380 4119648
Можно поставить эти же значения.увеличивать имеет смысл в случае увеличения нагрузки. В одном из источнике рекомендовали следующие значения:
sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"
tcp_wmem
— векторная (минимум, режим нагрузки, максимум) переменная которая cодержит 3 целых числа, минимальное, принятое по умолчанию и максимальное количество памяти, резервируемой для буферов передачи сокета TCP.
По умолчанию:
cat /proc/sys/net/ipv4/tcp_wmem 4096 16384 4119648
Можно оставить эти же значения. Увеличивать их имеет смысл в случае увеличения нагрузки. В одном из источнике рекомендовали следующие значения:
sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"
rmem_default, wmem_default
Так же есть «глобальные» параметры размеров буфера, и они не перекрывают значения переменных tcp_rmem и tcp_wmem (читай описание выше)
- rmem_default — размер буфера приема данных по умолчанию для всех соединений.
- wmem_default — Размер буфера передачи данных по умолчанию для всех соединений.
Их значения по умолчанию:
cat /proc/sys/net/core/rmem_default 229376 cat /proc/sys/net/core/wmem_default 229376
Можно оставить эти же значения. Увеличивать их имеет смысл в случае увеличения нагрузки. Например, в одном из источнике рекомендовали следующие значения:
sysctl -w net.core.rmem_default=65536 sysctl -w net.core.wmem_default=65536
rmem_max, wmem_max
а эти «глобальные» параметры перекрывают «максимумы» переменных tcp_rmem и tcp_wmem (опять же, читай описание выше)
- rmem_max — максимальный размер буфера приема данных для всех соединений.
- wmem_max — максимальный размер буфера передачи данных для всех соединений.
Их значения по умолчанию:
cat /proc/sys/net/core/rmem_max 131071 cat /proc/sys/net/core/wmem_max 131071
Можно оставить эти же значения. Увеличивать их имеет смысл в случае увеличения нагрузки. Например, в одном из источнике рекомендовали следующие значения:
sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.wmem_max=16777216
tcp_orphan_retries
— параметр который определяет число неудачных попыток, после которого уничтожается соединение TCP, закрытое на локальной стороне.
По умолчанию:
cat /proc/sys/net/ipv4/tcp_orphan_retries 0
Рекомендуется уменьшить значение этого параметра, поскольку закрытые соединения могут поглощать достаточно много ресурсов (т.е. оставляем 0):
sysctl -w net.ipv4.tcp_orphan_retries=0
ip_conntrack_max
— Максимальное количество соединений для работы механизма connection tracking (используется, например, iptables).
По умолчанию:
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max 65536
При слишком маленьких значениях ядро начинает отвергать входящие подключения с соответствующей записью в системном логе:
sysctl -w net.ipv4.netfilter.ip_conntrack_max=16777216
tcp_timestamps
— включает временные метки протокола TCP, которые позволяют управлять работой протокола в условиях высоких нагрузок (с помощью tcp_congestion_control)
По умолчанию метки включены:
cat /proc/sys/net/ipv4/tcp_timestamps 1
Кстати, лучше отставить его включенным, иначе не будет работать опция tcp_tw_reuse.
sysctl -w net.ipv4.tcp_timestamps=1
tcp_sack
— разрешаем выборочные подтверждения протокола TCP. Опция необходима для эффективного использования всей доступной пропускной способности некоторых сетей.
По умолчанию опция включена:
cat /proc/sys/net/ipv4/tcp_sack 1
Рекомендуется включать эту опцию, если вы имеете неустойчивые соединения. Однако, если вы соединены 1.5-метровым кабелем с другой машиной, то в таком случае, для достижения наивысшей скорости обмена, следует эту опцию отключить:
sysctl -w net.ipv4.tcp_sack=1
tcp_congestion_control
— протокол, используемый для управления нагрузкой в сетях TCP. bic и cubic реализации, используемые по умолчанию, содержат баги в большинстве версий ядра RedHat и ее клонов. Рекомендуется использовать htcp.
По умолчанию:
cat /proc/sys/net/ipv4/tcp_congestion_control cubic
Для сервера рекомендуется использовать htcp:
sysctl -w net.ipv4.tcp_congestion_control=htcp
tcp_no_metrics_save
— данная опция запрещает сохранять результаты изменений TCP соединения в кеше при его закрытии.
По умолчанию опция ничего не запрещает:
cat /proc/sys/net/ipv4/tcp_no_metrics_save 0
Так как это помогает повысить производительность, рекомендуется включить:
sysctl -w net.ipv4.tcp_no_metrics_save=1
net.ipv4.route.flush
— актуально для ядер 2.4. По странной причине в ядрах 2.4, если в рамках TCP сессии произошел повтор передачи с уменьшенным размером окна, все соединения с данным хостом в следующие 10 минут будут иметь именно этот уменьшенный размер окна. Данная настройка позволяет этого избежать.
Так как в ядре 3.2 она даже не читается, менять ничего не стал.
ip_local_port_range
— опция, которая содержит диапазон локальных портов, доступных для установки исходящих подключений.
По умолчанию там такой диапазон:
cat /proc/sys/net/ipv4/ip_local_port_range 32768 61000
Для тяжелых проектов диапазон рекомендуется увеличить:
sysctl -w net.ipv4.ip_local_port_range="1024 65535"
tcp_tw_reuse
— опция позволяющая повторное использование TIME-WAIT сокетов в случаях, если протокол считает это безопасным.
По умолчанию отключена:
cat /proc/sys/net/ipv4/tcp_tw_reuse 0
Лучше включить:
sysctl -w net.ipv4.tcp_tw_reuse=1
tcp_window_scaling
— опция позволяет динамически изменять размер окна TCP стека
По умолчанию она включена:
cat /proc/sys/net/ipv4/tcp_window_scaling 1
Лучше так и оставить:
sysctl -w net.ipv4.tcp_window_scaling=1
tcp_rfc1337
— с помощью этой опции мы можем защитить себя от TIME_WAIT атак.
По умолчанию опция отключена:
cat /proc/sys/net/ipv4/tcp_rfc1337 0
На сервере она точно не помешает:
sysctl -w net.ipv4.tcp_rfc1337=1
ip_forward
— данная опция управляет переадресацией пакетов. Если этот параметр выключен, ОС считает себя узлом IP сети и дропает все пакеты, предназначенные не ей. Если параметр включен, то ОС считает себя маршрутизатором и действует в соответствии с RFC1812, в том числе пытается переслать адресованные не ей пакеты в соответствии с таблицей маршрутизации.
По умолчанию переадресация включена:
cat /proc/sys/net/ipv4/ip_forward 0
Если сервер не является маршрутизатором, то включать эту опцию нет необходимости:
sysctl -w net.ipv4.ip_forward=0
tcp_abort_on_overflow
— Эта переменная заставляет ядро отвергать новые соединения, если их поступает количество, с которым система не в состоянии справиться. Эту переменную следует использовать как крайнюю меру! По умолчанию она отключена:
cat /proc/sys/net/ipv4/tcp_abort_on_overflow 0
Если ситуация требует, то ее можно включить:
sysctl -w net.ipv4.tcp_abort_on_overflow=1
Как все это применить?
Я намеренно для изменения параметров использовал утилиту sysctl, а значения этих параметров просто читал с помощью cat. Сделано это было все для того, чтобы вам было ясно что способов изменения параметров ядра много.
Например, внести изменения мы так же можем с помощью echo:
echo "20000" > /proc/sys/net/ipv4/tcp_max_syn_backlog
А прочитать значения мы так же можем с помощью команды sysctl:
sysctl net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_max_syn_backlog = 2048
Кому какой способ больше нравится — решайте сами.
Как применить все эти значения разом, не сохраняя их?
Можно прочитать все описание выше и каждую переменную применять руками, с помощью «sysctl -w», и все эти значения будут работать до тех пор, пока вы не перезагрузите систему. Это полезно, пока ваше ядро находится в режиме «вашей отладки».
Для удобства ниже приведены все параметры разом, если решение вам нужно здесь и сейчас:
# включает фильтр обратного пути, она же защита от спуфинга (включаем строгий режим) sysctl -w net.ipv4.conf.all.rp_filter=1 # запрет маршрутизации от источников sysctl -w net.ipv4.conf.all.accept_source_route=0 sysctl -w net.ipv4.conf.lo.accept_source_route=0 sysctl -w net.ipv4.conf.eth0.accept_source_route=0 sysctl -w net.ipv4.conf.default.accept_source_route=0 # запрещаем принимать и отправлять ICMP пакеты перенаправления sysctl -w net.ipv4.conf.all.accept_redirects=0 sysctl -w net.ipv4.conf.all.secure_redirects=0 sysctl -w net.ipv4.conf.all.send_redirects=0 # отключаем ответ на broadcast ICMP ECHO sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1 # игнорируем ошибочные ICMP запросы sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1 # ответ на ICMP запросы sysctl -w net.ipv4.icmp_echo_ignore_all=0 # отключаем механизм SYN cookies (лучше отключить на высоконагруженных серверах) sysctl -w net.ipv4.tcp_syncookies=0 # максимальное число полуоткрытых соединений sysctl -w net.ipv4.tcp_max_syn_backlog=4096 # время удержания полуоткрытых соединений sysctl -w net.ipv4.tcp_synack_retries=1 # определяет максимальное число осиротевших TCP пакетов sysctl -w net.ipv4.tcp_max_orphans=65536 # время ожидания приема FIN до полного закрытия сокета sysctl -w net.ipv4.tcp_fin_timeout=10 # проверять TCP-соединения sysctl -w net.ipv4.tcp_keepalive_time=60 # интервал передачи проб sysctl -w net.ipv4.tcp_keepalive_intvl=15 # количество проверок перед закрытием соединения sysctrl -w net.ipv4.tcp_keepalive_probes=5 # макс. кол-во пакетов в очереди на обработку, если интерфейс получает пакеты быстрее, чем ядро может их обработать sysctl -w net.core.netdev_max_backlog=1000 # Максимальное число открытых сокетов, ждущих соединения sysctl -w net.core.somaxconn=15000 # размер приемного буфера сокетов TCP (мин-нагрузка-макс) sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216" # размер передающего буфера сокетов TCP (мин-нагрузка-макс) sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216" # размер буфера приема данных по умолчанию для всех соединений sysctl -w net.core.rmem_default=229376 # Размер буфера передачи данных по умолчанию для всех соединений sysctl -w net.core.wmem_default=229376 # макс. размер буфера приема данных для всех соединений sysctl -w net.core.rmem_max=16777216 # макс. размер буфера передачи данных для всех соединений sysctl -w net.core.wmem_max=16777216 # число неудачных попыток, после которого уничтожается соединение TCP, закрытое на локальной стороне sysctl -w net.ipv4.tcp_orphan_retries=0 # макс кол-во соединений для работы механизма connection tracking sysctl -w net.ipv4.netfilter.ip_conntrack_max=16777216 # включает временные метки протокола TCP sysctl -w net.ipv4.tcp_timestamps=1 # разрешаем выборочные подтверждения протокола TCP sysctl -w net.ipv4.tcp_sack=1 # протокол, используемый для управления нагрузкой в сетях TCP sysctl -w net.ipv4.tcp_congestion_control=htcp # запрещаем сохранять результаты изменений TCP соединения в кеше при его закрытии sysctl -w net.ipv4.tcp_no_metrics_save=1 # диапазон локальных портов, доступных для установки исходящих подключений sysctl -w net.ipv4.ip_local_port_range="1024 65535" # включаем повторное использование TIME-WAIT сокетов для безопасных протоколов sysctl -w net.ipv4.tcp_tw_reuse=1 # разрешаем динамически изменять размер окна TCP стека sysctl -w net.ipv4.tcp_window_scaling=1 # включаем защиту от TIME_WAIT атак sysctl -w net.ipv4.tcp_rfc1337=1 # отключаем переадресацию пакетов sysctl -w net.ipv4.ip_forward=0
Как сохранить эти значения?
Если сервер работает корректно со всеми настройками указанными выше, то для их сохранения достаточно добавить все эти переменные в конец файла /etc/sysctl.conf:
net.ipv4.conf.all.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.conf.all.accept_redirects=0 net.ipv4.conf.all.secure_redirects=0 net.ipv4.conf.all.send_redirects=0 net.ipv4.icmp_echo_ignore_broadcasts=1 net.ipv4.icmp_ignore_bogus_error_responses=1 net.ipv4.icmp_echo_ignore_all=0 net.ipv4.tcp_syncookies=0 net.ipv4.tcp_max_syn_backlog=4096 net.ipv4.tcp_synack_retries=1 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.core.netdev_max_backlog=1000 net.core.somaxconn=15000 net.ipv4.tcp_rmem="4096 87380 16777216" net.ipv4.tcp_wmem="4096 65536 16777216" net.core.rmem_default=229376 net.core.wmem_default=229376 net.core.rmem_max=16777216 net.core.wmem_max=16777216 net.ipv4.tcp_orphan_retries=0 net.ipv4.netfilter.ip_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.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
Заключение
На этом вроде все. В процессе написания статьи я изучал всевозможные настройки ядра, поэтому если есть где-то неточности или вам есть чем дополнить данный материал — пишите, буду очень рад.
Источники и все такое…
- http://mtaalamu.ru/blog/93.html
- http://adminunix.ru/komandy-dlya-proverki-ddos-ataki/
- http://citforum.ru/operating_systems/linux/ipsysctl/3.shtml
- http://linux-notes.org/zashhita-ot-ddos-atak/
- http://firstwiki.ru/index.php/краткое_руководство_по…
- https://www.kernel.org/doc/Documentation/networking…
- https://www.opennet.ru/base/sys/sysctl_linux.txt.html
- https://www.opennet.ru/base/sys/tcp_tune.txt.html
- https://www.opennet.ru/docs/RUS/LARTC/x1727.html
- http://ru.fractalizer.ru/frpost_197/настройка-ядра-linux-…
- http://fx-files.ru/archives/602