Что он на самом деле делает
Каждый посетитель делает запросы. Лимит говорит: от одного клиента я приму столько-то запросов за столько-то секунд, а всё сверх этого будет отклонено. В этом и вся идея — это счётчик с последствиями.
Ценность ему придаёт асимметрия. Скрапер, скрипт подстановки украденных учёток и вышедшая из-под контроля интеграция на уровне одного запроса выглядят точно так же, как браузер; по отдельному запросу их не различить. Но во времени они ведут себя совершенно иначе: человек читает страницу и делает несколько кликов в минуту, а скрипт — сотни запросов. Rate limiting ловит поведение, а не содержимое, поэтому он останавливает атаки, которые не распознает ни одна сигнатура.
Как выбрать число, которое не навредит
Ошибка — выбирать лимит по интуиции. Отталкивайтесь от того, что уже делает ваш реальный трафик: посмотрите на самого активного легитимного посетителя за обычный час и поставьте лимит с хорошим запасом выше. Лимит, до которого может дотянуться только бот, работает незаметно; лимит, который способен задеть увлечённого клиента, — это обращение в поддержку, которое вы создали себе сами.
Две детали избавят вас от большинства ложных срабатываний. Во-первых, помните, что один адрес могут делить несколько человек — офис, школа, NAT мобильного оператора, — поэтому лимит, рассчитанный «на одного человека», накажет целое здание. Во-вторых, помните про собственный трафик: мониторинг, health-check'и, партнёрская интеграция и ваш CI приходят с нескольких адресов с высокой частотой, и именно они первыми страдают от нового лимита.
Начинайте намеренно свободно. Лимит, который вы ужесточите через неделю наблюдений, обойдётся куда дешевле того, который придётся ослаблять после жалобы клиента.
Не каждому пути нужен один и тот же лимит
Единое число на весь сайт — компромисс, которым никто не доволен: достаточно свободный для просмотра страниц означает бесполезный на форме логина, а достаточно жёсткий для логина ломает страницу товара.
Думайте о том, во что запрос обходится вам и что злоупотребление им даёт атакующему. Логин, сброс пароля и оформление заказа дёшевы в запросе и ценны для атаки, поэтому им — самые строгие лимиты: человек входит один раз, а не сорок раз в минуту. Поиск и API-эндпоинты дороги в обслуживании и привлекательны для скрапинга: ограничивайте их по тому, что нужно реальной интеграции. Обычные страницы и статические файлы дёшевы и активно используются живыми людьми, поэтому им нужны щедрые лимиты или вообще никаких — кэш CDN и так их поглощает.
На cdn.com.tr лимит частоты запросов можно задать на уровне всего аккаунта, а также для отдельного правила доставки — именно это делает подход практичным: строгое правило для пути логина и более свободное для остального сайта.
Почему edge — правильное место для лимита
Rate limiting внутри приложения работает — в том смысле, что код выполняется. Но к моменту, когда приложение может посчитать запрос, оно уже приняло соединение, заняло воркер и, вероятно, обратилось к базе данных: атака уже отняла у вас тот ресурс, который вы пытались защитить. Под наплывом трафика сам лимитер становится частью того, что падает.
При применении на edge отказ происходит рядом с клиентом, ещё до того как трафик вообще дойдёт до вашего источника. Ваш сервер его не видит, значит и цену платите не вы. Поэтому же rate limiting на edge продолжает работать, когда вашему источнику уже тяжело: лимит не конкурирует за те ресурсы, которые он защищает.
Rate limiting против WAF и защиты от DDoS
Эти три вещи часто используют как синонимы, хотя они делают действительно разную работу.
Rate limiting считает. Он знает, как часто клиент спрашивает, и ничего не знает о том, что именно он спрашивает. Он останавливает перебор паролей, скрапинг и случайную долбёжку.
WAF инспектирует. Он читает запрос и блокирует те, что похожи на SQL-инъекцию, межсайтовый скриптинг или известный эксплойт — один вредоносный запрос будет пойман с первой же попытки, как бы медленно он ни приходил.
Защита от DDoS поглощает. Когда трафика столько, что даже просто посчитать его уже непосильно, объём приходится впитывать сетевой ёмкостью, распределённой по множеству локаций.
Вам нужны все три, потому что каждая закрывает слепое пятно остальных: один хитрый запрос, который счётчик пропустит; тысяча безобидных на вид запросов, в которых WAF не найдёт ничего плохого; и миллион запросов, которые ни одна отдельная машина не в состоянии даже обработать. На cdn.com.tr всё это — части одного edge, настраиваемые из одной панели.
Как выкатить лимит и ничего не сломать
Поставьте лимит достаточно высоко, чтобы, по вашим ожиданиям, он вообще не срабатывал, — и наблюдайте. Смотрите, что на самом деле было отклонено: если это скрапер или скрипт логина — ужесточайте уверенно; если это ваш собственный мониторинг или интеграция клиента — вы узнали об этом раньше, чем это стоило вам жалобы.
Держите исключения честными и немногочисленными: ваш мониторинг и известные партнёрские интеграции, а не «тот, кто громче всех пожаловался». И относитесь к лимиту как к живому числу: трафик растёт, выходит мобильное приложение, интеграция удваивает частоту опроса. Лимит, который был щедрым в прошлом году, может незаметно стать причиной того, что функция кажется сломанной.
Частые вопросы
С какого лимита лучше начать?
Универсального числа нет — всё зависит от того, что делают ваши реальные пользователи. Измерьте самого активного легитимного посетителя за обычный час, поставьте лимит с хорошим запасом выше и ужесточайте только после того, как понаблюдаете, что именно отклоняется. Строгие лимиты уместны на путях логина и сброса пароля, а не на обычных страницах.
Может ли rate limiting заблокировать реальных клиентов?
Может, если он слишком жёсткий, — особенно там, где один адрес делят многие (офисы, школы, мобильные сети) или где ваш собственный мониторинг и интеграции часто опрашивают сервис. Старт со свободного лимита и его ужесточение по наблюдаемому трафику снимают почти всю эту проблему.
Достаточно ли rate limiting, чтобы остановить DDoS-атаку?
Нет. Rate limiting справляется со злоупотреблениями со стороны обозримого числа клиентов. Распределённая атака идёт со слишком большого количества источников, чтобы подсчёт сам по себе помог, — тут нужна ёмкость для поглощения DDoS перед вашим источником, а rate limiting выполняет более тонкую работу позади неё.
Может, лучше ограничивать частоту в самом приложении?
Лимиты на уровне приложения полезны для бизнес-правил по аккаунтам («на этом тарифе 1000 вызовов API в день»). Для защиты от злоупотреблений лучше edge: запрос отклоняется, не доходя до вашего сервера, поэтому не стоит вам ничего и продолжает работать, пока ваш источник под нагрузкой.