Pull to refresh

Недорогой способ защиты от HTTP-флуда

Reading time3 min
Views16K
Случилась на днях, как всегда, не в самый подходящий момент, DDoS-атака на один из сайтов, размещенных на моем сервере. DDoS-атаки бывают разные, в этот раз злоумышленники запустили HTTP флуд.

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

Железные решения я считаю правильным выбором, но доступны они не всем и не всегда, а многие атаки, как показала моя практика, успешно отбиваются правильным использованием доступных программных средств. К тому же, захотелось немного поэкспериментировать.



После детального изучения возможностей давно и вполне успешно используемой мною связки nginx + Apache и документации к nginx родилось решение на базе модуля ngx_http_limit_req_module.

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

Что я сделал



Я проверил, собран ли nginx с модулем ngx_http_limit_req_module и внес в конфигурационный файл сервера следующие строки:

http {<br>    # Директива описывает зону, в которой хранятся состояния сессий. <br>    # Значения сессий определяется заданной переменной. <br>    <br>    limit_req_zone $binary_remote_addr zone=one:10m  rate=2r/s;<br>    <br>    # В данном случае состояния сессий хранятся в зоне "one" размером <br>    # 10 мегабайт и средняя скорость запросов для этой зоны не может <br>    # более 2 запросов в секунду. <br>    <br>    # Данный случай частный лично для моей <br>    # ситуации и подбирается индивидуально.<br>    <br>    ...<br>    <br>    # Атакуемый домен.<br>    server {<br><br>        ...<br><br>        location / {<br>            # Директива задаёт зону (zone) и максимально возможные всплески<br>            # запросов (burst). Если скорость запросов превышает описанную <br>            # в зоне, то их обработка запроса задерживается так, чтобы запросы <br>            # обрабатывались с заданной скоростью. Избыточные запросы задерживаются<br>            # до тех пор, пока их число не превысит <br>            # заданное число всплесков. В этом случае запрос завершается кодом <br>            # "Service unavailable" (503).<br>            <br>            limit_req  zone=one burst=4;<br>        }<br><br>* This source code was highlighted with Source Code Highlighter.


* пример конфигурации и пояснения со страницы документации по модулю


Что я получил



Все боты, которые с неистовой частотой «долбили» сервер, начали получать в ответ http- ошибку 503. А выбрать с логов IP ботов например так:

tail -1000 /var/log/nginx-access.log | grep " 503 " | cut -f1 -d" " | sort -u


И после этого занести их в таблицу фаервола (у меня FreeBSD и IPFW) проще некуда, равно как и поставить это все в crontab.

Вот, собственно, и все. На оригинальность идеи я не претендую, спасибо Игорю Сысоеву за реализацию nginx и данного модуля к нему.

Надеюсь, этот вполне доступный способ защиты от динамичного и интенсивного по частоте запросов HTTP-флуда будет вам полезен.

Tags:
Hubs:
+47
Comments100

Articles

Change theme settings