Флуд был не столько тяжелый по трафику, сколько интенсивный по
количеству запросов. Причем, как назло, запросов не однотипных, а
постоянно меняющихся. Все, что у меня на тот момент было из софтовых
средств защиты, не могло эффективно справиться с таким флудом, поэтому
пришлось использовать железные решения.
Железные решения я считаю правильным выбором, но доступны они не всем и
не всегда, а многие атаки, как показала моя практика, успешно
отбиваются правильным использованием доступных программных средств. К
тому же, захотелось немного поэкспериментировать.
После детального изучения возможностей давно и вполне успешно
используемой мною связки nginx + Apache и документации к nginx родилось
решение на базе модуля ngx_http_limit_req_module.
Этот модуль позволяет ограничить число запросов для заданной сессии или
с одного адреса. Я не буду детально описывать его возможности,
документация доступна всем желающим.
Что я сделал
Я проверил, собран ли nginx с модулем ngx_http_limit_req_module и внес в конфигурационный файл сервера следующие строки:
http {
# Директива описывает зону, в которой хранятся состояния сессий.
# Значения сессий определяется заданной переменной.
# В данном случае состояния сессий хранятся в зоне "one" размером
# 10 мегабайт и средняя скорость запросов для этой зоны не может
# более 2 запросов в секунду.
# Данный случай частный лично для моей
# ситуации и подбирается индивидуально.
...
# Атакуемый домен.
server {
...
location / {
# Директива задаёт зону (zone) и максимально возможные всплески
# запросов (burst). Если скорость запросов превышает описанную
# в зоне, то их обработка запроса задерживается так, чтобы запросы
# обрабатывались с заданной скоростью. Избыточные запросы задерживаются
# до тех пор, пока их число не превысит
# заданное число всплесков. В этом случае запрос завершается кодом
# "Service unavailable" (503).