Rate limiting в nginx: ограничиваем частоту запросов
Один агрессивный бот или скрипт способен уложить сайт, забив все воркеры запросами. Директива limit_req в nginx ставит лимит на частоту обращений с одного адреса — разбираем зоны, burst, nodelay и защиту чувствительных эндпоинтов.
Содержание
Зачем ограничивать частоту
['Rate limiting — это защита от того, что один клиент шлёт слишком много запросов слишком быстро: перебор паролей на форме логина, парсинг всего каталога, DoS с одного IP, ошибочный retry-цикл в приложении. nginx умеет это на уровне веб-сервера, ещё до того как запрос дойдёт до PHP или бэкенда.', '- Защита логина — брутфорс упирается в лимит запросов в секунду.
- Разгрузка бэкенда — всплеск трафика режется на входе, а не роняет приложение.
- Честность — один клиент не забирает все ресурсы у остальных.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS для отказоустойчивого сайтаОбъявляем зону limit_req
['Сначала в контекстеhttp объявляется зона — область общей памяти, где nginx хранит счётчики по ключу (обычно IP клиента). Ключ задаётся через limit_req_zone.', 'http {\n limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;\n}', 'Разберём параметры: $binary_remote_addr — компактная форма IP (экономит память), zone=perip:10m — имя зоны и её размер (10 МБ хватает примерно на 160 тысяч адресов), rate=10r/s — базовая скорость: не более 10 запросов в секунду с одного IP.', 'Скорость можно задавать и в минутах: rate=30r/m — 30 запросов в минуту, удобно для редких, но чувствительных операций.']
Применяем лимит с burst
['Объявленную зону подключают директивойlimit_req в нужном location или server. Голый лимит без burst слишком жёсткий — реальные браузеры шлют запросы пачками. Параметр burst разрешает всплеск.', 'location / {\n limit_req zone=perip burst=20 nodelay;\n proxy_pass http://backend;\n}', 'burst=20 — очередь на 20 «лишних» запросов сверх скорости: короткий всплеск пропускается, устойчивое превышение режется. nodelay означает, что запросы из очереди обрабатываются сразу, а не растягиваются во времени — так лимит незаметен обычным пользователям, но душит флуд.', 'Без nodelay nginx будет искусственно задерживать запросы из burst-очереди, выравнивая их под rate — это плавнее для бэкенда, но добавляет задержку. Для API чаще берут nodelay, для тяжёлых бэкендов — версию с задержкой.']
Жёсткий лимит на логин
['Форму входа и API аутентификации стоит защищать отдельной, более строгой зоной — здесь важнее остановить брутфорс, чем удобство. Заведём вторую зону и применим её точечно.', 'http {\n limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;\n}\nserver {\n location = /login {\n limit_req zone=login burst=3 nodelay;\n limit_req_status 429;\n proxy_pass http://backend;\n }\n}', 'rate=5r/m пропускает лишь 5 попыток входа в минуту с адреса — этого хватает человеку и мало ботнету. Директива limit_req_status 429 заставляет отдавать корректный код «Too Many Requests» вместо дефолтного 503.']
Проверка и мониторинг
['После правки конфига всегда проверяй синтаксис перед перезагрузкой — сломанный конфиг положит весь nginx.', 'sudo nginx -t && sudo systemctl reload nginx', 'Сработавшие лимиты видны в error-логе: nginx пишет строки limiting requests. Отследить их можно так.', "grep 'limiting requests' /var/log/nginx/error.log | tail", 'Смоделировать нагрузку для проверки удобно утилитой ab или hey: пусти 100 запросов в 10 потоков и убедись, что часть вернулась с 429 или 503.', 'ab -n 100 -c 10 https://example.com/']
Частые ошибки
['- Лимит за прокси — если сайт за Cloudflare или балансировщиком,
$binary_remote_addrпокажет IP прокси, а не клиента. Используй$http_x_forwarded_forсreal_ip. - Слишком маленький burst — легитимные пользователи ловят 503 при обычной навигации. Тестируй значения под реальный трафик.
- Забыли nginx -t — опечатка в зоне валит весь веб-сервер.
- Один лимит на всё — статику, API и логин лучше разводить по разным зонам с разной строгостью.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK и США. Оплата картой РФ и по СБП.
Арендовать VPS для отказоустойчивого сайтаЧастые вопросы
Чем limit_req отличается от limit_conn?
limit_req ограничивает частоту запросов в секунду, а limit_conn — число одновременных соединений с одного IP. Их часто используют вместе.
Как понять правильное значение rate?
Оцени нормальный трафик по логам: посмотри, сколько запросов в секунду делает обычный пользователь, и поставь rate с запасом, а burst — на короткие всплески.
Лимит защищает от DDoS?
От флуда с небольшого числа адресов — да. Против распределённой атаки с тысяч IP нужен внешний уровень защиты, nginx лишь снижает нагрузку на бэкенд.