Защита от простых 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?
Ответы на вопросы и разбор упражнений — в следующем уроке! А если возникли сложности — пишите в комментарии, разберём вместе. 🚀
Введение: чем VDS отличается от шаред-хостинга и зачем это веб-мастеру
Как правильно выбрать тариф: CPU, RAM, NVMe или SSD, канал
Выбор операционной системы: почему Ubuntu 22.04/24.04 — стандарт индустрии
Регистрация домена и первичная настройка DNS-записей (A, AAAA, CNAME)
Генерация SSH-ключей на локальном компьютере (Windows/Mac/Linux)
Добавление публичного ключа на сервер и первый вход по SSH
Отключение входа по паролю и запрет авторизации для root
Смена стандартного порта SSH для снижения шума в логах
Создание основного рабочего пользователя с правами sudo
Базовое обновление системы и установка необходимых утилит (curl, wget, git, htop)
Настройка часового пояса и синхронизация времени (NTP)
Установка и базовая настройка фаервола UFW
Разрешение только необходимых портов (SSH, HTTP, HTTPS)
Установка Fail2Ban для защиты от перебора паролей
Настройка правил Fail2Ban для SSH и веб-сервера
Знакомство с Docker: установка движка и CLI
Установка Docker Compose для управления мульти-контейнерными приложениями
Основы изоляции: почему каждый проект должен быть в своем контейнере
Подготовка файловой структуры сервера для удобного хранения проектов
Развертывание Nginx как обратного прокси-сервера через Docker
Настройка конфигурации Nginx для статических сайтов
Установка PHP-FPM в отдельном контейнере
Связка Nginx и PHP-FPM через внутреннюю Docker-сеть
Оптимизация настроек PHP-FPM (pm.max_children, memory_limit) под нагрузку
Установка MariaDB/MySQL в изолированном контейнере
Безопасное хранение паролей от БД через переменные окружения (.env)
Подключение к базе данных из внешнего клиента (DBeaver/Navicat) через туннель
Установка Redis для кэширования запросов и сессий
Интеграция Redis с PHP-приложением для ускорения работы
Автоматическая выдача SSL-сертификатов через Certbot (Let's Encrypt)
Настройка автопродления SSL-сертификатов по крону
Принудительный редирект с HTTP на HTTPS в Nginx
Включение gzip и brotli сжатия для ускорения загрузки страниц
Настройка кэширования статики (browser caching) в заголовках Nginx
Защита от простых DDoS и ботов: модуль limit_req в Nginx
Настройка резервного копирования баз данных (mysqldump) по расписанию
Настройка резервного копирования файлов проектов (tar)
Отправка бэкапов на удаленное хранилище (S3-compatible storage или другой сервер)
Ротация и очистка старых логов, чтобы не забить диск
Мониторинг нагрузки: установка и настройка htop и iotop
Просмотр логов в реальном времени: tail, grep и journalctl
Установка простого мониторинга доступности (Uptime Kuma или скрипт в Telegram)
Изоляция арбитражных инструментов: запуск ботов в отдельных контейнерах
Установка SOCKS5/HTTP прокси (3proxy) внутри Docker для мультиаккаунтинга
Настройка аутентификации и ограничения доступа к прокси по IP
Проверка анонимности и работы прокси-сервера
Оптимизация ядра Linux (sysctl.conf) для высоких нагрузок и сетевых соединений
Настройка swap-файла: когда он нужен, а когда вредит
Чек-лист финальной проверки безопасности перед запуском проекта
План действий при взломе или падении сервера: восстановление из бэкапа
АПТЕЧКА ДЛЯ ЖИВОТНЫХ
Автомобили Германии — FORD, MERSEDES, VW, IVECO
Чат рулетка 2026: чаты, где каждый момент — шанс
Чат рулетка онлайн
Чат с Аней: психологический разговор
Чатрулетка: новый способ общения
Чай и кофе: сила вкуса
Детские игрушки из безопасных материалов
Эксплуатация шин: Рекомендации по использованию
Фототехника для пейзажей
Как Aptum хостинг помогает малым бизнесам в управлении CRM-системами
Как выбрать Vdsina вечный хостинг для своего проекта
Компоненты безопасности IP
Конкуренция на российском автомобильном рынке
Онлайн генератор паролей для Windows
Оптимизация обработки форм GEO проекта
Сервер для социальных сетей: Безопасность, Скорость, Изоляция
Смешные моменты
Сравнение Arsys хостинг сервисов для блогеров с WordPress на 2023 год
Весь экран под циферблат