Pull to refresh

Метод определения и динамической защиты от DDoS типа SYN-flood

Reading time4 min
Views16K
Привет, Хабрасообщество.

Об актуальности DDoS атак в наше время рассказывать не стану. Достаточно взглянуть на статистику. Сталкиваюсь с атаками по роду деятельности довольно часто, возникла идея динамической защиты от DDoS типа SYN-flood на северах Linux и FreeBSD. Также предложена реализация мониторинга SYN-flood по SNMP.

Об этом всём под катом.

Параметры 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 секунд)
Аналогичные параметры для FreeBSD представлены в блоге.

Видим, что значения попыток повторной передачи и интервалы между ними очень велики. Идея в том, чтобы их уменьшить, не нова. Но стоит ли это делать статически на этапе загрузки системы? На сегодняшний день количество мобильных абонентов сети Интернет стремительно возростает, но в странах СНГ большинство из них осуществляет доступ через EDGE (а то и GPRS). Поэтому для таких посетителей сайта не стоит выставлять жесткие значения в ядре – они могут только из-за этого получить отказ в обслуживании даже при отсутствии атаки. Идеальный вариант – когда значения стоят близки к дефолтным при отсутствии атаки (они способствуют успешной установке соединения), и когда они уменьшены (кроме длины очереди) в условиях атаки.

Однажды меня посетила упомянутая идея именно с динамическим изменением параметров. Есть сомнения, действительно ли это полезно и не выставить ли значения на этапе загрузки системы статически. Данную проблему я описывал в блоге. Буду рад услышать мнения читателей по данному вопросу.

Отдельно про очередь SYN-запросов


Значение очереди 128 по умолчанию очень мало для нагруженой системы, тем более если она поддается атаке, поэтому естественно должна быть увеличена. Но существует предел, который ограничивает это увеличение.
Во-первых, каждое вхождение в очередь занимает 600 байт оперативной памяти.
Во-вторых, отдельная очередь длиной net.core.somaxconn отвеодится для каждого сервиса, слушающего порт TCP.
Исходя из этих соображений, значение net.core.somaxconn можно вычислять по формуле:
somaxconn = (MEMfree – MEMres)/600*N, где
MEMfree – текущая свободная RAM
MEMres – память, которую резервируем для работы системы и других программ
600 байт – занимает каждое вхождение в очередь
N – количество сервисов, слущающих порты TCP

Реализация в виде расширения для SNMP


Данная идея реализована в виде скрипта. К нему также прилагается конфигурационный файл, в котором можно настроить работу под свою систему вплоть до добавления/удаления изменяющихся параметров ядра по своему усмотрению. Я использую этот скрипт как расширение для SNMP. Есть версии для Linux и FreeBSD.

Вопрос: зачем дергать скрипт по SNMP, если можно по крону?
Ответ: это позволяет не только менять параметры ядра на лету, но и выполнить интеграцию с любой системой мониторинга, работающей по SNMP – настроить оповещения и тд. Лично я использую фронтенд для RRD Cacti и получаю графики загрузки очереди SYN. Шаблоны для Cacti доступны для скачивания на сайте. Данный вопрос не принципиален, функции защиты и расширения SNMP можно разнести по разным скриптам.

Тестирование защиты


Работа системы тестировалась на десктопе и лэптопе, подключенными к одному 100Mb L2 коммутатору. Тестировал с помощью hping.

Результаты на графике, построенном в режиме реального времени Cacti:

График Cacti

В режиме динамической защиты наблюдаются характерные пики. Они возникают вследствии того, что атака мониторится по пороговому значению – threshold. В будущем планирую мониторить по частоте заполнения и уменьшить эти пики.
Когда на графике замечены пики, вручную можно выставить форсированную защиту, когда параметры ядра устанавливаются в жесткие значения и не изменяются в зависимости от длины очереди. На графике видим, что значение очереди приблизилось почти к 0.

Замечания


1. На нагруженных серверах значение очереди 0 практически не бывает. Оно колеблется от 0 до ~40 в нормальном режиме, поэтому порог нужно подбирать.
2. Очередь SYN-запросов непременно возрастает и при HTTP-flood, поэтому детектирование атаки по пороговому значению очереди не совсем корректно. Хотя помехи собой не представляет и даже полезно.

Сайт


Для простоты ознакомления и настройки создал сайт synflood-defender.net. На нем представлены фичи существующие и планирующиеся, ссылка для скачивания, пошаговая инструкция по настройке и блог, в котором периодически будут появляться полезные записи по тематике DDoS.
Недавно скрипт помог защитить сервер одного товарища из Бразилии. В знак благодарности он опубликовал португальский перевод страницы How to use. Так что те хабрачитатели, кому удобнее читать на португальском, не ощутят дискомфорта ;)
Tags:
Hubs:
+41
Comments30

Articles

Change theme settings