Главная / База знаний / Rate limiting в nginx: защита от избыточных запросов
инструкция · 27 октября 2026

Rate limiting в nginx: защита от избыточных запросов

Как ограничить частоту запросов с одного IP через limit_req_zone и limit_req, что такое burst и nodelay, зачем нужен limit_conn, и почему rate limiting — не то же самое, что защита от DDoS.

Зачем ограничивать частоту запросов на уровне веб-сервера

Не каждый источник избыточной нагрузки на сервер — злонамеренная атака. Куда чаще встречаются куда более прозаичные ситуации: поисковый или парсинг-бот, слишком агрессивно обходящий сайт без соблюдения разумных пауз между запросами; скрипт автоматизации, по ошибке отправляющий запросы в цикле без задержки из-за бага в коде; либо прямая попытка перебора паролей на форме логина или подбора действительных промокодов через API. Во всех этих случаях характерный признак один и тот же — аномально высокая частота запросов с одного и того же источника за короткий промежуток времени.

Rate limiting — это механизм, ограничивающий количество запросов, которые сервер согласен принять от одного клиента за единицу времени, отклоняя или задерживая всё, что превышает установленный порог. В nginx эта функциональность встроена в стандартную сборку через модуль ngx_http_limit_req_module для ограничения частоты запросов и ngx_http_limit_conn_module для ограничения числа одновременных соединений — оба доступны без дополнительной установки на подавляющем большинстве сборок nginx.

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

Эта статья разбирает практическую настройку rate limiting в nginx: директивы limit_req_zone и limit_req, смысл параметров burst и nodelay, ограничение числа одновременных соединений через limit_conn, применение разных лимитов к разным частям сайта и типичные ошибки при настройке.

limit_req_zone: определение зоны лимита

Настройка rate limiting в nginx начинается с определения зоны — области разделяемой памяти, в которой nginx хранит состояние счётчиков запросов для каждого уникального ключа (обычно IP-адреса клиента). Зона объявляется директивой limit_req_zone в контексте http, а реальное применение этой зоны к конкретным запросам происходит уже в контексте server или location через директиву limit_req.

Определение зоны лимита на 10 запросов в секунду с одного IP-адреса
http {
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
}

Первый параметр — ключ, по которому ведётся подсчёт запросов, чаще всего это $binary_remote_addr — бинарное представление IP-адреса клиента, занимающее меньше памяти, чем текстовое представление того же адреса в $remote_addr, что важно при ограниченном размере самой зоны. Параметр zone задаёт имя зоны и её размер в памяти — 10 мегабайт, указанные в примере, достаточны примерно для 160 тысяч уникальных IP-адресов, поскольку на каждый адрес расходуется около 64 байт состояния.

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

Важная деталь работы зоны: если память зоны заполняется полностью (при очень большом числе уникальных IP-адресов, обращающихся к серверу за короткий период), nginx начинает удалять из зоны записи о наименее недавно активных адресах, освобождая место для новых, — это защищает от переполнения памяти ценой потери точности учёта для давно неактивных клиентов, что на практике почти никогда не создаёт проблем, поскольку такие клиенты и так не создают лишней нагрузки прямо сейчас.

limit_req: применение лимита, burst и nodelay

После определения зоны она применяется к конкретным запросам директивой limit_req внутри нужного контекста — обычно внутри блока location, что позволяет задавать разные лимиты для разных частей сайта в рамках одной и той же конфигурации.

Применение лимита с очередью на 20 запросов и немедленной обработкой в её пределах
location / {
    limit_req zone=general burst=20 nodelay;
}

Без дополнительных параметров лимит применяется крайне жёстко: превышение заданной скорости rate даже на долю секунды приводит к немедленному отклонению запроса с ошибкой. На практике реальный трафик браузера редко идёт равномерным потоком — при открытии страницы браузер обычно параллельно запрашивает сразу несколько ресурсов (CSS, JavaScript, изображения), создавая кратковременный всплеск запросов, который без дополнительной настройки будет ошибочно принят за избыточную нагрузку.

Параметр burst решает эту проблему, задавая размер очереди для запросов, превышающих базовую скорость rate, — вместо немедленного отклонения такие запросы ставятся в очередь и обрабатываются nginx с задержкой, достаточной для соблюдения средней скорости rate в целом. Без флага nodelay эта задержка равномерно растягивает обработку запросов из очереди во времени, что может ощутимо замедлить отклик для легитимного пользователя, чей короткий всплеск запросов попал именно в эту очередь.

Флаг nodelay меняет это поведение: запросы в пределах размера burst обрабатываются сразу же, без искусственной задержки, а ограничению подвергается только сам факт превышения размера очереди — если очередь burst заполнена, а новый запрос всё ещё превышает базовую скорость, только такой запрос будет отклонён. На практике комбинация burst с nodelay — наиболее часто используемый вариант настройки, поскольку она сглаживает легитимные всплески без ощутимой задержки для обычных посетителей, сохраняя при этом защиту от устойчиво избыточной нагрузки.

limit_conn: ограничение числа одновременных соединений

limit_req ограничивает частоту новых запросов во времени, но не число уже открытых и обрабатываемых соединений с одного клиента одновременно — для этой задачи существует отдельный механизм limit_conn, полезный против клиентов, открывающих аномально много параллельных соединений разом, что может происходить как по ошибке в клиентском коде, так и намеренно при попытке исчерпать доступные worker-соединения сервера.

Ограничение до 5 одновременных соединений с одного IP для раздела скачивания файлов
http {
    limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
}

server {
    location /download/ {
        limit_conn conn_zone 5;
    }
}

Синтаксис limit_conn_zone аналогичен limit_req_zone — та же логика ключа (обычно IP-адреса) и размера зоны в памяти, но без параметра rate, поскольку здесь считается не скорость поступления запросов, а текущее число одновременно открытых соединений. Применение через limit_conn в конкретном location задаёт максимально допустимое число одновременных соединений для этого ключа именно в рамках данного location.

Типичный практический случай применения limit_conn — раздел скачивания больших файлов: без ограничения один клиент теоретически может открыть десятки параллельных соединений для одновременной загрузки нескольких файлов или частей одного файла через докачку, полностью выбирая доступную пропускную способность канала и worker-соединения сервера в ущерб остальным посетителям. Разумный лимит в несколько одновременных соединений с одного адреса решает эту проблему, не мешая обычному сценарию скачивания одного-двух файлов подряд.

limit_req и limit_conn прекрасно комбинируются и решают взаимодополняющие задачи: первый защищает от слишком частых новых запросов, второй — от слишком большого числа одновременно висящих соединений, и для по-настоящему защищённой конфигурации критичных разделов сайта (форма логина, API, скачивание файлов) обычно имеет смысл применять оба механизма одновременно.

Разные лимиты для разных частей сайта

Одно из главных практических преимуществ rate limiting в nginx — гибкость применения: базовые зоны определяются один раз в контексте http, а конкретные лимиты для каждого location задаются независимо, что позволяет держать общий трафик по сайту достаточно свободным, одновременно жёстко ограничивая наиболее чувствительные к злоупотреблению эндпоинты.

Три независимые зоны лимита для общего трафика, страницы логина и API
http {
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=login:10m rate=1r/m;
    limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;
}

server {
    location / {
        limit_req zone=general burst=20 nodelay;
    }

    location = /login {
        limit_req zone=login burst=3;
    }

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

Для страницы логина резкое сокращение допустимой частоты запросов до одной-двух попыток в минуту напрямую защищает от перебора паролей: легитимный пользователь, вводящий пароль вручную, физически не способен превысить такой лимит даже с учётом опечаток, тогда как автоматизированный скрипт перебора, пытающийся проверить сотни паролей подряд, немедленно упирается в лимит и вынужден либо резко замедлиться, либо получать постоянные отказы.

Обратите внимание на отсутствие флага nodelay в правиле для /login в примере выше — здесь как раз оправдана искусственная задержка обработки запросов из очереди burst: небольшая пауза перед ответом на очередную попытку входа не создаёт заметного неудобства для реального пользователя, но дополнительно замедляет автоматизированный перебор паролей, даже если он укладывается в размер очереди burst по количеству запросов.

Для API-эндпоинтов лимит стоит подбирать исходя из реального профиля использования конкретного клиента приложения — мобильное приложение, синхронизирующее данные, или фронтенд, опрашивающий эндпоинт статуса, могут создавать легитимную частоту запросов заметно выше, чем обычный просмотр страниц сайта человеком, и слишком строгий лимит здесь будет мешать штатной работе приложения, а не только защищать от злоупотребления.

Отличие rate limiting от защиты от DDoS

Rate limiting в nginx работает на уровне одного сервера и различает клиентов по идентификатору — как правило, по IP-адресу. Это эффективно против нагрузки, сконцентрированной на ограниченном числе источников: одном агрессивном боте, одном скрипте с багом, ограниченном наборе адресов, задействованных при переборе пароля вручную или простым скриптом.

Распределённая атака типа DDoS (Distributed Denial of Service) устроена принципиально иначе: запросы приходят одновременно с тысяч или миллионов разных IP-адресов, зачастую через ботнет из скомпрометированных устройств, и лимит в 10 запросов в секунду с одного IP просто никогда не будет достигнут отдельным участником такой атаки, при том что суммарная нагрузка от всех участников разом легко превышает возможности сервера или даже пропускную способность его сетевого канала.

Более того, для по-настоящему объёмных атак на сетевом уровне (переполнение канала связи бессмысленным трафиком) rate limiting на уровне nginx вообще не успевает вступить в игру — nginx работает на прикладном уровне и не может ничего противопоставить атаке, которая исчерпывает пропускную способность сетевого канала ещё до того, как запросы доходят до самого процесса nginx для обработки.

Практический вывод: rate limiting в nginx — полезный и обязательный, но лишь один из уровней защиты, эффективный против конкретного класса проблем (агрессивные боты, перебор паролей, ошибки в клиентском коде, умеренные точечные злоупотребления), но не заменяющий собой специализированную защиту от DDoS на уровне сети или CDN, которая рассчитана на принципиально иной масштаб и характер распределённой нагрузки.

Настройка кода ответа и информативность для клиента

По умолчанию nginx отвечает кодом 503 Service Unavailable на запрос, превысивший установленный лимит, — этот код формально верен (сервер временно не готов обработать запрос), но не самый точный с точки зрения семантики HTTP, поскольку стандарт предусматривает отдельный код 429 Too Many Requests именно для ситуации превышения лимита частоты запросов.

Явная настройка кода ответа 429 вместо кода по умолчанию при превышении лимита
limit_req_status 429;
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;

location /api/ {
    limit_req zone=api burst=10 nodelay;
    limit_req_status 429;
}

Использование корректного кода 429 особенно важно для API, потребляемого другими программами, а не браузером напрямую, — многие HTTP-клиенты и SDK умеют автоматически распознавать именно этот код как сигнал временно снизить частоту запросов и повторить попытку позже (иногда с учётом заголовка Retry-After), тогда как код 503 чаще интерпретируется клиентским кодом как признак недоступности сервиса в целом, что может привести к менее подходящей стратегии повторных попыток на стороне клиента.

Директива limit_req_status также позволяет настроить отдачу собственной страницы ошибки для случая превышения лимита через error_page, что удобно для показа пользователю понятного сообщения ("слишком много запросов, попробуйте через минуту") вместо стандартной технической страницы ошибки nginx, особенно на страницах, доступных обычным посетителям сайта, а не только автоматизированным клиентам API.

Типичные ошибки настройки rate limiting

Слишком строгий общий лимит для всего сайта без учёта того, что современная страница генерирует множество параллельных запросов на статические ресурсы при каждом открытии, — легитимные посетители начинают получать ошибки 503 на часть ресурсов страницы просто из-за особенностей работы браузера, а не из-за реального злоупотребления.

Использование burst без nodelay там, где важна скорость отклика, — искусственная задержка обработки запросов из очереди может сделать интерфейс сайта заметно медленнее для обычных пользователей, чьи короткие легитимные всплески запросов регулярно попадают в эту очередь.

Применение одного и того же лимита ко всем частям сайта без выделения более строгих правил для чувствительных эндпоинтов вроде формы логина или API — упущенная возможность точечно защитить именно те места, где риск злоупотребления заметно выше среднего.

Расчёт на rate limiting в nginx как на полноценную защиту от DDoS — при реальной распределённой атаке с большого числа источников этот механизм не создаёт заметного препятствия, поскольку рассчитан на ограничение нагрузки с отдельных клиентов, а не суммарной нагрузки от множества разных источников одновременно.

Использование $remote_addr вместо $binary_remote_addr в качестве ключа зоны без понимания разницы — оба варианта работают корректно, но бинарное представление занимает меньше памяти в зоне лимита, что даёт больший практический запас по числу отслеживаемых уникальных адресов на тот же объём выделенной памяти.

Чек-лист настройки rate limiting в nginx

Шаг 1. Определите базовую зону лимита для всего сайта с достаточно свободным порогом (например, 10 запросов в секунду) и разумным burst для сглаживания параллельных запросов браузера при загрузке страницы.

Шаг 2. Выделите отдельную, значительно более строгую зону для страницы логина или других форм, чувствительных к перебору, с лимитом в единицы запросов в минуту.

Шаг 3. Для API определите отдельный лимит исходя из реального профиля использования конкретными клиентами приложения, а не по аналогии с обычным веб-трафиком.

Шаг 4. Добавьте limit_conn для разделов с раздачей больших файлов, чтобы ограничить число параллельных соединений с одного адреса.

Шаг 5. Настройте limit_req_status на 429 для API-эндпоинтов, чтобы клиентский код мог корректно распознать превышение лимита и адекватно отреагировать.

Шаг 6. Протестируйте настроенные лимиты реальным сценарием использования сайта (открытие страницы в браузере, типичный сценарий работы с API) прежде, чем считать конфигурацию готовой к продакшну.

Итог: точечный инструмент против конкретного класса проблем

Rate limiting в nginx — недорогой по усилиям настройки, но эффективный инструмент против вполне конкретного и распространённого класса проблем: агрессивных ботов, перебора паролей, скриптов с багами и умеренных точечных злоупотреблений отдельными источниками трафика. Настройка через limit_req_zone, limit_req и limit_conn занимает считаные строки конфигурации, но требует осмысленного подбора значений под реальный профиль трафика конкретного сайта, а не слепого копирования чужих цифр.

Важно ясно понимать границы применимости этого инструмента: он не заменяет собой защиту от распределённых атак, рассчитанных на принципиально иной масштаб и характер нагрузки, и в связке с rate limiting на уровне nginx стоит рассматривать дополнительные меры — CDN с защитой от ботов, специализированные сервисы защиты от DDoS, fail2ban для более агрессивной реакции на повторяющиеся нарушения с одного адреса.

Наибольшую практическую пользу rate limiting приносит именно там, где применяется точечно и осмысленно: жёсткий лимит на форме логина, разумный лимит для API под конкретный профиль его использования и достаточно свободный, но не бесконечный лимит для общего трафика сайта — такая дифференцированная настройка защищает наиболее уязвимые места, не создавая лишних неудобств для обычных посетителей.

почему мы

Почему стоит выбрать нас

Быстрый запуск

Подберём конфигурацию и развернём проект в день обращения.

Надёжность

NVMe-диски, защита от DDoS и резервные копии по расписанию.

Поддержка 24/7

Дежурные инженеры на связи в любое время суток.

Настройка под ключ

Установим CMS, настроим веб-сервер, SSL и почту за вас.

Перенос без простоя

Аккуратно перенесём сайт и базу данных на новый сервер.

Прозрачные цены

Актуальные тарифы и честный подбор без навязывания.

частые вопросы

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

Чем rate limiting в nginx отличается от защиты от DDoS?

Rate limiting в nginx ограничивает количество запросов, которые обрабатывает конкретный процесс nginx с одного идентификатора клиента (обычно IP-адреса) — это эффективно против переборов паролей, парсинга сайта ботами и случайных всплесков от одного источника, но бессильно против распределённой атаки с тысяч разных IP-адресов одновременно, где лимит на каждый отдельный адрес не достигается, а суммарная нагрузка на сервер или канал связи всё равно оказывается разрушительной.

Что означает burst в директиве limit_req?

Burst задаёт размер очереди запросов, превышающих базовую скорость лимита, которые nginx поставит в очередь и обработает с задержкой вместо немедленного отклонения — это сглаживает кратковременные всплески легитимного трафика (например, когда браузер параллельно запрашивает несколько ресурсов страницы почти одновременно), которые иначе были бы ошибочно приняты за избыточную нагрузку.

Зачем нужен флаг nodelay вместе с burst?

Без nodelay запросы из очереди burst обрабатываются nginx с искусственной задержкой, чтобы выдержать заданную базовую скорость лимита равномерно во времени, — это может ощутимо замедлить ответ для легитимного пользователя, чей короткий всплеск запросов попал в очередь. С nodelay запросы в пределах burst обрабатываются сразу же, без задержки, а ограничению подвергается только сам факт превышения размера очереди.

В чём разница между limit_req и limit_conn?

limit_req ограничивает частоту новых запросов в единицу времени (например, не более 10 запросов в секунду с одного IP), тогда как limit_conn ограничивает количество одновременно открытых соединений с одного IP-адреса, вне зависимости от того, как часто по ним идут запросы, — они решают разные, хотя и похожие по духу задачи и часто применяются вместе.

Как защитить именно страницу логина от перебора паролей через rate limiting?

Задать отдельную зону limit_req_zone для конкретного location с формой логина и применить к ней куда более жёсткий лимит (например, несколько попыток в минуту), чем к остальному сайту, — попытка перебора пароля почти всегда выглядит как аномально частые запросы к одному и тому же эндпоинту с одного IP, что и позволяет отличить её от обычного трафика посетителей.

Что произойдёт с запросом, превысившим лимит и не поместившимся в burst?

По умолчанию nginx вернёт клиенту ошибку 503 Service Unavailable — код ответа для такого случая можно изменить директивой limit_req_status на более подходящий (например, 429 Too Many Requests, специально предназначенный HTTP-стандартом именно для этой ситуации, но не входящий в число кодов nginx по умолчанию для этого случая).

Можно ли применять rate limiting только к определённым location, а не ко всему сайту сразу?

Да, и это стандартная практика: зона лимита определяется один раз в контексте http, а директива limit_req, реально применяющая эту зону, указывается внутри конкретных location — можно задать разные, даже разнонаправленные лимиты для статики, обычных страниц, API и особенно чувствительных эндпоинтов вроде формы логина в рамках одной и той же конфигурации сервера.

Нужен ли rate limiting, если перед сайтом уже стоит CDN с защитой от ботов?

Rate limiting на уровне nginx остаётся полезным дополнительным уровнем защиты даже при наличии CDN — он защищает от избыточной нагрузки, приходящей напрямую на сервер в обход CDN (если IP сервера известен или CDN настроен неполно), а также от легитимных, но чрезмерно активных клиентов и внутренних скриптов, которые CDN не считает подозрительными, но которые всё равно способны перегрузить конкретный эндпоинт.

Как оплачивать услуги?

Оплата помесячная, для облачных серверов доступна почасовая тарификация. Принимаются карты, банковские переводы и электронные кошельки.

Есть ли круглосуточная поддержка?

Да, дежурные инженеры на связи 24/7.

Выдаёте ли закрывающие документы?

Да, предоставим необходимые документы для оплаты.

Как оставить заявку?

Заполните форму на странице или нажмите «Заказать» — мы свяжемся и поможем с подбором.

заявка

Оставьте заявку

Ответим и поможем с подбором и настройкой.