ADG Оставить заявку
Блог Информационная безопасность 5 мин чтения

Первые DDoS-волны февраля: как сработали upstream-фильтры и где не хватило rate-limiting

Февраль 2022: аномальный трафик накрыл несколько клиентских площадок. Разбираем, где спасли провайдерские фильтры, где пробило, и срочно пересматриваем схемы защиты.

Контекст момента

Февраль 2022: резкий рост DDoS-атак на российскую инфраструктуру, операторы фиксируют аномальный трафик на уровнях L3/L4 и L7

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

Что случилось

Первая площадка ушла в недоступность по HTTP примерно в ночное окно. Grafana показала spike по входящему трафику - в несколько раз выше нормы. По характеру - смешанный: объёмный флуд на L4 плюс HTTP GET-запросы на публичные эндпоинты. Провайдер среагировал своими средствами через 20-30 минут - upstream ACL-ы отсекли основную объёмную часть. Приложение поднялось, но ещё около часа работало в ухудшенном режиме: HTTP-слой продолжал получать мусорные запросы, которые прошли через фильтр провайдера.

Вторая площадка - отдельный клиент, другой провайдер. Там картина немного другая: объём атаки был меньше, провайдер с ней справился быстрее, но приложение всё равно деградировало. Причина выяснилась позже: rate limiting на уровне nginx-а у этого клиента не был настроен практически никак. Каждый запрос из атакующей подсети попадал прямо в upstream - Rails-приложение, которое тратило на каждый запрос реальные ресурсы БД. Пул соединений лёг.

Третья площадка устояла. Там исторически стоит более плотная конфигурация: провайдерская фильтрация с более низким порогом срабатывания, nginx с rate limiting по IP и по user-agent, ограничение concurrency на уровне upstream. Никакого чуда - просто заранее настроено.

Где провайдерские фильтры спасают, а где нет

Upstream BGP Blackhole и ACL-фильтры провайдера работают хорошо против объёмных атак на L3/L4 - то есть именно тогда, когда нужно отсечь сотни гигабит флуда, пока канал не встал. Это их специализация, и с этим они справляются.

Проблема в другом:

  • Порог срабатывания у провайдера выше, чем мы думаем. Фильтры включаются не при появлении аномалии, а при достижении определённого объёма. До этого момента трафик идёт к нам. Небольшая L7-атака, которая не создаёт объёма, но убивает пул соединений приложения - это не их зона.
  • Провайдер не знает вашего приложения. Он режет по IP-репутации, по объёму, по pattern-ам BGP. Запрос к /api/search с хитрым параметром, который кладёт БД в неоптимальный план - это не его история.
  • Время реакции - это минуты, не секунды. Даже хорошо работающий upstream-фильтр - это не инлайн-защита. Есть окно, в которое прилетает всё.

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

Что должно быть на стороне приложения

После разбора трёх кейсов мы зафиксировали минимальный набор, без которого выходить на периметр в текущей ситуации - легкомысленно.

Rate limiting на уровне nginx - обязателен. limit_req_zone по IP, по комбинации IP + эндпоинт для тяжёлых запросов, отдельная зона для публичных API. Возвращать 429, не тратить ресурсы backend-а. Это не сложно настроить, но почему-то регулярно оказывается не настроено.

Ограничение concurrency на upstream. limit_conn на количество одновременных соединений с одного IP. Атака, которая открывает тысячу connections и держит их - без этого ограничения просто ляжет worker pool.

Connection limit на уровне БД или connection pool. Если приложение под нагрузкой начинает открывать connections как попало - БД умирает независимо от того, что происходит на сетевом уровне. Жёсткий потолок соединений в pgbouncer или аналоге - это не опционально.

Мониторинг с алертами на аномалии трафика. У одного из клиентов атака шла минут двадцать до того, как кто-то это заметил. Grafana была, дашборды были, алерта на аномальный RPS - не было. Это мы уже настраиваем через unified alerting.

Что пересматриваем

По итогам этой недели мы прошлись по клиентским конфигурациям в рамках managed-сопровождения и составили список того, что нужно довести до ума.

Первое - rate limiting. На удивление большая доля конфигураций nginx имеет его в зачаточном виде или не имеет вообще. Идёт проверка и настройка по всем периметровым серверам.

Второе - связка с провайдером. Не у всех клиентов есть настроенный механизм запроса BGP Blackhole на стороне провайдера. Это не автоматически работающая вещь - нужно знать, как запросить, какой IP/AS аннонсировать, кому звонить в 3 ночи. Проверяем, у кого это задокументировано и рабочее.

Третье - геофильтрация там, где она оправдана. Не для всех клиентов подходит, но для тех, у кого аудитория строго локальная - имеет смысл рассмотреть блокировку подсетей за пределами региона на уровне iptables или провайдера. Не панацея, но снижает поверхность.

Четвёртое - stress test. Хочется понять, при каком RPS конкретное приложение клиента начинает деградировать. Без этих цифр любые лимиты выставляются наугад.

Пока промежуточный счёт

Ситуация не завершена - атаки продолжаются на разных площадках по всему рунету, и у нас нет оснований считать, что это последняя волна. Мы сейчас в режиме повышенной готовности: мониторим, докручиваем конфиги, пересматриваем схемы. Кое-что обнаружилось неожиданно - например, что несколько кажущихся простыми конфигураций nginx-а никогда не проверялись на нагрузке выше обычной.

Наблюдение, которое хочется зафиксировать: разница между первой и третьей площадкой - не в деньгах и не в каком-то экзотическом железе. Разница в том, что на третьей эти конфигурации когда-то настроили и не тронули. Иногда техдолг выглядит не как сломанный код, а как отсутствующий limit_req_zone.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.