DDoS: типы атак и защита
Разбираем, как устроены распределённые атаки на отказ в обслуживании и как держать сервис на плаву, когда на него идёт лавина трафика.
DDoS (Distributed Denial of Service) — атака, при которой множество источников одновременно нагружают сервис, чтобы исчерпать его ресурсы и сделать недоступным для легитимных пользователей.
Этот урок — чисто оборонительный. Мы не учим «класть» чужие сайты: несанкционированное нарушение работы информационных систем наказуемо (УК РФ ст. 273/274). Цель — понять механику, чтобы грамотно строить защиту своего сервиса и спокойно проходить инциденты.
Зачем это знать защитнику
DDoS — одна из самых «дешёвых» для атакующего и болезненных для бизнеса угроз. Не нужно искать уязвимость в коде: достаточно отправить больше запросов, чем сервис способен переварить. Защитник должен заранее знать пределы своей инфраструктуры, иметь план реагирования и автоматические механизмы фильтрации, иначе атака превращается в многочасовой простой.
Три класса атак
Атаки удобно делить по уровню модели OSI, на который они давят. От класса зависит и метод защиты.
Объёмные (volumetric)
Цель — забить канал связи мусорным трафиком, измеряется в гигабитах в секунду (Гбит/с). Типичный приём — амплификация (отражение): атакующий шлёт небольшой запрос на уязвимый публичный сервис (открытый DNS-, NTP-, memcached-резолвер) с подменённым (spoofed) адресом жертвы, а сервис отвечает жертве пакетом в десятки раз больше. Защита на уровне одного сервера тут бессильна — канал переполняется ещё до вашего оборудования.
Протокольные (protocol)
Истощают не канал, а таблицы состояний устройств: межсетевых экранов, балансировщиков, самого ядра ОС. Классика — SYN flood: поток TCP-пакетов с флагом SYN открывает массу полуоткрытых соединений, которые занимают слоты в очереди и не доводятся до конца. Измеряется в пакетах в секунду (pps).
Прикладные (L7, application)
Самые коварные: трафик выглядит как обычные HTTP-запросы, проходит фильтры нижних уровней, но каждый запрос дорог для бэкенда (тяжёлый поиск, генерация PDF, обращение к БД). Даже умеренный поток валит приложение, оставаясь незаметным по объёму. Отличить такого «бота» от живого пользователя — главная сложность защиты L7.
Как это работает под капотом
Многие объёмные атаки опираются на спуфинг IP-адреса источника: в UDP отправитель не проверяется рукопожатием, поэтому ответ уходит не атакующему, а жертве. Отсюда два следствия. Во-первых, отражение даёт усиление (amplification factor) — отношение размера ответа к запросу; у некоторых протоколов оно достигало сотен. Во-вторых, провайдеры по всему миру внедряют BCP 38 (ingress filtering) — отбрасывают на выходе пакеты с заведомо чужим адресом источника. Это коллективная гигиена: чем больше сетей её соблюдает, тем меньше материала для спуфинга.
SYN flood эксплуатирует устройство TCP-рукопожатия. На каждый SYN сервер выделяет память под полуоткрытое соединение и держит его до таймаута. Контрмера в ядре — SYN cookies: сервер не хранит состояние, а кодирует параметры соединения в начальном номере последовательности и восстанавливает их, только когда клиент пришлёт корректный ACK. Включается на уровне ОС:
# Linux: проверить и включить SYN cookies (защита от SYN flood)
sysctl net.ipv4.tcp_syncookies
sudo sysctl -w net.ipv4.tcp_syncookies=1
Логика простого ограничителя запросов (rate limiter) на уровне приложения концептуально такая:
from collections import deque
WINDOW_SECONDS = 1.0
MAX_REQUESTS = 5 # не более 5 запросов в секунду с одного ключа
hits = deque()
def allow(now: float) -> bool:
while hits and now - hits[0] > WINDOW_SECONDS:
hits.popleft() # выбрасываем устаревшие отметки
if len(hits) < MAX_REQUESTS:
hits.append(now)
return True
return False
t = 0.0
for i in range(8):
print(i, "ok" if allow(t) else "throttled")
t += 0.1 # 10 запросов/сек — быстрее лимита
Вывод:
0 ok 1 ok 2 ok 3 ok 4 ok 5 throttled 6 throttled 7 throttled
Это «скользящее окно» — упрощённая модель того, что делают балансировщики и API-шлюзы, отсекая всплески с одного клиента.
Как защититься
Защита от DDoS — это эшелоны, а не одна кнопка. Ключевая идея: фильтровать как можно дальше от вашего сервера, чтобы канал и оборудование не успевали захлебнуться.
- Anti-DDoS-сервисы и scrubbing-центры. Трафик проходит через распределённую сеть очистки, которая поглощает объёмные атаки своей огромной ёмкостью и возвращает вам только «чистый» поток. Для веб-сервисов это часто провайдер CDN с защитой на периметре.
- CDN и кеширование. Сеть доставки контента отдаёт статику с краевых узлов по всему миру, скрывает реальный IP origin-сервера и размазывает нагрузку. До бэкенда доходит лишь малая доля запросов.
- Rate limiting и WAF. Ограничение частоты запросов на клиента/IP/токен плюс веб-файрвол, отсекающий аномальные L7-паттерны. Для подозрительных клиентов — challenge (проверка, что это браузер/человек).
- Blackholing (RTBH). Крайняя мера: по протоколу BGP объявляется маршрут «в никуда» для атакуемого адреса, и провайдер отбрасывает весь трафик к нему на своей границе. Сервис при этом тоже недоступен — но вы спасаете остальную инфраструктуру. Тоньше работает flowspec, отбрасывающий только вредоносные потоки.
- Запас по ёмкости и автоскейлинг. Горизонтальное масштабирование и резерв по полосе дают время среагировать.
- План реагирования. Заранее согласованные контакты у провайдера/защиты, runbook, мониторинг трафика и алерты по аномалиям. Импровизация во время атаки стоит часов простоя.
Хорошая гигиена самого защитника — не быть звеном чужой атаки: закрывать открытые резолверы, не оставлять наружу memcached/NTP без ограничений, соблюдать BCP 38 в своей сети.
Итоги
- DDoS делят на объёмные (давят на канал), протокольные (на таблицы состояний) и L7 (на приложение) — метод защиты зависит от класса.
- Спуфинг и амплификация — двигатель объёмных атак; BCP 38 и закрытие открытых резолверов сокращают их базу.
- SYN flood гасится SYN cookies; всплески L7 — rate limiting, WAF и challenge.
- Реальная защита — эшелоны: scrubbing/CDN на периметре, лимиты и WAF на приложении, blackholing как крайняя мера, и обязательный план реагирования.
- Нарушать работу чужих систем нельзя; знание механики нужно, чтобы защищать своё.