Эволюция DDoS-атак

Read the Docs исторически была терпима к спайдерам и ботам, парсящим хостируемую документацию. IP-based rate limiting решал большинство проблем с abusе. Около двух лет назад стал заметен всплеск трафика вместе с распространением AI краулеров, и похоже, что другие члены dev-сообщества сталкиваются с похожими проблемами. Стало простым делом подключить AI-сгенерированный скрейпер к сетям прокси. Защиты адаптировались, но июньская атака была более чем в 10 раз больше, чем всё, что приходилось видеть раньше.

Ключевые характеристики атаки:

  • Массивный объём: на пике 5,5 млн запросов в минуту против обычного суточного пика менее 100k req/min.

  • Глобальное распределение: вредоносные запросы поступали с миллионов уникальных IP-адресов в сотнях сетей (ASN) по всему миру, включая блоки жилых IP и крупные хостинг-провайдеры.

  • Рандомизация заголовков и TLS: атакующие систематически варьировали HTTP-заголовки и параметры TLS-соединения, уходя от сигнатурных фильтров (JA3/JA4).

  • Ограничения автоматической защиты CDN: Read the Docs использует Cloudflare, и хотя их автоматическая DDoS-защита перехватила трафик из некоторых "известных ботнетов", значительная часть атаки прошла первую проверку и дошла до rate limiting и WAF-правил.

  • Обход кэша: атакующие нашли и целенаправленно атаковали URL, вызывавшие промахи кэша, такие как несуществующие страницы с уникальными путями (404) и временные редиректы (302).

  • Адаптивное поведение: при введении блокировок или rate limit ботнет менял скорость запросов, ротировал целевые пути и распределял трафик через более широкие пулы IP для тестирования границ защиты.

Масштаб и широта

Предыдущие миниатюрные DDoS-атаки или крупные распределённые скрейперы, как правило, были сконцентрированы каким-то образом: запросы либо поступали из небольшого набора стран, либо из небольшого набора IP-блоков, либо имели небольшой набор браузерных сигнатур. Эта атака была по-настоящему глобальной, поступала со всех стран одновременно — кошмар для rate limiting, когда правила применяются по Cloudflare colocation. Сложно составить правила, ограничивающие распределённую атаку и не влияющие на легитимные боты, скрейпящие с разумной скоростью с одного IP или подсети.

В один момент, когда атакующие сфокусировались на редиректах, они забросали захардкодированный Nginx редирект (простую директиву rewrite regex) таким трафиком, что даже на горизонтально масштабируемой инфраструктуре начали падать запросы. Nginx редирект способен легко обработать тысячи запросов в секунду.

Кроме распределения по миру атака попадала и по разным свойствам Read the Docs: по публичной документации, по коммерческому хостингу. Атакующие также пытались сломать author-facing dashboards, требующие аутентификации.

Было опцией просто включить Cloudflare's "Under Attack Mode" и выдавать каждому посетителю JavaScript challenge, но это не хотели делать. Это сломало бы все API интеграции и создало бы трение для сотен тысяч реальных читателей документации. Вместо этого полагались на rate limiting и целевые челленджи в комбинации с агрессивным кэшированием и переносом функций на край сети.

«Мы никогда не смогли бы справиться с этой атакой без Cloudflare.»

Адаптация к защитам

Read the Docs интенсивно использует Cloudflare для кэширования и rate limiting. Десятки rate limiting правил (управляемых через Terraform) защищают инфраструктуру на основе IP, тысяч хостнеймов и сотен тысяч поддоменов, ASN, браузерных отпечатков и комбинаций всего этого.

Атака началась с небольшого числа доменов, где атакующие обнаружили временные редиректы (302), не кэшируемые на краю и обслуживаемые Python бэкэндом вместо чего-то вроде Nginx. За несколько минут ops-команда получила алерт из-за краткого outage (пользователи часто не замечают outages, потому что кэшированная документация продолжает работать), и примерно за полчаса эти редиректы переместили на край Cloudflare. Казалось, это конец, но атакующие попробовали разные тактики на других хостах и сервисах ещё полторы недели.

Analytics showing oscillating 'Yo-Yo' traffic levels during the attack.

График показывает волнообразный «Йо-йо» паттерн трафика во время атаки.

Атакующие нарастали до порога rate limit, потом отступали, давая окнам rate limit истечь. Это называется yo-yo паттерном и спроектировано так, чтобы максимизировать финансовые расходы auto-scaled инфраструктуры и вызывать перемежающуюся деградацию. Атакующие знали, что используется WAF с rate limits, и знали, как нанести максимум урона несмотря на это.

Защита от объёмных DDoS-атак

Защита от потоков на миллионы запросов в минуту требует многоуровневого подхода: edge кэширование, web app firewall, rate limiting, локальные кэши и fingerprinting запросов. Самый быстрый запрос — тот, что обслужен CDN или WAF.

Edge caching

Первая линия защиты — правильный CDN и минимизация числа запросов, доходящих до origin-серверов. Сервирование документации из CDN имеет множество преимуществ. Для Read the Docs, где документация меняется редко, кэширование довольно агрессивно, но кэш purge'ится для конкретного docs-сайта, когда свежая документация pushed в git и пересобирается. CDN также делает получение документации значительно быстрее для людей, географически удалённых от origin-серверов.

Однако атакующие, зондируя защиты, быстро обнаружили, какие запросы кэшированы, а какие нет, по тому, как быстро CDN отвечает. Это значит, что нахождение даже нескольких некэшированных запросов даёт атакующим угол атаки. Всё ещё находятся новые пути и endpoints, которые не кэшированы, но даже очень короткоживущие кэшированные ответы (с использованием Cache-Control заголовка) для редиректов и обычных 200 ответов помогут против такого рода атак.

Slack notification when Read the Docs is getting 45k uncached req/min

Уведомление Slack: 45k некэшированных запросов в минуту. Без кэширования и rate limiting auto-scaling инфраструктура просто масштабируется, чтобы обработать нагрузку за счёт сервиса.

Rate limiting и fingerprinting

Поскольку не хотелось выдавать JavaScript challenge всем пользователям, использовались целевые rate limiting правила, комбинирующие bot probability scores с per-IP rate limits для челленджа подозрительного трафика и безпрепятственного просмотра легитимных пользователей и хорошо ведущих себя ботов. Все, кто решал JavaScript challenge, знают, что они создают трение. Решили, что лучше пропустить какой-то malicious трафик и ошибиться в сторону неделания challenge реальным пользователям. Тем не менее, rate limits всё ещё были нужны для защиты инфраструктуры.

Вместо сосредоточения на откуда пришел запрос (IP, страна), защиты должны фокусироваться на как выглядит запрос:

  • Cipher suite и TLS аномалии: автоматизированные скрейперы и бот-клиенты часто представляют аномальные TLS-соединения, отличающиеся от браузеров. Cloudflare's bot detection имеет специальные инструменты для этого.

  • Слишком много плохих запросов: легитимные пользователи и хорошие боты почти всегда получают успешные (200) ответы, не редиректы или 404. Поскольку 200 всегда кэшированы, они почти никогда не создают проблемы. Когда видим слишком много дорогих запросов типа редиректов или 404, начинаем rate limiting по браузерному отпечатку, ASN или даже всему домену. Добавление этих правил, которые называют "penalty box", вероятно, сделало наибольшую разницу в автоматической mitigation атаки по мере её эволюции.

  • Несоответствия протокола: вредоносные инструменты часто объявляют современные User-Agent строки, используя старые HTTP/1.1 соединения. К сожалению, это несоответствие не было полезно в этой атаке, которая была полностью HTTP/2 и HTTP/3.

  • Client fingerprinting: каждый, кто использует Golang HTTP client или Python requests модуль с одинаковыми TLS cipher suites, будет иметь одинаковый JA4 fingerprint. Это fingerprinting специфичен браузеру или инструменту, не пользователю. Эти fingerprints тоже не были полезны в этой атаке, так как атакующие рандомизировали свои TLS параметры.

  • IP block классификация: область, над которой всё ещё работают — классификация большего количества IP блоков в разные категории с собственными лимитами. Для сервиса типа Read the Docs, получающего много automated трафика и хотящего позволить ботам, известно, что будет много трафика от больших cloud ASN типа Amazon, Google Cloud, Azure. Они должны иметь более высокие лимиты, чем большинство residential или minor hosting провайдеров.

Дайте пользователям лазейку

Решение, которое было принято — всегда дать реальным пользователям escape hatch. Read the Docs очень редко выдаёт прямые блокировки или баны конкретным IP или user agents. Вместо этого наихудший сценарий — это JavaScript challenge, и если пользователь решает challenge, они очень вряд ли получат challenge снова в течение следующего дня или около того.

Уроки и ключевые выводы

DDoS-атака июня 2026 года подтвердила несколько критических моментов для запуска high-traffic инфраструктуры:

  • IP blocking устарел для распределённых атак: ботнеты или крупные скрейперы используют proxy сервисы, что делает простые IP блоки бесполезными. Это уже было известно, но инцидент это подчеркнул. Защиты должны иметь более широкие rate limits по более чем просто IP (ASN, hostname и т.д.).

  • Кэшируйте агрессивно: кэшируйте всё, будь то простой static файл, 404 или временный редирект. Даже установка короткого кэш-окна в несколько минут гарантирует, что эти ресурсы не смогут быть использованы для атаки инфраструктуры. Настройки по умолчанию на CDN и в большинстве web фреймворков — не то, что хочет сервис типа Read the Docs.

  • Защищайте cache-miss поверхности: атакующие активно ищут нонкэшируемые пути (например, динамические редиректы, search endpoints, 404). Кэшируйте где возможно, и если кэширование невозможно, пытайтесь обрабатывать как можно больше на краю.

  • Целевые челленджи лучше, чем грубые инструменты: комбинирование bot management heuristics с rate limits позволило mitiga'ть атаку с минимальным влиянием на легитимных пользователей.

  • Infrastructure as Code необходим: управление edge и WAF правилами через Terraform позволило быстро и безопасно review'ить, тестировать, version-control и вводить в production сложные фильтрующие правила.

По-прежнему видны низкие уровни фонового трафика из IP блоков атаки, но инфраструктура находится в гораздо более сильной позиции, чем была до атаки. По мере того как AI tooling и proxy networks делают такие атаки дешевле и более доступными, они перестают быть зарезервированы для больших enterprise-мишеней. Они становятся baseline reality для любого high-profile публичного сервиса. Ops-команда снова спит нормально, но рассматривает это скорее как extended reprieve, чем думает, что атаки — это дело прошлого.