DDoS — это когда тысячи (или миллионы) запросов одновременно летят на ваш сервер, пока он не падает под нагрузкой. Звучит как что-то из мира крупных корпораций, но на практике атакуют всех: интернет-магазины, небольшие SaaS-сервисы, корпоративные сайты и даже личные блоги — если кому-то это выгодно или просто интересно.

Атака может длиться 10 минут или неделю. Может быть направлена на конкретный эндпоинт API или на весь сервер целиком. И стоимость даже часового простоя для бизнеса — это потерянные заказы, репутационный урон и головная боль для команды.

Хорошая новость: базовую защиту можно выстроить без огромного бюджета. Плохая: «базовая» не значит «достаточная против целенаправленной серьёзной атаки». Но для большинства случаев — более чем.

Что вообще происходит при DDoS

Distributed Denial of Service — распределённая атака отказа в обслуживании. «Распределённая» означает, что запросы идут не с одного IP, а с тысяч разных — ботнет, арендованные серверы, скомпрометированные устройства.

Атаки делятся на несколько типов:

Объёмные атаки (volumetric) — забивают канал трафиком. Если у вас канал 1 Гбит/с, а атака генерирует 10 Гбит/с, сервер просто недоступен. Против этого можно бороться только на уровне провайдера или CDN.

Протокольные атаки — SYN flood, ICMP flood, UDP flood. Эксплуатируют особенности сетевых протоколов. Например, SYN flood открывает миллионы полуоткрытых соединений, исчерпывая таблицу состояний сервера.

Атаки на уровне приложения (L7) — самые хитрые. HTTP-запросы выглядят как обычный трафик, но их много. Например, тысячи запросов к тяжёлой странице поиска с разными параметрами. Фильтровать сложнее всего.

Первый рубеж: настройки на уровне ОС

До того как ставить сторонние решения, стоит правильно настроить сам Linux-сервер.

SYN cookies

Включите защиту от SYN flood через ядро:

sysctl -w net.ipv4.tcp_syncookies=1
sysctl -w net.ipv4.tcp_max_syn_backlog=2048
sysctl -w net.ipv4.tcp_synack_retries=2

Добавьте в /etc/sysctl.conf, чтобы настройки сохранялись после перезагрузки.

Ограничение соединений через iptables

Bруза блокирует IP, которые открывают слишком много соединений за короткое время:

iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

Это грубый инструмент — легитимные пользователи за NAT тоже могут попасть под блокировку. Используйте аккуратно.

Для более точной блокировки по количеству соединений с одного IP:

iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT --reject-with tcp-reset

fail2ban как базовый щит

fail2ban читает логи и банит IP, которые ведут себя подозрительно. Устанавливается за пару минут:

apt install fail2ban

Для nginx создайте /etc/fail2ban/jail.local:

[nginx-req-limit]
enabled = true
filter = nginx-req-limit
action = iptables-multiport[name=ReqLimit, port="http,https"]
logpath = /var/log/nginx/error.log
findtime = 600
banctime = 7200
maxretry = 10

fail2ban не спасёт от серьёзной распределённой атаки, но отсечёт примитивный скрипт-кидди-флуд.

Nginx как L7-фильтр

Если у вас nginx на фронте — используйте его возможности по rate limiting.

Ограничение запросов

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
    
    server {
        location / {
            limit_req zone=one burst=20 nodelay;
            limit_req_status 429;
        }
    }
}

Здесь: не более 10 запросов в секунду с одного IP, бёрст до 20 без задержки. Остальное — 429 Too Many Requests.

Ограничение соединений

http {
    limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
    
    server {
        limit_conn conn_limit_per_ip 20;
    }
}

Блокировка по User-Agent и геолокации

Пустой или подозрительный User-Agent — частый признак бота:

if ($http_user_agent = "") {
    return 444;
}

444 — специальный код nginx, который закрывает соединение без ответа, не тратя ресурсы.

Если ваша аудитория — только Россия, блокировка по GeoIP срежет значительную часть атак. Модуль ngx_http_geoip2_module + база MaxMind GeoLite2 — бесплатное решение.

CDN и защита на уровне провайдера

Против объёмных атак без CDN или специализированного провайдера не обойтись. Если атака генерирует трафика больше, чем ваш канал — никакие iptables не помогут.

Cloudflare

Бесплатный тариф Cloudflare уже даёт приличную защиту:

  • Скрытие реального IP сервера (трафик идёт через их сеть)
  • Автоматическая фильтрация части атак
  • DDoS-protection для L3/L4 включена по умолчанию
  • Browser Integrity Check и Challenge Page для подозрительных запросов

Pro-тариф (от $20/месяц) добавляет WAF с готовыми правилами и более тонкую настройку rate limiting.

Важный момент: если реальный IP вашего сервера где-то утёк (например, в старых DNS-записях или в SSL-сертификатах на crt.sh), атакующий может бить напрямую, минуя Cloudflare. Смените IP после подключения CDN.

Anycast-сети

Kруп��е CDN-провайдеры используют Anycast: один IP-адрес анонсируется с множества точек по всему миру, трафик поглощается ближайшими узлами. Против объёмных атак мощностью 100+ Гбит/с это единственный реальный метод.

Защита на уровне хостинга

Многие VPS/выделенные серверы предлагают Anti-DDoS как опцию. OVH, Hetzner, VDSINA, Selectel — у каждого своё решение. Уточняйте у провайдера: что именно они фильтруют, на каком уровне, есть ли порог после которого они просто null-route ваш IP (чёрная дыра — трафик к вам просто дропается на уровне провайдера).

Null-route — это не защита, это капитуляция. Сервер недоступен, атака тоже не доходит. Для атакующего — победа.

WAF — Web Application Firewall

WAF фильтрует HTTP-трафик по сигнатурам и правилам. Помогает против L7-атак, SQL-инъекций, XSS и других прикладных угроз.

ModSecurity

Опенсорс WAF, интегрируется с nginx и Apache. С набором правил OWASP Core Rule Set (CRS) закрывает большинство типовых атак:

apt install libmodsecurity3 libnginx-mod-security2

Настройка требует времени — правила генерируют ложные срабатывания, нужно тюнить под свой проект. Но оно того стоит.

Cloudflare WAF

Если уже используете Cloudflare — включите WAF в панели управления. На Pro-тарифе доступны готовые правила для WordPress, Drupal, популярных CMS и фреймворков.

Мониторинг и реакция

Без мониторинга вы узнаете об атаке от клиентов, которые пишут «у вас сайт не работает». Это плохо.

Что отслеживать

  • Количество запросов в секунду (RPS) — резкий скачок в 5-10 раз от нормы это тревожный сигнал
  • Полоса пропускания — внезапный рост входящего трафика
  • Количество активных соединений
  • Время ответа сервера — если растёт, значит ресурсы перегружены
  • Ошибки 5xx в логах nginx

Инструменты

Для быстрой проверки прямо сейчас:

# Количество соединений по IP
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n | tail -20

# Топ IP в логах nginx за последний час
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20

# RPS прямо сейчас
tail -f /var/log/nginx/access.log | pv -l -i 1 > /dev/null

Для постоянного мониторинга — Prometheus + Grafana или хотя бы Netdata (ставится одной командой, даёт real-time дашборд).

Автоматическая блокировка

Скрипт, который мониторит nginx-логи и банит IP с аномальным количеством запросов:

#!/bin/bash
THRESHOLD=500
LOGFILE=/var/log/nginx/access.log

tail -n 10000 $LOGFILE | \
  awk '{print $1}' | \
  sort | uniq -c | \
  awk -v t=$THRESHOLD '$1 > t {print $2}' | \
while read ip; do
  if ! iptables -C INPUT -s $ip -j DROP 2>/dev/null; then
    iptables -A INPUT -s $ip -j DROP
    echo "$(date): Blocked $ip" >> /var/log/ddos-block.log
  fi
done

Запускайте через cron каждые 5 минут. Это грубо, но работает.

Архитектурные решения

Некоторые решения надо закладывать на этапе проектирования.

Разделение сервисов

Если API и фронтенд живут на одном сервере — атака на публичный эндпоинт кладёт всё сразу. Разносите по разным инстансам. Тогда DDoS на публичный API не трогает базу данных или внутренние сервисы.

Кеширование

Значительная часть DDoS-атак на уровне приложения работает потому, что каждый запрос генерирует нагрузку на базу данных. Правильно настроенный кеш (Redis, Varnish, nginx proxy_cache) снижает нагрузку на бэкенд в разы — атака бьёт в кеш, который держит нагрузку лучше.

CAPTCHA для чувствительных эндпоинтов

Формы логина, регистрации, поиска — типичные цели для L7-атак. hCaptcha или Cloudflare Turnstile (бесплатные альтернативы Google reCAPTCHA) добавляют барьер для ботов.

Очереди для тяжёлых операций

Если у вас есть эндпоинт, который делает что-то долгое (генерирует PDF, отправляет письмо, обращается к внешнему API) — оберните его в очередь. Бот может заспамить запросами, но обработчик будет брать задачи по одной.

Что делать прямо во время атаки

Атака уже идёт, сервер лагает — план действий:

  1. Определите характер атаки. Смотрите на количество уникальных IP, географию, паттерн запросов. netstat, tcpdump, логи nginx.

  2. Включите режим «я в бункере» в Cloudflare. Under Attack Mode — все посетители проходят JS-challenge. Легитимные пользователи с задержкой 5 секунд, боты отваливаются.

  3. Заблокируйте подозрительные диапазоны IP. Если атака идёт с конкретных AS или стран — блокируйте целыми подсетями через iptables или в Cloudflare.

  4. Обратитесь к хостеру. Они могут поставить upstream-фильтрацию или перенаправить трафик через scrubbing-центр.

  5. Не платите вымогателям. Если атака сопровождается требованием денег — оплата не гарантирует остановку и помечает вас как платёжеспособную цель.

Реальный пример бюджетной защиты

Для небольшого проекта (корпоративный сайт, интернет-магазин) рабочая связка выглядит так:

  • Cloudflare бесплатный тариф — скрываем IP, базовая фильтрация
  • nginx rate limiting — 10 RPS с одного IP, бёрст 30
  • fail2ban — бан IP после 10 ошибок за 10 минут
  • sysctl — SYN cookies и увеличенный backlog
  • Netdata — мониторинг в реальном времени

Это займёт полдня на настройку и закроет 90% типовых атак. Против целенаправленной мощной атаки (100+ Гбит/с) без платного Anti-DDoS не обойтись — но такие атаки стоят денег и обычно направлены на крупные цели.

Когда мы в REEXY настраиваем серверную инфраструктуру для клиентов, именно эту связку берём за основу — и докручиваем под конкретный проект в зависимости от нагрузки и бюджета.

Чеклист базовой защиты

  • SYN cookies включены в sysctl
  • iptables ограничивает количество соединений с одного IP
  • fail2ban настроен и запущен
  • nginx rate limiting настроен для всех публичных эндпоинтов
  • Реальный IP сервера скрыт за CDN
  • Cloudflare (или аналог) подключён
  • Настроен мониторинг RPS и входящего трафика
  • Есть план действий на случай атаки

DDoS-защита — это не разовая настройка, а процесс. Атаки эволюционируют, меняются паттерны, появляются новые векторы. Раз в квартал пересматривайте настройки, следите за обновлениями fail2ban и ModSecurity, проверяйте логи на аномалии.