sadrix logoSadriX
Минцифры готовит обязательную регистрацию IMEI смартфонов, купленных за границей
Гайды

Как ограничить частоту запросов в Nginx: полное руководство по rate limiting

Настраиваем защиту от брутфорса, парсинга и флуда с помощью модуля limit_req

09 444 просмотров4 мин
0
Поделиться:TelegramVK

Введение

Nginx — один из самых популярных веб-серверов и обратных прокси, и одной из его сильных сторон является встроенная защита от избыточной нагрузки. Ограничение частоты запросов (rate limiting) позволяет защитить сайт от брутфорс-атак, парсинга, случайных всплесков трафика и простейших DDoS. В этом руководстве мы разберём, как настроить ограничение скорости запросов с помощью модуля limit_req, объясним ключевые параметры и покажем типичные ошибки.

Материал рассчитан на администраторов, знакомых с основами конфигурации Nginx. Все примеры проверены на актуальных версиях Nginx (1.18+).

Требования

  • Установленный Nginx версии 1.18 или новее (модуль limit_req входит в стандартную сборку).

  • Доступ к файлам конфигурации (обычно /etc/nginx/nginx.conf или /etc/nginx/conf.d/).

  • Права root или sudo для перезагрузки Nginx.

  • Базовое понимание синтаксиса директив Nginx.

Шаг 1. Проверка поддержки модуля limit_req

Убедитесь, что ваш Nginx собран с модулем ngx_http_limit_req_module. Выполните:

nginx -V 2>&1 | grep -o with-http_limit_req_module

Если команда вывела with-http_limit_req_module, всё в порядке. В противном случае потребуется пересборка Nginx или установка пакета с полным набором модулей.

Шаг 2. Определение зоны ограничения (limit_req_zone)

Директива limit_req_zone задаёт зону разделяемой памяти, в которой хранятся счётчики запросов. Она размещается в контексте http.

Синтаксис:

limit_req_zone ключ zone=имя:размер rate=скорость;

Пример: ограничим 10 запросов в секунду на IP-адрес.

http {
    limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s;
}

Размер зоны 10 МБ позволяет хранить около 160 000 уникальных IP-адресов. Ключом может быть не только IP, но и, например, $server_name или комбинация переменных.

Шаг 3. Применение ограничения в location или server

Директива limit_req включает ограничение для конкретного контекста:

server {
    location /api/ {
        limit_req zone=perip;
        proxy_pass http://backend;
    }
}

Без дополнительных параметров Nginx будет отклонять запросы, превышающие заданную скорость, возвращая код 503.

Шаг 4. Настройка burst — обработка всплесков

Параметр burst позволяет накапливать запросы сверх лимита и обрабатывать их с задержкой. Это полезно для сайтов с неравномерным трафиком.

limit_req zone=perip burst=20;

Теперь при превышении скорости до 20 «лишних» запросов будут поставлены в очередь и обработаны по мере освобождения. Остальные получат 503.

Шаг 5. Использование nodelay для мгновенной обработки

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

limit_req zone=perip burst=20 nodelay;

Такой вариант подходит для API, где важна скорость ответа, но нужно сгладить пики.

Шаг 6. Настройка кода ответа и логирования

По умолчанию при превышении лимита возвращается 503 Service Unavailable. Можно изменить код на 429 Too Many Requests:

limit_req_status 429;

Также полезно логировать отклонённые запросы на отдельный уровень:

limit_req_log_level warn;

Это поможет анализировать атаки и подбирать оптимальные лимиты.

Шаг 7. Ограничение по нескольким зонам

Можно комбинировать несколько зон для разных условий. Например, отдельно ограничить запросы к API и к статике:

limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;
limit_req_zone $binary_remote_addr zone=static:10m rate=50r/s;

location /api/ {
    limit_req zone=api burst=10 nodelay;
}
location /static/ {
    limit_req zone=static burst=100 nodelay;
}

Шаг 8. Исключение доверенных IP из ограничений

Для внутренних сервисов или мониторинга можно отключить лимиты с помощью geo и map:

geo $limited {
    default 1;
    192.168.1.0/24 0;
}
map $limited $limit_key {
    0 "";
    1 $binary_remote_addr;
}
limit_req_zone $limit_key zone=perip:10m rate=10r/s;

Если ключ пустой, Nginx не применяет ограничение.

Шаг 9. Тестирование конфигурации

Перед применением проверьте синтаксис:

nginx -t

Затем перезагрузите конфигурацию:

systemctl reload nginx

Для проверки лимитов используйте утилиту ab, wrk или простой скрипт с curl в цикле. Убедитесь, что при превышении скорости возвращается ожидаемый код.

Шаг 10. Мониторинг и подбор оптимальных значений

Следите за логами ошибок и статистикой. Слишком жёсткие лимиты могут блокировать реальных пользователей, слишком мягкие — не защитят от атак. Начните с умеренных значений (например, 10 r/s для API) и корректируйте по мере необходимости.

Типичные ошибки

1. Слишком маленький размер зоны. При 1 МБ зона вмещает около 16 000 адресов; при большом трафике счётчики будут вытесняться, и лимиты перестанут работать корректно. 2. Использование `$remote_addr` вместо `$binary_remote_addr`. Последний экономит память (4 байта против 7–15). 3. Отсутствие `burst`. Без него даже небольшой всплеск приведёт к 503, что раздражает пользователей. 4. Неправильный выбор ключа. Если ключ включает $request_uri, зона будет быстро переполняться. 5. Забыли про `nodelay`. Очередь с задержкой может увеличить время ответа и негативно сказаться на SEO. 6. Игнорирование доверенных IP. Внутренние сервисы могут получить блокировку.

FAQ

Вопрос: В чём разница между `limit_req` и `limit_conn`? Ответ: limit_req ограничивает частоту запросов (запросов в секунду), а limit_conn — количество одновременных соединений с одного IP.

Вопрос: Можно ли ограничивать по URL? Да, в качестве ключа можно использовать $request_uri, но это требует больше памяти и подходит для небольших сайтов.

Вопрос: Какой код ответа лучше возвращать? Для API рекомендуется 429, для обычных страниц — 503.

Вопрос: Как обойти ограничение для поисковых ботов? Используйте map с проверкой $http_user_agent и устанавливайте пустой ключ для доверенных ботов.

Вопрос: Влияет ли rate limiting на SEO? Если правильно настроить burst и nodelay, влияние минимально. Резкие 503 могут навредить, поэтому лучше использовать 429.

Итог

Ограничение частоты запросов в Nginx — мощный и гибкий инструмент защиты. Настройка занимает несколько минут, но требует понимания параметров rate, burst и nodelay. Начните с базовой конфигурации, протестируйте под нагрузкой и постепенно настраивайте под свой трафик. Помните о мониторинге и не забывайте исключать доверенные адреса.

Читайте также

Комментарии

Комментарии доступны только зарегистрированным пользователям. Войти

  • Пока нет комментариев. Будьте первым.