Функция лимита запросов (rate limiting) позволяет гибко настраивать количество запросов, которые приходят на ваш сервер. Это полезно для защиты от автоматизированных атак — например от ботов, которые скупают популярный товар.
Каждый раз, когда система фиксирует запрос, соответствующий условиям, срабатывает счетчик. Если счетчик превышает заданный лимит, выполняется действие защиты.
Учитывайте, что загрузка одной страницы сайта обычно требует нескольких запросов. Для веб-страниц не рекомендуется устанавливать лимит ниже 300 запросов в минуту
Лимит действует для запросов одной группы — например, для запросов с одного IP, запросов от одного авторизованного аккаунта, и других групп. Вы можете настроить ключи группировки внутри каждого правила.
У лимита запросов есть допустимая погрешность — единичные запросы сверх лимита могут дойти до сервера. Это необходимо, чтобы оптимизировать модуль и сделать его доступным для проектов с большим объемом трафика
Правила лимита запросов
Лимит запросов работает на основе правил. Их можно включать и выключать в зависимости от ситуации. Правило определяет:
- Условия — какие запросы мы считаем и ограничиваем, а какие пропускаем в любых количествах
- Лимит — сколько максимум запросов, соответствующих условиям, может быть пропущено к серверу за период времени
- Ключи группировки — по каким параметрам мы определяем, что несколько запросов попадают под действие одного счетчика
- Действие защиты — что происходит с запросами сверх лимита
Количество правил ограничено. Если нужно создать больше правил, улучшите тариф или обратитесь в поддержку.
Условия
Условие состоит из параметра (1), оператора (2) и значения параметра (3).
Каждое условие сверяет параметр запроса с его значением используя оператор. Если условие правдиво (оператор возвращает true), срабатывает счетчик.
Кнопкой AND можно добавить еще один параметр к условию. Счетчик сработает только если выполнены все параметры в условии (логическое И).
Кнопка Добавить условие создает новое условие. В таком случае счетчик сработает если выполнены все параметры хотя бы одного условия (логическое ИЛИ).
Параметры
Всего доступно 18 параметров запроса. Для каждого параметра — свой набор допустимых значений и операторов.
Полный список доступных параметров:
Название параметра | Описание | Возможные значения | Операторы |
---|---|---|---|
версия HTTP | версия протокола HTTP | HTTP/2 HTTP/1.1 HTTP/1.0 HTTP/0.9 | in |
тип HTTP-запроса | тип HTTP-запроса, который указывает, какое желаемое действие выполнится для данного ресурса | GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE PATCH | in |
адрес (URL address) | часть URI-адреса запроса | equals in contains startsWith endsWith | |
домен (Host) | HTTP-заголовок Host — содержит имя домена, для которого предназначен запрос | equals in contains startsWith endsWith | |
сжатие (Accept-Encoding) | HTTP-заголовок Accept-Encoding — указывает на алгоритм сжатия контента, который принимает клиент | equals in contains startsWith endsWith exists | |
язык (Accept-Language) | HTTP-заголовок Accept-Language — указывает на язык страницы, который принимает клиент | equals in contains startsWith endsWith exists | |
тип контента (Content-Type) | HTTP-заголовок Content-Type — указывает MIME-тип контента, который отправляет или ожидает клиент | equals in contains startsWith endsWith exists | |
источник (Origin) | HTTP-заголовок Origin — показывает откуда будет производиться загрузка. Включает протокол, имя хоста и порт | equals in contains startsWith endsWith exists | |
реферер (Referer) | HTTP-заголовок Referer — показывает откуда будет производиться загрузка. Включает протокол, имя хоста, порт и URL | equals in contains startsWith endsWith exists | |
User-Agent | HTTP-заголовок, который содержит информацию о ПО клиента и его устройстве | equals in contains startsWith endsWith exists | |
тип контента (Sec-Fetch-Dest) | fetch-заголовок Sec-Fetch-Dest — указывает тип контента, который отправляет или ожидает клиент | audio audioworklet document embed empty font frame iframe image manifest object paintworklet report script serviceworker sharedworker style track video worker xslt | in exists |
тип запроса (Sec-Fetch-Mode) | fetch-заголовок Sec-Fetch-Mode — указывает тип (mode) запроса | cors navigate no-cors same-origin websocket | in exists |
происхождение (Sec-Fetch-Site) | fetch-заголовок Sec-Fetch-Site — указывает на происхождение запроса. Позволяет определить нелегитимное перенаправление | cross-site same-origin same-site none | in exists |
сookies | куки, которые хранит пользователь (этот параметр позволяет задать название и значение куки) | equals in contains startsWith endsWith exists | |
время (GMT) | время по Гринвичу (GMT+0), в которое поступил запрос | between | |
страна | код страны (ISO 3166-1 alpha-2), из которой поступил запрос | in | |
номер AS | номер AS | in | |
IP-адрес | IP-адрес, с которого получен запрос | in |
Операторы
Оператор определяет, как соотносится параметр и его значение у каждого конкретного запроса. Если заданное условие выполнено, счетчик лимита учитывает запрос.
Доступны следующие операторы:
Оператор | Отрицание | Описание |
---|---|---|
равно (equals) | не равно (not equals) | Проверяет, равен ли параметр заданному значению |
равно (in) | не равно (not in) | Проверяет, равен ли параметр одному из заданных значений (можно указать несколько значений) |
содержит (contains) | не содержит (not contains) | Проверяет, встречается ли заданное значение в строке параметра |
начинается с (startsWith) | не начинается с (not startsWith) | Проверяет, начинается ли строка параметра с заданного значения |
кончается на (endsWith) | не кончается на (not endsWith) | Проверяет, кончается ли строка параметра заданным значением |
существует (exists) | не существует (not exists) | Проверяет, указан ли параметр |
в диапазоне (between) | не в диапазоне (not between) | Проверяет, находится ли параметр в диапазоне между двумя числами |
Ключи группировки
Ключи группировки — это критерии объединения запросов в группы. Если у нескольких запросов совпадет параметр-ключ, счетчик лимита для них будет общим.
Например, если в ключ группировки добавить IP, максимальное количество запросов с одного адреса будет ограничено лимитом.
Доступны ключи:
Ключ | Описание |
---|---|
IP-адрес | IP-адрес, с которого получен запрос |
страна | Код страны (ISO 3166-1 alpha-2), из которой поступил запрос |
номер AS | Номер AS |
домен (Host) | HTTP-заголовок Host — содержит имя домена, для которого предназначен запрос |
cookies | Куки, которые хранит пользователь (этот ключ позволяет задать название куки) |
авторизован как (Authorization) | HTTP-заголовок Authorization, который содержит данные для подтверждения права доступа к ресурсу |
ETag | Заголовок ответа ETag содержит уникальный идентификатор версии ресурса, которая хранится у клиента. Может использоваться для идентификации пользователя, который сменил IP, но не очистил кэш |
отпечаток TLS (JA3 hash) | Хэш незашифрованного приветствия при установке TLS-соединения. Будет одинаковым у браузеров (и других программ, в том числе вредоносных) одной версии |
Настройка правила
Допустим, мы хотим ограничить нагрузку на сайт в часы пик, когда он более уязвим из-за всплесков органического трафика.
Создадим такое правило лимита запросов:
С 14:00 до 18:00 по МСК не пропускать больше 100 запросов в минуту к личному кабинету
- В личном кабинете откройте услугу «Веб-защита», на вкладке Домены выберите нужный домен. В левом меню выберите Лимит запросов
- Нажмите кнопку Добавить правило
- В окне создания правила задайте название и установите нужный лимит, период времени и действие защиты
Установите действие защиты «Блокировать (429)», чтобы не пропускать запросы сверх лимита - Добавьте в условие первый параметр — время
С 14:00 до 18:00 по Москве — это с 11:00 до 15:00 по Гринвичу - Чтобы ограничение действовало только для личного кабинета, укажите нужный URL (или Host, если личный кабинет расположен на поддомене). Добавить еще один параметр можно с помощью кнопки AND
- Вы также можете добавить альтернативное условие — например, чтобы ограничение действовало и для личного кабинета на поддомене сайта. Условия соотносятся друг с другом по принципу логического ИЛИ: счетчик срабатывает, если запрос соответствует хотя бы одному из условий
Теперь счетчик сработает и при запросе к example.com/clientarea, и при запросе к my.example.com - Выберите ключ группировки. Для запросов с одинаковым параметром-ключом (в нашем случае — для запросов с одинаковым IP-адресом) счетчик будет общим
- Установите статус правила. Чтобы лимит вступил в силу сразу после создания правила, выберите Включено. После нажатия кнопки Сохранить новое правило появится в списке.
Статистика по правилу
После создания правила вы сможете следить за его работой с помощью вкладки Статистика правила.
Ниже рассмотрим доступные графики и их значения.
В примерах ниже используются правила с небольшим лимитом — 100 запросов в час, 150 запросов за 20 минут. На практике лимит не может быть меньше количества секунд в интервале
Уникальные группы
График показывает количество уникальных групп — то есть групп запросов, у которых совпадают все значения параметров из ключа группировки.
Например, если задан ключ группировки IP-адрес
/32
, каждый IP-адрес будет считаться отдельной уникальной группой.
Уникальная группа создается при появлении запроса, для которого нет подходящей уникальной группы — в примере выше это будет каждый запрос с нового IP-адреса. Если запросов из группы больше не приходит, она исчезает из статистики через период правила * 2
.
Количество запросов
Тепловая карта показывает распределение уникальных групп на шкале запросов. Чем темнее сегмент, тем больше уникальных групп оказалось в этом диапазоне.
Считаются только запросы, которые попадают под действие правила
Рассмотрим в качестве примера такую карту:
Самая «горячая» прослойка на тепловой карте находится в диапазоне 5–20 запросов — то есть чаще всего посетители из каждой уникальной группы делают 5–20 запросов в минуту. Используя эти данные, можно корректировать лимит правила.
Остаток лимита
Остаток лимита можно представить как набор одноразовых «пропусков» к сайту для запроса. Когда у уникальной группы заканчиваются пропуски, к запросам будет применено действие. Счетчик возвращается в исходное положение в начале нового периода.
Допустим, у нас есть запрос с IP-адреса 192.0.2.112
, который попадает под действие правила с ключом группировки IP-адрес
/32
и лимитом 100 запросов в час
. Действие правила — Блокировать (429)
.
Соответственно, уникальной группе 192.0.2.112
назначается лимит в 100 запросов, а каждый пропущенный запрос уменьшает этот лимит на 1. Когда у группы закончится остаток лимита, клиенты из нее (то есть все посетители сайта с адресом 192.0.2.112
) не смогут делать новые запросы до конца периода.
Вот как будет выглядеть «путь» этой уникальной группы на графике:
Мы видим, что уникальная группа исчерпала весь лимит за 20 минут. После этого запросы с 192.0.2.112
были заблокированы с кодом ответа 429.
Уменьшим период времени до 20 минут и проверим правило на трафике с разных адресов:
На тепловой карте видно, что к концу каждого двадцатиминутного периода многие уникальные группы исчерпывают лимит (оказываются в диапазоне 0–5 по оси Y). Если для сайта этот трафик легитимный, значит многие реальные пользователи видят ошибку 429 — следовательно, выставлен слишком жесткий лимит.
Увеличим лимит до 150 запросов. Количество уникальных групп, которые исчерпали лимит, уменьшилось — большая часть посетителей сайта теперь не встречают ошибку 429.
Топ активных групп
Осталось разобраться, кого блокирует лимит — легитимные или нежелательные группы запросов. В этом поможет топ активных групп.
Для каждой группы доступен свой график, на котором видно, как изменялся остаток лимита. Найдем группу с адресом 192.0.2.112
и проанализируем, как лимит повлиял на работу пользователей из этой группы.
На графике видно, что группа тратит лимит слишком быстро и пользователи вынуждены ждать следующего периода, чтобы продолжить работу с сайтом. Если трафик с адреса 192.0.2.112
мы считаем легитимным, необходимо еще немного увеличить лимит или уменьшить интервал, чтобы избежать блокировок: