Привет, Хабрасообщество.
Об актуальности DDoS атак в наше время рассказывать не стану. Достаточно взглянуть на статистику. Сталкиваюсь с атаками по роду деятельности довольно часто, возникла идея динамической защиты от DDoS типа SYN-flood на северах Linux и FreeBSD. Также предложена реализация мониторинга SYN-flood по SNMP.
Об этом всём под катом.
Операционные системы предоставляют возможность тонкой настройки параметров для работы в сети по протоколу TCP. На UNIX это производится путем изменения значений параметров ядра. Ниже описаны параметры, которые влияют на обработку очереди SYN-запросов. В скобках приведены значения по умолчанию:
Видим, что значения попыток повторной передачи и интервалы между ними очень велики. Идея в том, чтобы их уменьшить, не нова. Но стоит ли это делать статически на этапе загрузки системы? На сегодняшний день количество мобильных абонентов сети Интернет стремительно возростает, но в странах СНГ большинство из них осуществляет доступ через EDGE (а то и GPRS). Поэтому для таких посетителей сайта не стоит выставлять жесткие значения в ядре – они могут только из-за этого получить отказ в обслуживании даже при отсутствии атаки. Идеальный вариант – когда значения стоят близки к дефолтным при отсутствии атаки (они способствуют успешной установке соединения), и когда они уменьшены (кроме длины очереди) в условиях атаки.
Однажды меня посетила упомянутая идея именно с динамическим изменением параметров. Есть сомнения, действительно ли это полезно и не выставить ли значения на этапе загрузки системы статически. Данную проблему я описывал в блоге. Буду рад услышать мнения читателей по данному вопросу.
Значение очереди 128 по умолчанию очень мало для нагруженой системы, тем более если она поддается атаке, поэтому естественно должна быть увеличена. Но существует предел, который ограничивает это увеличение.
Во-первых, каждое вхождение в очередь занимает 600 байт оперативной памяти.
Во-вторых, отдельная очередь длиной net.core.somaxconn отвеодится для каждого сервиса, слушающего порт TCP.
Исходя из этих соображений, значение net.core.somaxconn можно вычислять по формуле:
somaxconn = (MEMfree – MEMres)/600*N, где
MEMfree – текущая свободная RAM
MEMres – память, которую резервируем для работы системы и других программ
600 байт – занимает каждое вхождение в очередь
N – количество сервисов, слущающих порты TCP
Данная идея реализована в виде скрипта. К нему также прилагается конфигурационный файл, в котором можно настроить работу под свою систему вплоть до добавления/удаления изменяющихся параметров ядра по своему усмотрению. Я использую этот скрипт как расширение для SNMP. Есть версии для Linux и FreeBSD.
Вопрос: зачем дергать скрипт по SNMP, если можно по крону?
Ответ: это позволяет не только менять параметры ядра на лету, но и выполнить интеграцию с любой системой мониторинга, работающей по SNMP – настроить оповещения и тд. Лично я использую фронтенд для RRD Cacti и получаю графики загрузки очереди SYN. Шаблоны для Cacti доступны для скачивания на сайте. Данный вопрос не принципиален, функции защиты и расширения SNMP можно разнести по разным скриптам.
Работа системы тестировалась на десктопе и лэптопе, подключенными к одному 100Mb L2 коммутатору. Тестировал с помощью hping.
Результаты на графике, построенном в режиме реального времени Cacti:
В режиме динамической защиты наблюдаются характерные пики. Они возникают вследствии того, что атака мониторится по пороговому значению – threshold. В будущем планирую мониторить по частоте заполнения и уменьшить эти пики.
Когда на графике замечены пики, вручную можно выставить форсированную защиту, когда параметры ядра устанавливаются в жесткие значения и не изменяются в зависимости от длины очереди. На графике видим, что значение очереди приблизилось почти к 0.
1. На нагруженных серверах значение очереди 0 практически не бывает. Оно колеблется от 0 до ~40 в нормальном режиме, поэтому порог нужно подбирать.
2. Очередь SYN-запросов непременно возрастает и при HTTP-flood, поэтому детектирование атаки по пороговому значению очереди не совсем корректно. Хотя помехи собой не представляет и даже полезно.
Для простоты ознакомления и настройки создал сайт synflood-defender.net. На нем представлены фичи существующие и планирующиеся, ссылка для скачивания, пошаговая инструкция по настройке и блог, в котором периодически будут появляться полезные записи по тематике DDoS.
Недавно скрипт помог защитить сервер одного товарища из Бразилии. В знак благодарности он опубликовал португальский перевод страницы How to use. Так что те хабрачитатели, кому удобнее читать на португальском, не ощутят дискомфорта ;)
Об актуальности 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 секунд)
Видим, что значения попыток повторной передачи и интервалы между ними очень велики. Идея в том, чтобы их уменьшить, не нова. Но стоит ли это делать статически на этапе загрузки системы? На сегодняшний день количество мобильных абонентов сети Интернет стремительно возростает, но в странах СНГ большинство из них осуществляет доступ через 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:
В режиме динамической защиты наблюдаются характерные пики. Они возникают вследствии того, что атака мониторится по пороговому значению – threshold. В будущем планирую мониторить по частоте заполнения и уменьшить эти пики.
Когда на графике замечены пики, вручную можно выставить форсированную защиту, когда параметры ядра устанавливаются в жесткие значения и не изменяются в зависимости от длины очереди. На графике видим, что значение очереди приблизилось почти к 0.
Замечания
1. На нагруженных серверах значение очереди 0 практически не бывает. Оно колеблется от 0 до ~40 в нормальном режиме, поэтому порог нужно подбирать.
2. Очередь SYN-запросов непременно возрастает и при HTTP-flood, поэтому детектирование атаки по пороговому значению очереди не совсем корректно. Хотя помехи собой не представляет и даже полезно.
Сайт
Для простоты ознакомления и настройки создал сайт synflood-defender.net. На нем представлены фичи существующие и планирующиеся, ссылка для скачивания, пошаговая инструкция по настройке и блог, в котором периодически будут появляться полезные записи по тематике DDoS.
Недавно скрипт помог защитить сервер одного товарища из Бразилии. В знак благодарности он опубликовал португальский перевод страницы How to use. Так что те хабрачитатели, кому удобнее читать на португальском, не ощутят дискомфорта ;)