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

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

Настройка модуля limit_req для контроля нагрузки и безопасности веб-сервера

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

Введение

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

Требования

  • Установленный Nginx версии 1.10 и выше (модуль limit_req доступен по умолчанию).

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

  • Права на перезагрузку конфигурации (nginx -s reload или systemctl reload nginx).

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

Шаг 1: Определите зоны ограничения

Прежде чем писать конфигурацию, решите, что именно вы хотите ограничивать:

  • По IP-адресу клиента — универсальный вариант для защиты от флуда.

  • По сессии/пользователю — если у вас есть аутентификация (например, по cookie).

  • По конкретному URL — для чувствительных эндпоинтов (логин, API).

Например, для защиты формы входа достаточно ограничить частоту POST-запросов к /login по IP.

Шаг 2: Создайте зону limit_req_zone

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

Пример:

http {
    limit_req_zone $binary_remote_addr zone=login_zone:10m rate=5r/s;
    ...
}
  • $binary_remote_addr — ключ, по которому группируются запросы (IP-адрес в бинарном виде, экономит память).

  • zone=login_zone:10m — имя зоны и размер памяти (10 МБ хватит примерно на 160 000 уникальных IP).

  • rate=5r/s — разрешённая скорость: 5 запросов в секунду. Можно указывать в минутах: 30r/m.

Шаг 3: Примените ограничение в location

В блоке location используйте директиву limit_req, указав имя зоны и параметры.

location = /login {
    limit_req zone=login_zone burst=10 nodelay;
    proxy_pass http://backend;
}
  • burst=10 — разрешает всплеск до 10 запросов сверх установленной скорости (они ставятся в очередь).

  • nodelay — не задерживать обработку запросов из очереди, а сразу возвращать 503 при превышении. Без nodelay Nginx будет буферизовать запросы, что может увеличить задержку.

Шаг 4: Настройте код ответа и логирование

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

limit_req_status 429;

Для логирования отклонённых запросов добавьте в http или server:

limit_req_log_level warn;

Уровень warn будет писать в error_log, не засоряя его при штатной работе.

Шаг 5: Ограничьте соединения (limit_conn)

Дополнительно можно ограничить число одновременных соединений с одного IP. Это полезно против медленных атак (slowloris).

http {
    limit_conn_zone $binary_remote_addr zone=addr_zone:10m;
    ...
}

server {
    limit_conn addr_zone 10;
    limit_conn_status 429;
}

Здесь одному IP разрешено не более 10 одновременных соединений.

Шаг 6: Настройте белый список

Чтобы не блокировать мониторинг, поисковых ботов или офисные IP, используйте geo и переменную для исключения.

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

Если $limit_key пуст, ограничение не применяется.

Шаг 7: Разные лимиты для разных location

Можно создавать несколько зон и применять их выборочно.

http {
    limit_req_zone $binary_remote_addr zone=api_zone:10m rate=20r/s;
    limit_req_zone $binary_remote_addr zone=static_zone:10m rate=50r/s;
}

location /api/ {
    limit_req zone=api_zone burst=30 nodelay;
    proxy_pass http://api_backend;
}

location /static/ {
    limit_req zone=static_zone burst=100 nodelay;
    root /var/www/static;
}

Шаг 8: Тестирование и отладка

После внесения изменений проверьте конфигурацию:

nginx -t

Затем перезагрузите Nginx:

systemctl reload nginx

Для проверки работы лимита используйте утилиту ab (Apache Benchmark) или curl в цикле:

for i in {1..20}; do curl -s -o /dev/null -w "%{http_code}\n" http://ваш-сайт/login; done

Часть запросов должна вернуть 429 (или 503).

Шаг 9: Мониторинг и анализ логов

Следите за попаданием в лимиты через error_log:

tail -f /var/log/nginx/error.log | grep limiting

Если лимиты срабатывают слишком часто для легитимных пользователей, увеличьте burst или rate. Помните, что rate задаётся в запросах в секунду (r/s) или в минуту (r/m).

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

1. Слишком маленький burst — приводит к блокировке нормальных пользователей при пиковой нагрузке. Начните с burst, равного 2–5-кратному rate. 2. Использование `$remote_addr` вместо `$binary_remote_addr` — первый хранится как строка и занимает больше памяти. 3. Забыли `nodelay` — запросы буферизуются, увеличивая время ответа. Используйте nodelay для API и форм входа. 4. Ограничение применяется ко всем запросам, включая статику — это может замедлить загрузку сайта. Разделяйте зоны для статики и динамики. 5. Отсутствие белого списка — мониторинг или поисковые роботы могут быть заблокированы, что негативно скажется на SEO. 6. Неверный размер зоны — при малом размере (например, 1m) счётчики быстро вытесняются, и лимиты работают некорректно. Выделяйте минимум 10m для больших сайтов. 7. Игнорирование кода 429 — некоторые клиенты не понимают 503, лучше использовать 429 для API.

FAQ

Вопрос: Можно ли ограничить скорость по пользователю, а не по IP? Да, если у вас есть аутентификация, используйте ключ $remote_user или $cookie_session. Например: limit_req_zone $cookie_session zone=user_zone:10m rate=10r/s;.

Вопрос: Что лучше: `limit_req` или `limit_conn`? Они дополняют друг друга: limit_req ограничивает частоту запросов, limit_conn — число одновременных соединений. Для полной защиты используйте оба.

Вопрос: Как временно отключить лимиты? Закомментируйте директиву limit_req в нужном location или установите очень высокий rate.

Вопрос: Влияет ли rate limiting на SEO? Если правильно настроить белый список для поисковых ботов (Googlebot, YandexBot), влияние будет минимальным. Иначе боты могут получить 429 и снизить частоту обхода.

Вопрос: Можно ли использовать несколько зон в одном location? Да, можно указать несколько директив limit_req с разными зонами, но лимиты будут применяться последовательно.

Итог

Настройка rate limiting в Nginx — эффективный способ защитить сервер от перегрузок и атак. Используйте limit_req_zone и limit_req для контроля частоты, limit_conn для ограничения соединений, не забывайте про белые списки и тестирование. Грамотно подобранные параметры (rate, burst, nodelay) обеспечат баланс между безопасностью и удобством для пользователей.

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

Комментарии

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

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