Привет, Хабрасообщество.
Об актуальности DDoS атак в наше время рассказывать не стану. Достаточно взглянуть на статистику. Сталкиваюсь с атаками по роду деятельности довольно часто, возникла идея динамической защиты от DDoS типа SYN-flood на северах Linux. Данный тип атак базируется на принципе трехкратного рукопожатия в TCP.
В результате имеем расширение для протокола SNMP для мониторинга и защиты от SYN-flood + графики загрузки очереди SYN-запросов в Cacti.
Операционные системы предоставляют возможность тонкой настройки параметров для работы в сети по протоколу TCP. На UNIX это производится путем изменения значений параметров ядра. Ниже привожу параметры, которые влияют на обработку очереди SYN-запросов. В скобках приведены значения по умолчанию:
Значение очереди 128 по умолчанию очень мало для нагруженой системы, тем более если она поддается атаке, поэтому естественно должна быть увеличена. Но существует предел, который ограничивает это увеличение.
Во-первых, каждое вхождение в очередь занимает 600 байт оперативной памяти.
Во-вторых, отдельная очередь длиной net.core.somaxconn отводится для каждого сервиса, слушающего свой порт.
Исходя из этих соображений, значение net.core.somaxconn можно вычислять по формуле:
somaxconn = (MEMfree – MEMres)/600*N, где
MEMfree — текущая свободная RAM
MEMres — память, которую резервируем для работы системы и других программ
600 байт — занимает каждое вхождение в очередь
N — количество сервисов, слущающих порты TCP
Мною был написан скрипт, в котором реализована данная идея. К нему также прилагается конфигурационный файл, в котором можно настроить работу под свою систему вплоть до добавления/удаления изменяющихся параметров ядра по своему усмотрению. Я использую этот скрипт как расширения для SNMP.
Вопрос: зачем дергать скрипт по SNMP, если можно по крону?
Ответ: это позволяет не только менять параметры ядра на лету, но и выполнить интеграцию с любой системой мониторинга, работающей по SNMP — настроить оповещения и тд. Лично я использую фронтенд для RRD Cacti и получаю графики загрузки очереди SYN. Шаблоны для Cacti доступны для скачивания на сайте.
Работа системы тестировалась на десктопе и лэптопе, подключенными к одному 100Mb L2 коммутатору. Тестировал с помощью hping:
Результаты на графике, построенном в режиме реального времени Cacti:

В режиме динамической защиты наблюдаются характерные пики. Они возникают вследствии того, что атака мониторится по пороговому значению – threshold. В будущем планирую мониторить по частоте заполнения и уменьшить эти пики.
Когда на графике замечены пики, вручную можно выставить форсированную защиту, когда параметры ядра устанавливаются в жесткие значения и не изменяются в зависимости от длины очереди. На графике видим, что значение очереди приблизилось почти к 0.
Для простоты ознакомления и настройки создал сайт. На нем представлены фичи существующие и планирующиеся, ссылка для скачивания, пошаговая инструкция по настройке и блог, в котором периодически будут появляться полезные записи по тематике DDoS.
Об актуальности DDoS атак в наше время рассказывать не стану. Достаточно взглянуть на статистику. Сталкиваюсь с атаками по роду деятельности довольно часто, возникла идея динамической защиты от DDoS типа SYN-flood на северах Linux. Данный тип атак базируется на принципе трехкратного рукопожатия в TCP.
В результате имеем расширение для протокола SNMP для мониторинга и защиты от SYN-flood + графики загрузки очереди SYN-запросов в Cacti.
Параметры TCP
Операционные системы предоставляют возможность тонкой настройки параметров для работы в сети по протоколу TCP. На UNIX это производится путем изменения значений параметров ядра. Ниже привожу параметры, которые влияют на обработку очереди SYN-запросов. В скобках приведены значения по умолчанию:
- net.core.somaxconn — максимальная величина очереди соединений (128)
- tcp_syn_retries — количество попыток передать SYN для удачного установления соединения (5)
- tcp_synack_retries — количество попыток передать ответ SYN,ACK на SYN-запрос (5)
- tcp_keepalive_intvl — как долго ожидать ответа каждой пробы keepalive (75 секунд)
- tcp_keepalive_probes — количество проб TCP keepalive, которую нужно передать перед принятием решения, что соединение утеряно (9)
- tcp_keepalive_time — частота, с которой необходимо передавать пакеты TCP keepalive для поддержания активности соединения, если оно не используется в текущий момент (7200 секунд)
Отдельно про очередь SYN-запросов
Значение очереди 128 по умолчанию очень мало для нагруженой системы, тем более если она поддается атаке, поэтому естественно должна быть увеличена. Но существует предел, который ограничивает это увеличение.
Во-первых, каждое вхождение в очередь занимает 600 байт оперативной памяти.
Во-вторых, отдельная очередь длиной net.core.somaxconn отводится для каждого сервиса, слушающего свой порт.
Исходя из этих соображений, значение net.core.somaxconn можно вычислять по формуле:
somaxconn = (MEMfree – MEMres)/600*N, где
MEMfree — текущая свободная RAM
MEMres — память, которую резервируем для работы системы и других программ
600 байт — занимает каждое вхождение в очередь
N — количество сервисов, слущающих порты TCP
Реализация в виде расширения для SNMP
Мною был написан скрипт, в котором реализована данная идея. К нему также прилагается конфигурационный файл, в котором можно настроить работу под свою систему вплоть до добавления/удаления изменяющихся параметров ядра по своему усмотрению. Я использую этот скрипт как расширения для SNMP.
Вопрос: зачем дергать скрипт по SNMP, если можно по крону?
Ответ: это позволяет не только менять параметры ядра на лету, но и выполнить интеграцию с любой системой мониторинга, работающей по SNMP — настроить оповещения и тд. Лично я использую фронтенд для RRD Cacti и получаю графики загрузки очереди SYN. Шаблоны для Cacti доступны для скачивания на сайте.
Тестирование защиты
Работа системы тестировалась на десктопе и лэптопе, подключенными к одному 100Mb L2 коммутатору. Тестировал с помощью hping:
hping -S -p 80 --rand-source X.X.X.X
Результаты на графике, построенном в режиме реального времени Cacti:

В режиме динамической защиты наблюдаются характерные пики. Они возникают вследствии того, что атака мониторится по пороговому значению – threshold. В будущем планирую мониторить по частоте заполнения и уменьшить эти пики.
Когда на графике замечены пики, вручную можно выставить форсированную защиту, когда параметры ядра устанавливаются в жесткие значения и не изменяются в зависимости от длины очереди. На графике видим, что значение очереди приблизилось почти к 0.
Замечания
- На рабочих серверах значение очереди 0 практически не бывает. Оно колеблется от 0 до ~40 в нормальном режиме, поэтому порог нужно подбирать.
- Очередь SYN-запросов непременно возрастает и при HTTP-flood, поэтому детектирование атаки по пороговому значению не всегда однозначно. Хотя помехи собой не представляет и даже полезно.
Сайт
Для простоты ознакомления и настройки создал сайт. На нем представлены фичи существующие и планирующиеся, ссылка для скачивания, пошаговая инструкция по настройке и блог, в котором периодически будут появляться полезные записи по тематике DDoS.