К содержимому
DDoS·Protect
База знаний

Ограничение запросов в nginx: limit_req и limit_conn на практике

Модуль ограничения запросов есть в любом nginx и закрывает простые атаки и переборы. Главное — настроить его по разделам, а не одним лимитом на весь сайт, и не забыть про исключения.

Базовая настройка

# http { ... }
# Зоны: ключ — адрес клиента, 10 МБ памяти хватает на ~160 тыс. адресов
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=search:10m rate=30r/m;
limit_conn_zone $binary_remote_addr zone=conn:10m;
limit_req_status 429;

# server { ... }
limit_conn conn 30;

location / {
    limit_req zone=general burst=40 nodelay;
    # ...
}

location = /login {
    limit_req zone=login burst=5;
    # ...
}

location /search {
    limit_req zone=search burst=10 nodelay;
    # ...
}

Как выбирать значения

  • rate — средняя скорость, которую вы готовы разрешить. Смотрите на реальный трафик в журналах и закладывайте запас в 2–3 раза.
  • burst — допустимый всплеск. Без него посетитель, открывший страницу с десятком ресурсов, получит отказ.
  • nodelay — обрабатывать всплеск сразу, а не растягивать во времени. Обычно нужен для страниц и не нужен для форм входа.

Исключения

geo $limit_exempt {
    default 0;
    10.0.0.0/8 1;        # внутренняя сеть
    192.0.2.10 1;        # офис (адрес условный)
}
map $limit_exempt $limit_key {
    0 $binary_remote_addr;
    1 "";               # пустой ключ — лимит не применяется
}
limit_req_zone $limit_key zone=general:10m rate=10r/s;
Пустой ключ исключает запрос из лимита

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

  • Один жёсткий лимит на весь сайт: статика упирается в него и страницы ломаются.
  • Лимит по $remote_addr за прокси или CDN: все посетители получают один адрес и упираются в общий лимит. Сначала настройте реальный IP.
  • Директивы вида «limit_req off» не существуют: чтобы отключить лимит для части путей, используйте пустой ключ через map.
  • Отсутствие limit_req_status 429: по умолчанию nginx отвечает 503, и это путают со сбоем.

Вопросы и ответы

Защитит ли limit_req от серьёзного DDoS?

Нет. Лимит отклоняет лишние запросы, но nginx всё равно принимает каждое соединение и тратит на него ресурсы. Это хорошая защита от переборов и небольших всплесков, а от крупной атаки нужна фильтрация перед сервером.

Как проверить лимиты, не рискуя посетителями?

Добавьте limit_req_dry_run on (nginx 1.17.1 и новее): запросы не отклоняются, но превышения пишутся в error.log. Посмотрите несколько дней журнала и только потом включайте блокировку.

Ранний доступ

Подключим ваш сайт одним из первых

Сервис готовится к запуску. Оставьте заявку: проверим, от чего нужно защищать ваш проект, и подключим его в числе первых на условиях раннего доступа.