Защита от простых DDoS и ботов: модуль limit_req в Nginx
Защита от простых DDoS и ботов: модуль limit_req в Nginx
Представьте: ваш сайт внезапно начинает тормозить, а сервер валится под натиском тысяч запросов в секунду. Это не вирус и не хакерская атака в классическом смысле — это DDoS (распределённый отказ в обслуживании) или ботнет, который методично "забивает" ваш сервер мусорными запросами. Если вы арбитражник или веб-мастер, такая ситуация означает простой рекламы, потерю денег и репутации.
Но есть хорошая новость: Nginx умеет защищаться от таких атак "из коробки" с помощью модуля limit_req. Сегодня вы научитесь настраивать его так, чтобы:
✅ Ограничивать количество запросов с одного IP (или других ключей).
✅ Замедлять ботов, не блокируя реальных пользователей.
✅ Фильтровать подозрительный трафик ещё на уровне веб-сервера, не нагружая бэкенд.
Это не панацея от сложных DDoS (для них нужны Cloudflare, Akamai или специализированные решения), но 90% простых атак и ботов вы сможете отсечь самостоятельно — бесплатно и за 10 минут.
1. Как работает limit_req: простая аналогия
Представьте, что ваш сервер — это ресторан с одним поваром. Вдруг в дверь ломятся 100 человек и каждый кричит: "Мне бургер! Срочно!". Пovar не успевает, клиенты злятся, а настоящие гости (ваши пользователи) уходят, потому что не могут пробиться через толпу.
Модуль limit_req — это вышибала у двери, который говорит:
- "Стоять в очереди! Заказывать можно не чаще, чем раз в 5 секунд!"
- "Если ты уже заказал 10 бургеров за минуту — иди отсюда, ты подозрителен!"
Результат:
- Нормальные посетители получают обслуживание без задержек.
- Боты и DDoS-ботнеты "задыхаются" в ограничениях и уходят искать более лёгкую жертву.
2. Ключевые понятия: что нужно знать перед настройкой
| Термин | Описание | Пример значения |
|---|---|---|
Зона (zone) |
Область памяти, где Nginx хранит счётчики запросов для каждого ключа (IP, куки и т.д.). | limit_req_zone=one:10m |
Ключ (key) |
Параметр, по которому группируются запросы (обычно $binary_remote_addr — IP клиента). |
$binary_remote_addr |
Скорость (rate) |
Максимальное количество запросов в единицу времени (например, 10r/s). |
10r/s (10 запросов/сек) |
Всплеск (burst) |
Сколько запросов можно сделать "запасом" сверх лимита, если сервер не загружен. | burst=20 |
Задержка (nodelay) |
Если не указано — Nginx будет искусственно задерживать ответы при превышении лимита. | nodelay (отключает задержки) |
Важно:
burstпозволяет кратковременно превышать лимит (например, при загрузке страницы с множеством ресурсов).- Без
nodelayNginx будет замедлять ответы боту, вместо того чтобы отдавать ошибку503. Это полезно, чтобы "заморить голодом" атакующего.
3. Базовая настройка: ограничение по IP
Шаг 1. Определяем зону ограничений
Добавьте в конфиг Nginx (обычно /etc/nginx/nginx.conf или /etc/nginx/conf.d/limit.conf) следующее:
http {
# Создаём зону "one" размером 10Мб, ключ — IP клиента
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
...
}
Что это значит?
$binary_remote_addr— IP клиента в бинарном формате (экономит память).zone=one:10m— зона называетсяone, занимает 10 Мб (хватит на ~160 000 уникальных IP).rate=10r/s— не более 10 запросов в секунду с одного IP.
Шаг 2. Применяем ограничение к сайту
В конфиге вашего сайта (например, /etc/nginx/sites-available/your-site.conf) добавьте:
server {
...
location / {
# Применяем зону "one", разрешаем burst=20 (запас на кратковременные всплески)
limit_req zone=one burst=20 nodelay;
# Если лимит превышен — возвращаем ошибку 503
limit_req_status 503;
}
}
Что происходит?
- Если IP отправляет ≤10 запросов/сек — всё работает нормально.
- Если 11-30 запросов/сек — Nginx использует
burst(запас), но не блокирует. - Если >30 запросов/сек — клиент получает HTTP 503 (Service Unavailable).
Шаг 3. Перезагружаем Nginx
sudo nginx -t # Проверяем конфиг на ошибки
sudo systemctl reload nginx
4. Продвинутые сценарии: тонкая настройка
Сценарий 1: Разные лимиты для разных URL
Например, ограничить /api/ строже, чем /static/:
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=static:10m rate=20r/s;
server {
location /api/ {
limit_req zone=api burst=10;
}
location /static/ {
limit_req zone=static burst=30;
}
}
Сценарий 2: Ограничение по кукам (для авторизованных пользователей)
Если у вас есть пользователи с сессиями, можно ограничивать по кукам вместо IP (полезно, если за NAT сидит много людей с одним IP):
limit_req_zone $cookie_sessionid zone=users:10m rate=20r/s;
server {
location /dashboard/ {
limit_req zone=users burst=30;
}
}
Сценарий 3: Замедление вместо блокировки (nodelay)
Если вы хотите не блокировать, а замедлять ботов (чтобы они тратили больше времени на атаку):
location / {
limit_req zone=one burst=20; # Убираем nodelay — Nginx будет задерживать ответы
}
Эффект:
- При превышении лимита Nginx будет отдавать данные с задержкой (например, по 1 запросу в секунду).
- Ботнет будет "вязнуть", тратить ресурсы зря.
5. Логи и мониторинг: как понять, что работает?
Проверка текущих ограничений
Вы можете посмотреть статистику по зонам с помощью ngx_http_limit_req_module:
# Включаем отображение зон в конфиге Nginx
http {
limit_req_status 503;
...
}
# После этого в логах (/var/log/nginx/error.log) будут записи типа:
# 2024/02/20 12:34:56 [error] 1234#0: *1000 limiting requests, excess: 5.000 by zone "one", client: 192.168.1.1, server: example.com, request: "GET / HTTP/1.1", host: "example.com"
Тестирование с помощью ab (Apache Benchmark)
Установите утилиту ab и проверьте, как Nginx реагирует на нагрузку:
ab -n 1000 -c 50 http://ваш-сайт/
-n 1000— всего 1000 запросов.-c 50— одновременно 50 соединений.
Что смотреть?
- Если >50% запросов возвращают 503 — ограничение работает.
- Если все запросы проходят — увеличьте
rateили уменьшитеburst.
6. Типичные ошибки и как их избежать
| Ошибка | Причина | Решение |
|---|---|---|
| Nginx не ограничивает запросы | Зона не применена в location или неправильный key. |
Проверьте limit_req zone=... в нужном блоке. |
| Слишком много ложных срабатываний | Слишком низкий rate (например, 1r/s). |
Увеличьте rate до 10-20r/s для обычных сайтов. |
| Памяти не хватает на все IP | Зона слишком мала (например, zone=one:1m для 100к IP). |
Увеличьте размер зоны (1 Мб ≈ 16 000 IP). |
| Боты обходят ограничения | Используют разные IP или подделывают куки. | Комбинируйте limit_req с fail2ban или Cloudflare. |
| Замедление мешает реальным пользователям | Нет burst или слишком маленькое значение. |
Установите burst=20-50 для сглаживания пиковых нагрузок. |
7. Когда limit_req не поможет?
Модуль limit_req эффективен против:
✔ Простых DDoS (SYN-flood, HTTP-flood с одного IP).
✔ Ботнетов с низкой интенсивностью (сканеры, парсеры).
✔ Брутфорс-атак (перебор паролей).
Но он бессилен против: ✖ Распределённых атак (тысячи уникальных IP). ✖ Slowloris-атак (медленные запросы, занимающие соединения). ✖ Атак на уровне L3/L4 (UDP-flood, ICMP-flood).
Решение для сложных случаев:
- Cloudflare / Akamai (бесплатный тариф отсекает 90% мусора).
- Fail2Ban (банит IP после нескольких ошибок).
- Аппаратные firewall (например, FortiGate).
Практика для закрепления
Упражнение 1: Базовая настройка
- Создайте зону
oneс лимитом 5 запросов/сек иburst=10. - Примените её ко всему сайту.
- Протестируйте с помощью
ab -n 100 -c 10 http://ваш-сайт/. - Вопрос: Сколько запросов должно вернуться с кодом
503?
Упражнение 2: Разные лимиты для API
- Создайте отдельную зону
api_zoneс лимитом 2r/s иburst=5. - Примените её только к
/api/. - Вопрос: Что произойдёт, если бот будет слать 10 запросов в секунду в
/api/users?
Упражнение 3: Логи и анализ
- Найдите в логах Nginx (
/var/log/nginx/error.log) записи о превышении лимитов. - Вопрос: Какой параметр отвечает за сообщение
"limiting requests, excess: X"?
Упражнение 4: Замедление вместо блокировки
- Уберите
nodelayиз конфига. - Протестируйте с помощью
curlили браузера, отправляя запросы чаще лимита. - Вопрос: С какой задержкой приходят ответы?
Упражнение 5: Комбинирование с fail2ban (бонус)
- Настройте
fail2banна бан IP, которые получают слишком много503. - Вопрос: Какой фильтр нужно использовать в
/etc/fail2ban/jail.local?
Ответы на вопросы и разбор упражнений — в следующем уроке! А если возникли сложности — пишите в комментарии, разберём вместе. 🚀
Генератор паролей с длинной 64 символа
Женская одежда с бахромой
Кадастровые работы в Бийске
Как Aptum хостинг помогает малым бизнесам в управлении CRM-системами
Как выбрать планировку сайта для блогов на DreamHost
Как выбрать Vdsina вечный хостинг для своего проекта
Казань окна VEKA - профессионализм и опыт
Курьерская вода
Новостройки Оренбурга: недвижимость с отличной ценой
Онлайн чат-партнерство
Пиломатериалы для возведения бани
Почему VDSina — лучший выбор хостинга
Секреты Вконтакте: тонкости и хитрости
Скидки до 50% на тур в Коста-Рике
Видеочат рулетка бесплатно