Остановите трафик ботнета до того, как он доберётся до базы данных
Как фильтрация на уровне IP отсекает ботнеты, credential stuffing и массовые регистрации на периметре — ещё до того, как приложение откроет соединение с базой.
Большинство прикладных стеков устроены слишком вежливо. Приходит запрос, роутер передаёт его контроллеру, контроллер открывает соединение с базой, выполняет запрос, собирает ответ. Для живого пользователя это нормальный путь. Для ботнета — подарок.
Распределённому ботнету не обязательно искать уязвимость, чтобы навредить. Ему достаточно, чтобы приложение продолжало отвечать «да»: да — форме входа, да — поисковому эндпоинту, да — письму для сброса пароля, да — ещё одному соединению из пула. К моменту, когда такой трафик доходит до ORM, вы уже заплатили за TLS, поиск сессии и поход в базу — и всё это умножено на тысячи узлов в минуту.
Самый дешёвый запрос — тот, который вы вообще не обрабатывали. В этом и заключается смысл фильтрации по IP на периметре.
Как ботнет выглядит на уровне IP
Трафик ботнета редко приходит с одного адреса. Обычно адресов много, и их можно разложить на несколько хорошо узнаваемых категорий:
- Скомпрометированные домашние устройства. Роутеры, IoT-устройства и заражённые рабочие станции. По отдельности трафика немного, вместе — огромный объём.
- Арендованные мощности в дата-центрах. Дешёвые VPS, поднятые пачками. Обычный покупатель почти никогда не оформляет заказ с диапазонов AWS, OVH или Hetzner.
- Коммерческие proxy-сети. Резидентские и мобильные proxy-пулы, которые перепродаются гигабайтами и прямо позиционируются как способ обходить блокировки по IP.
- Публичные VPN и выходные узлы TOR. Полезны для пользователей, которым важна приватность, но непропорционально часто встречаются в злоупотреблениях.
Ни одна из этих категорий сама по себе не означает злой умысел. IP из дата-центра может быть вашим же мониторингом. VPN-выходом может пользоваться клиент в гостиничном Wi-Fi. Именно поэтому решение должно оставаться за вами, а не за универсальным блок-листом: вам нужна классификация, а затем вы применяете к ней свою политику.
Блокировать до базы данных, а не после
Порядок действий важнее точности любого отдельного сигнала. Возьмём две версии одного и того же эндпоинта входа.
| Stage | Without IP filtering | With IP filtering first | | --- | --- | --- | | Parse request | Yes | Yes | | IP classification | — | ~1 lookup, cached | | Session / user lookup | Yes | Only if allowed | | Password hash verify | Yes (expensive by design) | Only if allowed | | Rate-limit write | Yes | Only if allowed |
Хеширование пароля намеренно сделано медленным — в этом его смысл. Но при credential stuffing по незащищённой форме входа ваш собственный механизм безопасности превращается в инструмент отказа в обслуживании. Если принять решение по IP до проверки пароля, атакующий узел получит 403 ценой обращения к hash map, а пул соединений с базой останется доступен реальным клиентам.
Та же логика работает для поисковых эндпоинтов, которые нагружают полнотекстовые индексы, для регистрационных форм, запускающих транзакционные письма, и для любых действий, где каждая попытка пишет строку в аудит.
Практичная политика, а не глухая стена
Жёстко блокировать всё подозрительное — верный способ получить злые обращения в поддержку. Лучше работает многоуровневая реакция. Если у каждого адреса есть тип и оценка риска, такую политику легко описать:
- Пропускать без лишних действий. Адреса домашних и корпоративных провайдеров с низким risk score. Это подавляющее большинство нормального трафика.
- Добавлять трение. VPN или выходные узлы TOR — только на чувствительных действиях: регистрация, сброс пароля, изменение реквизитов для выплат. Покажите challenge, потребуйте подтверждение по email, не выдавайте бесплатный trial автоматически.
- Сильно ограничивать. Диапазоны дата-центров и хостингов, которые ходят в пользовательские эндпоинты. Легитимным интеграциям место в вашем API с ключом, а не в форме логина.
- Отклонять на периметре. Известная abusive proxy-инфраструктура, которая бьёт по аутентификации, или любой адрес, уже превысивший свой per-IP бюджет.
Важно: шаг 4 — самая маленькая корзина, а не режим по умолчанию. Цель — сделать злоупотребления дорогими, а не сделать продукт недоступным.
Где размещать проверку в стеке
Есть три варианта, в порядке примерной эффективности:
- CDN или reverse proxy. Самая ранняя точка. Запрос вообще не попадает на application server. Хорошо подходит для грубых правил по очевидно враждебным диапазонам.
- Middleware в приложении. Срабатывает до роутинга и до любого обращения к базе. Здесь живёт более тонкая политика по конкретным эндпоинтам: строго для
/login, мягче для/pricing. - Внутри бизнес-логики. Для решений, которым нужен контекст аккаунта: например, отметить вход с IP дата-центра в аккаунт, который раньше всегда использовал одного мобильного оператора.
Большинству команд в первую очередь нужен второй вариант. Это несколько строк перед роутером — и защита всего, что находится за ним.
Кешируйте агрессивно, при сбое пропускайте
Два эксплуатационных правила не дадут IP-reputation проверке самой стать причиной аварии:
Кешируйте по адресу. Ботнеты повторно используют узлы. Короткий in-memory TTL — минуты, а не дни — сводит тысячи запросов к одному lookup и оставляет добавленную задержку в диапазоне микросекунд для повторяющихся нарушителей. Guarda по этой же причине кеширует проверки на стороне сервера, а окно кеширования можно настроить.
Fail open, но логируйте громко. Если сервис репутации недоступен, пропустите запрос и запишите событие. Антиабуз-контроль, который роняет checkout из-за проблем у стороннего сервиса, может стоить дороже самой атаки. Fail-closed стоит оставить только для действительно критичных действий вроде вывода средств.
Что измерять после включения
Сначала включите фильтр в режиме log-only и сравните неделю наблюдений с неделей блокировок:
- Долю запросов, отклонённых до обращения к базе данных.
- Насыщение пула соединений с базой в пиковые периоды атаки.
- Количество неуспешных попыток входа в час.
- Обращения в поддержку с формулировками вроде «не могу войти» — это канарейка false positive.
- Долю регистраций, дошедших до подтверждённого аккаунта: обычно она заметно растёт, когда прекращаются одноразовые регистрации из дата-центров.
Если последние два показателя движутся не туда, ослабьте конкретный уровень политики, а не выключайте всю систему целиком.
Честные ограничения
IP-репутация — это один слой защиты, а не магический firewall. Резидентские proxy-пулы ротируются через реальные пользовательские адреса, которые могут выглядеть неотличимо от ваших клиентов. Carrier-grade NAT означает, что за одним мобильным IP могут стоять тысячи людей. Злоумышленники с бюджетом всегда найдут более чистую инфраструктуру, чем злоумышленники без бюджета.
Зато IP-фильтрация стабильно убирает дешёвое высокообъёмное большинство — скриптовые заливы с арендованных серверов и выжженных proxy-листов. После этого более медленным и умным защитным механизмам — device fingerprinting, поведенческому анализу, MFA, rate limits на уровне аккаунтов — приходится разбираться с гораздо меньшей и более интересной аудиторией.
В этом и есть реалистичная победа: не непроницаемый периметр, а база данных, которая продолжает отвечать на запросы, пока вас атакуют.
Вы можете проверить любой адрес по сигналам Guarda о proxy, VPN, TOR, hosting и risk score с помощью бесплатной проверки на главной странице, а затем подключить тот же вызов в middleware перед вашими маршрутами.
