Pull to refresh

Простой и эффективный метод отразить http DDoS от 50мбит с помощью nginx и iptables

Reading time7 min
Views67K
Здравствуй, Хабр!
Предлагаю твоему вниманию простой и в то же время эффективный метод борьбы с http DDoS. На основе сервера Xeon 2.5GHz / 4Gb RAM / SAS можно отражать атаку примерно до 300 Мбит/с (значение получено методом экстраполяции).

Способ реализация

Производится тонкая настройка параметров системы. Так что север будет способен выдерживать больше подключений от ботнета, чем канал до сервера сможет пропустить.

Область применения

Борьба с Http DDoS на выделенном сервере или ВПС. Максимальная возможная мощность сдерживания DDoS атаки ограничивается физическими возможностями сервера и пропускной способностью канала.

SEO под DDoS-ом

Ваш сайт будет правильно индексироваться во время атаки, что позволит сохранить позиции в выдаче поисковых систем. Особенно актуально для сайтов с большими SEO бюджетами.

Стоимость и эффективность

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

Описание метода

Я буду рассказывать о применение метода и достигнутых результатах, на основе реального случай борьбы с http DDoS атакой.

В моем распоряжении было два сервера Xeon 2.5GHz / 4Gb RAM / SAS, первый под PHP, второй под БД. Все настройки производились на первом сервере.ОС – Debian 4, сайт был с посещаемостью ~ 60к. Фронтендом являлся nginx. Ядро системы было настроено по умолчанию. Стандартное средство бана по ip – iptables в конкретном случае справилось с атакой ботнета размером до 7К.
В случае более мощной атаки придется установить ipset.

История борьбы с DDoS


День первый. Переполнение сетевого стека

IP адрес выделенный под ДОСом перестанет отвечать на какие-либо запросы (ping,http,ssh), при том что остальные IP сервера продолжат исправно работать. Если у сервера несколько IP то сайт под ДОСом ляжет, работа других сайтов на сервере и ssh нарушена не будет.
По умолчанию ОС Debian и другие ОС не в состоянии поддерживать огромное количество соединений создаваемое ботнетом. Необходимо внести изменения в настройки ядра, чтобы укрепить стек TCP/IP. Я не буду подробно останавливается на настройке ядра, приведу лишь пример такой конфигурации.

net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.core.rmem_max = 996777216
net.core.wmem_max = 996777216
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_mem= 786432 1048576 996777216
net.ipv4.tcp_wmem = 4096 87380 4194304
net.ipv4.tcp_max_orphans = 2255360
net.core.netdev_max_backlog = 10000
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 494967295
kernel.shmall = 268435456
net.core.somaxconn= 16096


Подобнее о параметрах можно прочитать в документации, например debian.telenet.ru/doc/sysctl.conf, а лучше поиск через google.com свежих статей по данной теме.
Аккуратно меняем конфигурацию ядра и перезагружаем сервер…
И так. Наша система способна выдержать натиск ботов. Но праздновать победу еще очень рано. Из-за огромного количества соединений процессы PHP и БД полностью «съедают» ресурсы памяти и процессора, так что значение load average превышает 100 пунктов.
Необходимо отсечь паразитные соединения

Недостатки поиска ботов командой netstat

Анти-дос администратор, к которому я обратился с проблемой, предложил метод поиска ботов командой netstat. В процессе применения данного метода я заметил несколько существенных недостатков. Рассмотрим их подробно:
1. Создание blacklist-а занимает много времени, что не позволяет нам часто обновлять blacklist
2. Эффективный поиск ботов возможен только при остановленном вебсервере. В это время сайт не доступен для клиентов и появляется угроза неправильной индексации сайта поисковыми системами
3. В blacklist могут попасть IP поисковых роботов, что недопустимо

Осознав неэффективность предложенного метода, я приступил к созданию своего метода поиска и бана ботов который должен
1. обеспечить постоянную стабильную работу вебсервера (сайта)
2. гарантирует наименьшую вероятность в blacklist поисковых роботов

День второй. Возможности железа сервера + nginx

Сервер Xeon 2.5GHz / 4Gb RAM / SAS DoS-ят запросами GET / HTTP/1.1.
  1. Эксперимент А. Веб сервер (в данном случае nginx) остановлен
    Входящий трафик 6085.2 kbits/sec
    Исходящий трафик 5342.1 kbits/sec
  2. Эксперимент Б. Nginx отдает пустой HTML (return 444;)
    Входящий трафик 56 Мбит/с
    Исходящий трафик 54 Мбит/с
  3. Эксперимент В. Nginx отдает HTML размером около 2 Кб – это страничка с небольшим сообщением вроде «приносим свои извинения за перебои в работе сайта»
    Входящий трафик 57 Мбит/с
    Исходящий трафик 353 Мбит/с

<… >*

На основе эксперимента можно сделать следующие выводы:

а) Можно полностью отказаться от фильтрации при наличии достаточной емкости канала и отсутствием соотношений входящий/исходящий трафик.
Ваш сайт будет доступен клиентам ценой огромного паразитного трафика.
Легкомысленное решение полностью отказаться от фильтрации. Злоумышленники могу увеличить мощность DoS так что «ляжет» гигабитный канал.

б) Когда мы забаним абсолютно всех ботов то паразитный трафик от ботнета составит всего лишь 5 Мбит/с. Забанить всех ботов также невозможно, на это потребуется слишком много ресурсов. Кроме того, высока вероятность бана поисковых роботов.

Также необходимо обратить внимание на то, что исходящий трафик с последнем случаем превысил 100 Мбит/с. Значит, сервер подключенный к порту 100 Мбит/с станет очень трудно доступен по ssh в силу полной загруженности канала. Во избежание подобной неприятности, я рекомендую настроить отдачу пустого HTML или return 444 в nginx до завершения настройки фильтрации ботов.

Поиск ботов средствами nginx

В данном случае сервер атакуют запросами request: «GET / HTTP/1.1».
Делаем предположение о том, что хорошие клиенты делают не более 2х одновременных запросов к главной странице сайта. Считаем клиентов открывших более 3х одновременных соединений атакующими ботами и баним их IP адресы на фаерволе.

Предположение было подтверждено экспериментально. На основе анализа лога http запросов за сутки из 120 000 IP адресов, только с 19ти IP было сделано более 2х одновременных запросов.

Для реализации поиска ботов создаем специальную обработку запросов
request: «GET / HTTP/1.1» в nginx.
error_log /var/log/nginx/error.log;
<…>
location =/ {
limit_conn one 3;
root /home/www/site.ru;
}

IP адреса с которых было открыто более 3х одновременных подключений буду записаны в error.log с сообщением limiting connections by zone. На основе лога ошибок мы сможем построить blacklist ip атакующего ботнета.

Фильтрация ботов в iptables

Важно заметить. IPtables не пригодны для фильтрации большого количества адресов. При количестве цепочек >2К iptables процесс ksoftirqd начинает потреблять 100% CPU, что приводит к запредельной загрузке сервера. Проблема решается установкой ipset или уменьшением количество правил в iptables.
В данном случае установка ipset была отложена на случай крайней необходимости. У сервера не было встроенного KVM и пересобрать ядро было рискованно.

Приступим к созданию blacklist-а. В бан мы помеcтим только самых агрессивных ботов, дабы не перегружать iptables.

# ищем ботов
cat /var/log/nginx/error.log | grep "limiting connections by zone" | grep "request: \"GET / HTTP/1.1"| awk '{print $12}'| awk -F"," '{print $
1}'| sort | uniq -c | sort -nr > /tmp/botnet.blacklist
# очищаем скрипт бана
cat /dev/null > /tmp/iptables_ban.sh
# создаем DROP правила для 50 самых агрессивных ботов
awk '{print "iptables -A INPUT -p tcp --dport 80 -s " $2 " -j DROP" }' botnet.blacklist | head -n 50 >> /tmp/iptables_ban.sh
# загружаем blacklist
bash /tmp/iptables_ban.sh
# делаем ротацию лога
cat /dev/null > /home/www/nginx_log/error.log
[ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`


Добавляем скрипт в крон с частотой несколько минут. Частоту подбираем опытным путем. Я сделал раз в 5 минут.

*/5 * * * * /root/script/ban.sh

В результате iptables будет пополнятся новыми ботами.

Схема фильтрации
ddos nginx iptables

День третий. Итог


Данный метод обеспечил стабильный доступ клиентов к сайту. Правильная индексация в ПС была подтверждена тем, что сайт сохранил свои позиции в выдаче. Загрузка сервера не выходила за разумные пределы la неболее 6-7 пунктов. Исходящий трафик с сервера не превышал 100 Мбит/с. Для отражения атаки >7К ботнета вполне достаточно возможностей iptables.

DDoS как стихийное бедствие и избежать ущерба невозможно.
Часть клиентов, за время сбоя вашего сервиса, перейдет к конкурентам.
Вам придется понести некоторые расходы на переработки программистов, администраторов или приобретение дополнительного оборудования.
Ваш ресурс активно продвигается в ПС (yandex, google) значит, критичен риск неправильной индексации и как результат провал позиций в выдаче.
Главная задача минимизировать ущерб от DDoS.

В моем случае DDoS атака прекратилась на следующий день после запуска фильтрации. Заказчик DoS не был готов тратить больше денег на увеличение атаки.

В большинстве случаев DDoS является оружием конкурентной борьбы в сети. Клиенты практически мгновенно способны перейти к вашим конкурентам, если ваш ресурс будет работать со сбоями.

Я считаю, что борьба с DDoS заключается не в бане ботов, а в создании условий в которых ваш суммарный ущерб от атаки сопоставим с затратами ее инициаторов. Заказчик должен потрать, например, 50 000 руб. чтобы нанести вам ущерб в 50 000руб., конкурентам экономически не выгодно организовывать такие атаки.

Метод описанный в этой статье не является панацеей, это лишь часть комплекса мер по отражению DoS. План развития крупного сервиса должен учитывать риски и предлагать меры по уменьшению негативных последствий атак.

Надеюсь, моя статья будет полезна сообществу разработчиков и администраторов вебприложений.

___
* Я убрал из текста абзац про 300Мбит, т.к. он обоснованно вызывает нарекания.

«Свыше 300Мбит/с мы «упремся» в предел...» — справедливо для HDD отдающего видео/аудио, т.е. «тяжелые» файлы. Для HTML файлов это утверждение несправедливо.

Текст удаленного абзаца:
«По результатам проведенного эксперимента ясно, что сервер способен выдержать увеличение атаки примерно до 300Мбит/с. Свыше 300Мбит/с мы «упремся» в предел рандомного чтения SAS дисков. Значит, мы имеем хороший запас прочности и высока вероятность эффективного отражения атаки с сохранением доступности клиентам наших вебсервисов.»
Tags:
Hubs:
+165
Comments78

Articles

Change theme settings