Что такое rate limiting по IP?

Rate limiting по IP — это механизм, ограничивающий количество запросов, которые IP-адрес может отправить серверу за определённый период времени. Если вы превышаете лимит, сервер временно отклоняет ваши запросы, как правило, с ошибкой HTTP 429 («Too Many Requests»). Это один из самых распространённых инструментов защиты серверов от злоупотреблений, атак типа «отказ в обслуживании» и автоматизированного скрапинга.

Вы наверняка уже сталкивались с этим, не осознавая. Когда сайт показывает «Слишком много попыток, повторите через 5 минут» после нескольких неудачных входов, это rate limiting. Когда API возвращает ошибку после определённого числа вызовов в минуту, это rate limiting. Когда поисковик временно блокирует ваши запросы, потому что вы искали слишком быстро, это тоже rate limiting.

Почему это необходимо

У веб-сервера ограниченные ресурсы: процессор, память, пропускная способность, подключения к базе данных. Каждый запрос потребляет часть этих ресурсов. Без ограничений один пользователь (или автоматизированный скрипт) мог бы монополизировать сервер, отправляя тысячи запросов в секунду, делая сервис недоступным для всех остальных.

Rate limiting защищает от нескольких типов угроз:

Атаки DDoS и перебор паролей. Атака распределённого отказа в обслуживании (DDoS) заваливает сервер запросами, чтобы сделать его недоступным. Один rate limiting не способен заблокировать массовую DDoS-атаку (идущую с тысяч разных IP), но он ограничивает ущерб, который может нанести один IP. Для атак перебором паролей (brute force) rate limiting — первая линия обороны: ограничение в 5–10 попыток входа в минуту делает атаку непрактичной.

Злоупотребление скрапингом и краулингом. Боты, извлекающие контент сайтов (цены, статьи, данные), отправляют сотни запросов в секунду. Rate limiting замедляет этих ботов до состояния, когда массовая экстракция становится экономически нецелесообразной (слишком медленно, слишком много серверного времени).

Злоупотребление API. Публичные API (погода, геолокация, ИИ, платежи) имеют стоимость за запрос для провайдера. Без rate limiting пользователь мог бы потреблять непропорциональные ресурсы — случайно (цикл в коде) или намеренно. Большинство API устанавливают лимиты по ключу API и по IP-адресу.

Справедливость между пользователями. Даже без злого умысла «жадный» пользователь (обновляющий страницу 50 раз в минуту или с плохо написанным скриптом) может ухудшить опыт для остальных. Rate limiting обеспечивает справедливое распределение ресурсов.

Как это работает технически

Принцип прост: сервер связывает каждый запрос с IP-адресом, считает количество запросов от этого IP в окне времени и отклоняет запросы, превышающие заданный порог. Но конкретная реализация зависит от алгоритма.

Фиксированное окно (Fixed Window). Время делится на фиксированные интервалы (например, минутные окна). Сервер считает запросы по IP в каждом окне. Если вы достигли 100 запросов в текущем окне, следующие отклоняются до начала нового окна. Это самый простой алгоритм, но у него есть недостаток: если отправить 100 запросов в конце одного окна и 100 в начале следующего, вы отправили 200 запросов за несколько секунд — вдвое больше предусмотренного лимита.

Скользящее окно (Sliding Window). Вместо фиксированных окон сервер смотрит на последние N секунд в любой момент. Каждый запрос учитывается в скользящем периоде. Это сглаживает распределение и устраняет проблему фиксированного окна, но требует больше памяти и вычислений на стороне сервера.

Token Bucket (ведро с жетонами). У каждого IP есть «ведро» с фиксированным числом жетонов. Каждый запрос потребляет один жетон. Жетоны восстанавливаются с постоянной скоростью (например, 10 в секунду). Если ведро пусто, запрос отклоняется. Модель допускает короткие всплески (burst): вы можете отправить много запросов разом, если ведро полно, а затем ждать восстановления. Это самый используемый алгоритм в продакшене, потому что он гибкий и предсказуемый одновременно.

Leaky Bucket (дырявое ведро). Запросы поступают в очередь (ведро) и обрабатываются с постоянной скоростью (скорость утечки). Если ведро полно, новые запросы отклоняются. В отличие от Token Bucket, Leaky Bucket обеспечивает строго постоянную скорость обработки без всплесков. Полезно, когда нужен идеально равномерный поток обработки.

Где применяется rate limiting

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

На уровне веб-сервера. Nginx, Apache и большинство веб-серверов имеют встроенные модули rate limiting. Nginx, например, использует алгоритм Leaky Bucket с директивой limit_req. Вы задаёте число запросов в секунду на IP, и Nginx делает остальное. Эффективно для базовой защиты, но сервер всё равно должен принять и частично обработать каждый запрос перед отклонением.

На уровне reverse proxy или балансировщика нагрузки. Размещение rate limiting перед серверами приложений (на reverse proxy типа Nginx или HAProxy, или на балансировщике) позволяет блокировать запросы до того, как они достигнут приложения. Это эффективнее по ресурсам.

На уровне CDN или WAF. Сервисы вроде Cloudflare, AWS WAF или Akamai применяют rate limiting на границе сети (edge), до того как запрос вообще достигнет вашей инфраструктуры. Это самый эффективный слой против объёмных атак, потому что запрос блокируется как можно ближе к источнику.

На уровне приложения. Само приложение может реализовать rate limiting, часто с большей детализацией: по авторизованному пользователю, по эндпоинту, по типу операции. Например, API может разрешить 1 000 GET-запросов в минуту, но лишь 10 POST-запросов на эндпоинт создания аккаунта, потому что злоупотребления при создании аккаунтов — частый вектор атаки.

HTTP-заголовки, связанные с rate limiting

Когда сервер применяет rate limiting, он обычно сообщает информацию о лимитах через HTTP-заголовки в ответе. Универсального стандарта нет, но самые распространённые соглашения:

X-RateLimit-Limit: максимальное число запросов, разрешённых в текущем окне. X-RateLimit-Remaining: количество оставшихся запросов до достижения лимита. X-RateLimit-Reset: момент (в Unix timestamp или оставшихся секундах), когда окно сбрасывается и счётчик обнуляется. Retry-After: стандартный HTTP-заголовок, указывающий, сколько ждать перед повтором, возвращается вместе с ответом 429.

Черновик IETF (RFC 6585 для кода 429 и более новые предложения) пытается стандартизировать эти заголовки, но на практике каждый API использует свои соглашения. Если вы разрабатываете приложение, потребляющее API, всегда читайте документацию API, чтобы знать, как оно сообщает свои лимиты.

Почему одного IP не всегда достаточно

Rate limiting по IP имеет фундаментальную проблему: IP-адрес не всегда соответствует одному пользователю.

CGNAT. Многие мобильные операторы и некоторые провайдеры используют CGNAT (Carrier-Grade NAT), при котором сотни или тысячи пользователей делят один публичный IPv4-адрес. Если вы ограничиваете IP 100 запросами в минуту, вы фактически ограничиваете всех пользователей за этим CGNAT общим лимитом в 100 запросов. Один обычный пользователь может исчерпать квоту для всех остальных.

Корпоративные и университетские сети. Тысячи сотрудников или студентов могут выходить в интернет через один публичный IP (или небольшое число адресов). Rate limiting по IP наказывает их коллективно.

VPN и прокси. Пользователи VPN часто делят IP-адрес с сотнями других людей. Строгий rate limiting по IP может заблокировать легитимных пользователей просто потому, что они используют тот же VPN-сервер, что и бот.

Динамические IP-адреса. С другой стороны, атакующий может легко менять IP-адрес (используя пул прокси, ботнет или просто включая авиарежим на телефоне) и обходить rate limiting по IP. Если лимит установлен по IP, а у атакующего доступ к 10 000 адресам, эффективный лимит умножается на 10 000.

Поэтому современные системы rate limiting обычно комбинируют IP с другими идентификаторами: ключ API, токен аутентификации, отпечаток браузера, сессионная cookie. IP остаётся полезным критерием, но редко достаточным в одиночку.

Что происходит, когда вас ограничивают

Самый частый ответ — HTTP-код 429 (Too Many Requests). Сервер также может вернуть 503 (Service Unavailable), если ограничение вызвано общей перегрузкой, а не индивидуальным превышением.

Некоторые сервисы не блокируют доступ полностью, а деградируют сервис: замедляют ответы (throttling), снижают качество результатов или добавляют CAPTCHA для проверки, что вы человек.

Другие сервисы блокируют молча, не возвращая явной ошибки. Продолжают отвечать кодом 200 (OK), но возвращают пустые данные или ухудшенные результаты. Такой «тихий rate limiting» (shadow banning) распространён в соцсетях и некоторых поисковиках и спроектирован так, чтобы ботам было сложно его обнаружить.

Как разработчики справляются с rate limiting

Если вы разрабатываете приложение, потребляющее API, нужно правильно обрабатывать rate limiting. Стандартный метод — «exponential backoff»: получив ответ 429, вы ждёте определённое время перед повтором и удваиваете это время при каждом последующем сбое. Например: первая попытка через 1 секунду, вторая через 2, третья через 4 и т.д.

К лучшим практикам относятся:

Чтение заголовков Retry-After и X-RateLimit-Reset, чтобы точно знать, когда повторять, а не гадать. Реализация кеша, чтобы не повторять одни и те же запросы. Группировка запросов (batching), когда API это позволяет. Распределение запросов во времени вместо отправки пачкой. Предусмотреть circuit breaker, который прекращает вызовы API на время, если ошибки 429 накапливаются, чтобы не усугублять ситуацию.

Rate limiting и конфиденциальность

Rate limiting по IP подразумевает, что сервер идентифицирует и отслеживает запросы по IP-адресу. Это форма обработки персональных данных (IP-адрес считается персональными данными во многих юрисдикциях, особенно по GDPR в Европе и ФЗ-152 в России). Компании, реализующие rate limiting, должны в теории упоминать эту обработку в политике конфиденциальности.

С точки зрения пользователя rate limiting по IP также означает, что ваша активность подсчитывается. Если вы используете VPN или прокси ради конфиденциальности, rate limiting может парадоксально вас наказывать: вы делите IP с другими пользователями, и общая квота исчерпывается быстрее.

Обход rate limiting

Смена IP-адреса (через VPN, ротационный прокси или авиарежим на телефоне) позволяет обойти rate limiting, основанный исключительно на IP. Коммерческие сервисы скрапинга используют пулы из тысяч резидентных IP-адресов для распределения запросов и удержания ниже порогов по IP.

Но современные системы защиты не ограничиваются IP. Они комбинируют анализ отпечатка браузера, поведение при навигации (ритм кликов, движения мыши, время на страницах), CAPTCHA и анализ паттернов запросов для различения людей и ботов, даже когда IP меняется при каждом запросе.

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

Примеры типичных лимитов

Сервис / контекстТипичный лимит
Страница входа5–10 попыток в минуту на IP
Публичный REST API60–1 000 запросов в минуту на ключ API
API поисковика100 запросов в день (бесплатный план)
Контактная форма2–5 отправок в час на IP
Скачивание файлов10–50 скачиваний в час на IP
CDN / WAF (Cloudflare)Настраиваемо, часто 100+ запросов за 10 секунд

Эти лимиты сильно варьируются в зависимости от сервиса, тарифного плана и контекста. Платный API обычно предлагает значительно более высокие лимиты, чем бесплатный план. Чувствительный эндпоинт (вход, оплата, создание аккаунта) имеет гораздо более низкие лимиты, чем эндпоинт чтения данных.

Rate limiting по IP — базовая защита для любого сервера в интернете. Он предотвращает злоупотребления, защищает ресурсы и обеспечивает справедливый доступ. Но IP-адрес сам по себе — всё менее надёжный идентификатор при CGNAT, VPN и прокси. Современные системы комбинируют IP с другими сигналами для различения легитимного и вредоносного трафика, и именно эта комбинация определяет разницу между эффективной защитой и простым фильтром, который легко обойти.