Несколько лет назад увидеть DDoS‑атаку было целым событием. Если такое и случалось, то инцидент тщательно анализировала целая команда специалистов, а каждая извлечённая крупица информации использовалась для обучения моделей, формирования новых факторов и улучшения подходов для защиты от новых потенциальных атак.

Но постепенно число атак увеличивалось, и в какой‑то момент отбить очередной DDoS стало обычным делом. Только за прошедший 2023 год мы в Яндексе отразили 989 атак на уровне L7. В этом нам помогло инхаус‑решение — Антиробот, который работает на уровне L7 сетевой модели OSI.

В этом посте я хочу рассказать о том, как работает, на чём обучается Антиробот и с какими атаками ему приходится иметь дело. А ещё расскажу, почему важно системно подходить к анализу каждой атаки и как ML помогает отражать их.

С чем приходится бороться 

Обычно мы разделяем DDoS-атаки на два типа: атаки на уровни сетевой модели OSI L3–L4 и на уровень L7. Первые нацелены на сетевое оборудование: они пытаются перегрузить каналы или маршрутизатор. Там работают знакомые вам протоколы TCP/UDP. А когда мы говорим про L7, цель атаки — положить приложение или сайт, а если точнее — непосредственно бэкенд. Здесь используются GET/POST-HTTP-запросы.

Наша команда отвечает за защиту именно от L7-DDoS-атак, поэтому сегодня мы поговорим исключительно о них.

Если посмотреть статистику за 2023 год, то можно увидеть, что каждый второй сервис Яндекса хотя бы раз подвергался DDoS-атакам. Конечно, более популярные сервисы подвергаются атакам чаще, менее популярные, соответственно, реже, но они для нас важны в равной степени — мы стремимся к тому, чтобы одинаково хорошо защищать все сервисы. 

Если говорить об атаках на уровне L7, то за 2023 год мы зафиксировали 989 атак на сервисы Яндекса, в 2022 году их было 761, а за три месяца 2024 года мы уже отбили 231 атаку.

Расширенная статистика 

2022 год

  • Средняя мощность атак составила 234 000 RPS, максимальная — 13 400 000 RPS.

  • В среднем атака длилась около 10 минут. Самая долгая — 8 часов.

  • 90% атак не превышали 412 000 RPS, на оставшиеся 10% приходятся атаки более мощные, вплоть до 13,4 млн RPS. Но вне зависимости от их мощности — 10 000 RPS или 13 400 000 RPS — нам важно одинаково хорошо защищать сервисы от атак.

  • Всего за 2022 год мы отбили 761 атаку. Это в среднем по две атаки в день. Самый «горячий» месяц — декабрь (149 атак), а меньше всего нас пытались положить в январе (38 атак).

Атаки за 2022 год по месяцам
Атаки за 2022 год по месяцам

2023 год

  • Средняя мощность атак составила 200 000 RPS, максимальная — 8 300 000 RPS.

  • В среднем атаки длились не более 20 минут, однако были и такие, которые продолжались до 6 часов. Самая долгая атака в 2023 году длилась 88 часов.

  • Если говорить о природе DDoS‑атак, большая часть из них (~80%) происходит с хостингов и различных облачных провайдеров. Периодически мы видим атаки с мобильных прокси (~14% трафика атак).

  • Всего за 2023 год мы отбили 989 атак. Это в среднем по две-три атаки в день. Самый «горячий» месяц — январь (164 атаки).

Атаки за 2023 год
Атаки за 2023 год

Вывод простой: количество атак год к году только увеличилось — теперь мы отбиваем примерно по две-три штуки в день. Средняя атака стала мощнее, но при этом максимальная нагрузка в целом снизилась.

2024 год

На момент написания статьи (март 2024 года) мы отразили 231 атаку — 113 в январе, 66 в феврале и уже 52 в марте. То есть сохраняется тренд 2023 года — отбиваем примерно по две-три атаки в день.

Средняя мощность — 223 000 RPS, а максимальная — 2 140 000 RPS. При этом 90% атак укладываются в 777 000 RPS (0,9 перцентиль).

В среднем один DDoS длится около 30 минут. Самая долгая атака, которая случилась за эти пару месяцев, продолжалась 5,5 часов.

Атаки за три месяца 2024 года
Атаки за три месяца 2024 года

Атаки в сотни тысяч RPS стали вполне обычным делом. Но важно то, что атакующие постоянно совершенствуют свои инструменты. Атаки, которые приходят изо дня в день, — не один и тот же набор параметров, заголовков и IP‑адресов. Мы отслеживаем разные группы атакующих и видим, как они совершенствуют своё ПО, переходят с нерезидентских IP‑адресов на резидентские и придумывают другие ухищрения.

Именно поэтому для эффективной защиты наших сервисов мы используем ML. Оно даёт возможность уйти от быстро устаревающих эвристических правил в пользу моделей, которые позволяют обобщить информацию об атаках и использовать её в качестве превентивной меры.

Что такое Антиробот и как он работает

Антиробот — это внутренний сервис, который в онлайн‑режиме анализирует запросы к сервисам Яндекса. Он определяет, от кого поступил запрос — от человека или робота.

Антиробот начали делать более 10 лет назад — первоначально только для защиты Поиска Яндекса. Всё это время он развивался и учился решать всё более сложные и масштабные задачи. Например, когда на сервисы Яндекса стали всё чаще приходить DDoS‑атаки и мощность очередной прирастала на 2–3 млн RPS, мы за месяц существенно изменили архитектуру Антиробота, чтобы он мог эффективнее работать на более высоких нагрузках.

Сейчас Антиробот вырос в настоящий highload. Он живёт на уровне балансировщика трафика L7 (это сервис, который устанавливает безопасное соединение с клиентами и распределяет весь входящий трафик по сервисам и приложениям, живущим в нашей инфраструктуре) и активно с ним взаимодействует.

В любой момент Антиробот должен выдерживать нагрузку RPS всех сервисов Яндекса вместе взятых. При этом он должен выдерживать и дополнительную нагрузку в десятки миллионов RPS во время атак. Другими словами, если атака идёт на один сервис Яндекса, то это никак не должно аффектить работу Антиробота в другом сервисе. При этом Антиробот умеет дружить со всеми типами балансеров: их в Яндексе несколько видов — Антиробот одинаково хорошо работает с каждым из них.

https://hsto.org/r/w1560/getpro/habr/post_images/110/6da/b5b/1106dab5b6af0446dfab3377a477f0e6.png
График RPS самой мощной DDoS-атаки на Яндекс 5 сентября 2021 года. Наша техническая команда смогла нейтрализовать атаку и предотвратить отказ в обслуживании

Вся система работает достаточно просто. Балансер отправляет каждый запрос в Антиробот и ожидает получить один из ответов:

  • запрос хороший → пропускаем его дальше до сервиса;

  • запрос подозрительный → направляем запрос на челлендж (показываем капчу);

  • запрос зловредный → блокируем запрос (показываем ошибку 403).

От работы Антиробота зависит работоспособность всех сервисов Яндекса, поэтому на него накладываются самые высокие требования к стабильности и работоспособности. И он уже многие годы исполняет эти требования и занимает самый высокий тир доступности в рамках Яндекса.

Кстати, одна из основных задач Антиробота, помимо защиты от DDoS‑атак, — это защита сервисов от паразитной нагрузки со стороны роботов‑парсеров. У этой задачи другие требования к метрикам, но решается она на той же инфраструктуре — тут тоже активно используются ML‑методы. Но не будем углубляться в эту историю и вернёмся к отражению DDoS.

Архитектура Антиробота

Если посмотреть под капот Антиробота, то мы увидим две части: быструю и умную.

Быстрая часть отвечает на каждый запрос Балансера. Тут важно укладываться в SLA ответа даже при высокой нагрузке во время DDoS‑атак. Основная часть факторов формируется «по записи». То есть записывается то, что приходит в запросе: куда он идёт, какие у него заголовки и IP‑адрес. Однако есть и более хитрые факторы: например, насколько часто конкретный IP‑адрес замечен в DDoS‑атаках.

Над факторным пространством, которое мы собрали на конкретном запросе, запускается лёгкий CatBoost, чтобы оценивать роботность этого самого запроса. Мы его называем лёгким, потому что он обладает небольшим количеством деревьев и ограничений по их глубине. Это нужно, чтобы уметь запускать модель на каждом запросе даже во время мощных DDoS‑атак, во время которых количество запросов кратно увеличивается.

В умной части сосредоточена бо́льшая часть магии. Здесь заложено огромное факторное пространство: на текущий момент оно насчитывает десятки тысяч факторов. Помимо факторов «по записи», как в быстрой части, тут используются агрегации по времени и по таким сущностям, как IP‑адрес, активность использования конкретным пользователем текущего и остальных сервисов Яндекса. По мере развития Антиробота каждый аналитик и разработчик сервиса привнёс в это факторное пространство что‑то своё.

Умная часть позволяет запускать более сложные модели. Здесь наш CatBoost обладает уже бо́льшим количеством деревьев, и они могут быть глубже. Также важно, что здесь у нас есть время на подсчёт более сложных факторов, например агрегаций по времени или понимания, на какие ещё сервисы идут запросы с конкретного IP.

Также умная часть позволяет обнаружить «плохую» сущность, например IP злоумышленника, и занести её в так называемый robotset. Потом быстрая часть смотрит на этот robotset и принимает решение — банить его полностью или нет.

Что касается метрик, то здесь мы используем такой подход. Представим, что прямо сейчас на сервис N идет DDoS‑атака. От Антиробота ожидается, что вся атака полностью будет отбита — то есть recall (полнота) будет ~1.

Почему ожидается такое значение полноты? Давайте представим, что на сервис пришла атака в 10 млн RPS, и у нас есть крутая модель, которая работает с полнотой 0,99. Эта оставшаяся 0,01 составляет 100 000 RPS, что вполне себе приличная нагрузка, которая может, например, существенно замедлить сервис, а некоторые сервисы и вовсе привести к неработоспособности. Поэтому даже полноты в 0,99 тут недостаточно.

Что касается хорошего человеческого трафика, который в это же время идёт на сервис, то важно не задевать людей и держать precision (точность) тоже ~1.

Понятно, что точность и полнота, равные 1, могут быть только в наших мечтах. Но мы постоянно стремимся к этим значениям: при обучении мы фиксируем точность наших методов на значении >0,999 и увеличиваем полноту, добавляя новые факторы и тем самым усложняя наш CatBoost.

Чуть подробнее про ML

А зачем вообще в задаче защиты от DDoS‑атак использовать ML? Конечно, можно обойтись и без него, однако методы машинного обучения очень хорошо решают эту задачу благодаря тому, что с ними появляется возможность обобщать данные и находить такие комбинации факторов запроса, которые сложно заметить эксперту. Проще говоря, ML‑модели очень хорошо отделяют «хороший» трафик от «плохого».

Как я рассказывал выше, в обеих частях Антиробота есть ML‑модели. Для ловли DDoS‑атак эффективнее обучать сервис на его умной части — там гораздо больше различных агрегаций, в том числе по времени, которые помогают вычленить из общего трафика DDoS‑атаки.

Если бы передо мной поставили задачу обучить ML‑модель для защиты от DDoS‑атак пару лет назад, то, наверное, я бы пошёл искать синтетические данные или эмулировать атаки, чтобы хоть как‑то хоть где‑то найти горсть данных. Сегодня у нас такой проблемы нет, ведь с DDoS‑атаками мы встречаемся каждый день.

Сейчас у нас есть отточенный цикл разработки и внедрения ML‑моделей:

Шаг 1. Антиробот логирует запросы, а также на каждый запрос формирует два факторных пространства: на быстрой части — около тысячи факторов, а на умной — десятки тысяч.

Шаг 2. Аналитики строят пайплайны по разметке данных.

Шаг 3. Далее аналитики в зависимости от задачи обучают CatBoost, который будет запускаться в продакшне в реалтайме. К нему есть ряд требований:

  • модель достаточно легковесная, чтобы запускать её на каждом запросе;

  • она удовлетворяет нашим требованиям точности и полноты;

  • она достаточно стабильна — под этим я имею в виду, что она использует такую комбинацию факторов, которую крайне сложно раздебажить «снаружи» и подобрать такой паттерн атаки, который пройдёт мимо модели.

Важно отметить, что в динамически меняющемся мире DDoS‑атак не получается обучить ML раз и навсегда. Увы, модели быстро устаревают. Именно поэтому мы не снижаем темп разбора атак и генерации новых факторов, чтобы быть сильнее.

Хочется отметить, что без людей и выстроенных процессов все эти высокопроизводительные решения могут быстро превратиться в тыкву.

Что есть кроме Антиробота 

Несмотря на защитные алгоритмы Антиробота, мы не исключаем из процесса человека. Как и в большинстве других команд Яндекса, у нас есть еженедельные дежурства. У нас работает регулярный процесс, который создаёт тикет на каждую случившуюся атаку. Конечно, иногда они бывают False Positive: например, запуск рекламной кампании нового продукта, который может создавать аномальные всплески трафика на сервис.

Раз уж DDoS — событие достаточно регулярное, дежурный аналитик каждый день просматривает атаки, которые приходили на различные сервисы. Приоритетная задача: подробно изучить атаку, понять, как её отлавливать в следующий раз, придумать новые факторы и отправить эти данные в обучающую выборку для ML‑моделей Антиробота.

Для нас важно извлекать максимальное количество знаний из всех атак, которые выдерживают наши сервисы. Даже из тех, которые мы без проблем отбили. Наиболее общий алгоритм разбора атаки выглядит так:

  • смотрим случайные запросы;

  • находим паттерн поведения;

  • ищем, чем текущая атака отличается от предыдущих;

  • добавляем данные по атаке в обучающую выборку для ML‑модели, чтобы она ещё лучше защищала нас от DDoS‑атак в будущем.


В текущей реальности нам важно системно подходить к задаче по защите сервисов от DDoS — отслеживать атаки и понимать, как они модифицируются и совершенствуются. И в нашем случае успешное отражение атак базируется на трёх компонентах:

  • технологии (Антиробот);

  • люди (аналитики + разработчики);

  • процессы.

Благодаря технологиям получается отбивать постоянные атаки на сервисы Яндекса. Благодаря людям получается развивать технологии, обучать ML‑модели и бороться со злоумышленниками. Благодаря процессам получается выстроить постоянный пайплайн улучшений как для технологий, так и для ML‑алгоритмов.

Все три компонента неразрывно связаны, и важно поддерживать все их в постоянном тонусе. Стоит убрать или ослабить один из них — вся система начнёт разрушаться. Так что противостоять попыткам положить сервисы на лопатки можно только совместными усилиями.

Комментарии (1)


  1. stranger1101
    22.03.2024 15:53

    Спасибо за статью, очень интересно было прочитать про масштабы DDoS-атак! Но было бы еще более интересно увидеть больше технических подробностей.

    Как делаете инференс? Как удается обеспечить быстрый апскейл сервиса при аттаке? Судя по скриншоту он должен переживать увеличение нагрузки в духе х100 меньше чем за минуту.

    В чем именно роль быстрой vs. умной части? У быстрой сильно меньше recall? Какая часть запросов доходит до умной части?

    Как размечаете выборку, как проверяете что recall/precision остаются в заданных границах? Делаете какой-то пост-анализ или есть какие-то метрики в реалтайме?