MHOSTMHOST

Как защитить VPS от DDoS-атак: пошаговое руководство с Cloudflare

DDoS-атака перегружает сервер потоком запросов или трафика, и сайт перестаёт отвечать. Бесплатный Cloudflare в связке с правильной настройкой VPS отсекает большую часть таких атак на сайты.

В руководстве семь шагов: подключаем Cloudflare, прячем реальный IP, закрываем сервер от прямого доступа и настраиваем Nginx и ядро Linux. Команды подходят для Ubuntu/Debian и Nginx.

Атаки бывают двух типов, и защищаются от них по-разному:

  • L3/L4 (сетевые) забивают канал или стек TCP, например SYN flood и UDP flood. Защита — Cloudflare со скрытым IP, иначе фильтрация у хостинга.
  • L7 (прикладные) имитируют посетителей и грузят приложение, например HTTP flood или перебор страниц поиска. Защита — WAF и rate limiting в Cloudflare, лимиты Nginx.

Шаг 1. Подключите домен к Cloudflare

После подключения весь трафик сайта идёт через сеть Cloudflare, и атака упирается в неё, а не в ваш VPS.

  1. Зарегистрируйтесь на cloudflare.com и нажмите Add a domain. Выберите тариф Free.
  2. Cloudflare импортирует DNS-записи. Сверьте их с текущими у регистратора: A, AAAA, CNAME, MX, TXT.
  3. Для записей сайта (@, www) включите оранжевое облако — статус Proxied. Серое облако (DNS only) трафик не защищает.
  4. У регистратора домена замените NS-серверы на два адреса, которые выдал Cloudflare.
  5. Дождитесь статуса Active. Обычно это занимает от 15 минут до нескольких часов.

Проверка: dig +short example.com должен вернуть IP Cloudflare, а не IP вашего сервера.


Шаг 2. Настройте защиту в Cloudflare

Базовая защита от DDoS в Cloudflare включена всегда, но без настройки WAF и лимитов L7-атаки частично проходят к серверу.

SSL/TLS

  • Режим шифрования — Full (strict). Режим Flexible оставляет трафик до сервера незашифрованным.
  • В Origin Server создайте Origin Certificate (до 15 лет) и установите его в Nginx.
  • Включите Always Use HTTPS.

Security → Settings

  • Bot Fight Mode — включить. Блокирует простых ботов.
  • Security Level — Medium. Во время атаки — High.
  • Browser Integrity Check — включить.

WAF → Custom rules (на Free доступно 5 правил). Примеры выражений:

  • Защитить вход в админку (действие Managed Challenge): (http.request.uri.path contains "/wp-login.php") or (http.request.uri.path contains "/wp-admin")
  • Отсечь страны без вашей аудитории (Managed Challenge): (not ip.src.country in {"UA" "PL" "DE"})
  • Закрыть XML-RPC (Block): (http.request.uri.path eq "/xmlrpc.php")

WAF → Rate limiting rules (на Free — 1 правило). Пример: запросы к / с одного IP больше 100 за 10 секунд → Block на 10 секунд. Порог подберите по аналитике, чтобы не резать обычных посетителей.

Caching — чем больше страниц отдаёт кеш Cloudflare, тем меньше запросов доходит до VPS. Включите кеширование статики и настройте Cache Rules для страниц, которые не зависят от пользователя.

Шаг 3. Скройте реальный IP сервера

Если атакующий знает IP вашего VPS, он бьёт напрямую, в обход Cloudflare. Это самая частая причина, по которой защита «не работает».

Где обычно утекает IP:

  • Старые DNS-записи. Сервисы истории DNS хранят IP, на который домен смотрел до Cloudflare. Если сайт раньше работал без прокси, попросите у хостера новый IP.
  • Поддомены с серым облаком. mail, ftp, cpanel, dev часто указывают на тот же сервер. Проксируйте их или вынесите на другой IP.
  • Почта. MX-запись и заголовки писем раскрывают IP отправителя. Отправляйте почту через внешний сервис (SMTP-релей) или с отдельного сервера.
  • Исходящие запросы. Вебхуки, pingback в WordPress, загрузка картинок по URL — сервер сам показывает свой IP чужим сайтам.
  • Ответ по прямому IP. Сканеры обходят весь интернет и находят сайт по IP и SSL-сертификату. Как закрыть — в шагах 4 и 5.

Проверка: curl -I http://IP_СЕРВЕРА с другой машины не должен возвращать ваш сайт.

Шаг 4. Пускайте на 80/443 только Cloudflare

Порты сайта должны принимать соединения только с адресов Cloudflare. Тогда бот, узнавший IP, не достучится до Nginx.

Сначала разрешите SSH, иначе потеряете доступ. Лучше — только со своего IP:

ufw allow from ВАШ_IP to any port 22 proto tcp
ufw default deny incoming
ufw default allow outgoing

Затем откройте 80 и 443 для диапазонов Cloudflare. Актуальные списки лежат по адресам https://www.cloudflare.com/ips-v4 и https://www.cloudflare.com/ips-v6:

for ip in $(curl -s https://www.cloudflare.com/ips-v4) $(curl -s https://www.cloudflare.com/ips-v6); do
ufw allow proto tcp from $ip to any port 80,443 comment 'Cloudflare'
done
ufw enable
ufw status numbered

Важно:

  • Диапазоны Cloudflare иногда меняются. Раз в месяц сверяйте их, например скриптом в cron.
  • Docker публикует порты в обход UFW. Если сайт в контейнере, привязывайте порт к 127.0.0.1 и проксируйте через Nginx на хосте.
  • Для строгой защиты включите в Cloudflare Authenticated Origin Pulls. Тогда Nginx примет только запросы с клиентским сертификатом Cloudflare.

Шаг 5. Настройте Nginx

Nginx — последний рубеж для L7-атак, которые прошли Cloudflare. Настраиваем три вещи: реальный IP посетителя, лимиты и заглушку для прямых запросов по IP.

Реальный IP посетителя. Без этого Nginx видит только адреса Cloudflare, и лимиты по IP бесполезны. Сгенерируйте конфиг:

{
for ip in $(curl -s https://www.cloudflare.com/ips-v4) $(curl -s https://www.cloudflare.com/ips-v6); do
echo "set_real_ip_from $ip;"
done
echo "real_ip_header CF-Connecting-IP;"
} > /etc/nginx/conf.d/cloudflare-realip.conf

Лимиты запросов и соединений. В блок http (/etc/nginx/nginx.conf):

limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
limit_req_status 429;
limit_conn_status 429;

client_header_timeout 10s;
client_body_timeout 10s;
send_timeout 10s;
keepalive_timeout 15s;
client_max_body_size 10m;

В блок server вашего сайта:

limit_req zone=req_limit burst=20 nodelay;
limit_conn conn_limit 20;

10 запросов в секунду с всплеском до 20 подходят обычному сайту. Для API или SPA с частыми запросами поднимите rate и burst.

Заглушка для запросов по IP. Сервер по умолчанию закрывает соединение, если запрос пришёл не на ваш домен:

server {
listen 80 default_server;
listen 443 ssl default_server;
ssl_reject_handshake on; # Nginx 1.19.4+
server_name _;
return 444;
}

Проверьте и примените: nginx -t && systemctl reload nginx.

Шаг 6. Укрепите ядро и подключите fail2ban

Сетевые параметры ядра. Защищают от SYN flood и подмены адресов. Создайте /etc/sysctl.d/99-ddos.conf:

net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_fin_timeout = 15
net.core.somaxconn = 4096
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

Примените: sysctl --system.

fail2ban. Есть нюанс: за Cloudflare все пакеты приходят с IP Cloudflare. Бан через iptables на сервере не остановит злоумышленника. Поэтому для сайта используйте действие cloudflare-token — оно блокирует IP на стороне Cloudflare через API.

apt install fail2ban

Создайте API-токен в Cloudflare с правами Zone → Firewall Services → Edit и добавьте в /etc/fail2ban/jail.local:

[sshd]
enabled = true
maxretry = 5
bantime = 1h

[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
findtime = 60
maxretry = 10
bantime = 1h

action = cloudflare-token[cfzone="ID_ЗОНЫ", cftoken="API_ТОКЕН"]

Перезапустите: systemctl restart fail2ban, проверьте: fail2ban-client status nginx-limit-req. Для SSH остаётся обычный бан через iptables — он идёт мимо Cloudflare.

Шаг 7. Что делать, если атака уже идёт

Первое действие — включить Under Attack Mode. Остальное — по результатам диагностики.

  1. Включите Under Attack Mode (Overview → Quick Actions). Каждый посетитель проходит JS-проверку, боты отсеиваются. Включайте только на время атаки: режим мешает поисковым роботам и API.
  2. Определите, куда идёт трафик. Посмотрите Security → Events и Analytics в Cloudflare. Если там всплеск — атака идёт через Cloudflare. Если там тихо, а сервер лежит — атакуют IP напрямую.
  3. Проверьте нагрузку на сервере:
    # соединения по состояниям: много SYN-RECV = SYN flood
    ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -nr

    # топ IP по запросам в логе Nginx
    awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20

    # топ URL — что именно атакуют
    awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20
  4. Заблокируйте источник в Cloudflare. Custom rule по пути, User-Agent, стране или ASN из логов. Для подозрительных ASN ставьте Managed Challenge, а не Block.
  5. Разгрузите приложение. Закешируйте атакуемые страницы через Cache Rules, временно отключите тяжёлый поиск и фильтры.
  6. Если атакуют IP напрямую — Cloudflare тут не поможет. Напишите в поддержку хостинга: нужна фильтрация на уровне сети или смена IP. После смены проверьте утечки из шага 3.

Где Cloudflare не поможет

Бесплатный Cloudflare защищает только веб-трафик по HTTP/HTTPS. Всё остальное на сервере остаётся открытым для атак.

  • Игровой сервер, VPN, другие TCP/UDP-сервисы. Free-тариф проксирует только HTTP/HTTPS. Нужна защита на уровне сети хостинга или платный Cloudflare Spectrum.
  • IP сервера уже известен. Атака идёт напрямую, мимо Cloudflare. Нужны смена IP и фильтрация у хостинга.
  • Объёмная атака на IP. Канал забит раньше, чем трафик дойдёт до firewall VPS. Спасает только фильтрация до сервера.
  • Почта, SSH, панели управления. Они не проксируются. Вынесите их на отдельный IP и откройте доступ по белому списку.

Настройки внутри VPS помогают против L7-атак и небольших флудов. От атаки в десятки гигабит, которая забивает канал, защищает только фильтрация на стороне дата-центра.

Чек-лист



Частые вопросы

Хватит ли бесплатного Cloudflare для защиты от DDoS? Для большинства сайтов — да, если скрыт реальный IP и настроены WAF и лимиты. Не хватит для сервисов не на HTTP и при утечке IP.

Замедлит ли Cloudflare сайт? Обычно нет. Кеш и CDN чаще ускоряют загрузку. Замедляет только Under Attack Mode — из-за проверки браузера на несколько секунд.

Можно ли защитить игровой сервер через Cloudflare? На бесплатном тарифе — нет, он проксирует только HTTP/HTTPS. Нужна защита на уровне сети хостинга или Cloudflare Spectrum.

Как понять, что сервер под DDoS-атакой? Сайт тормозит или недоступен, растут нагрузка CPU и число соединений, в логах много однотипных запросов. Команды для диагностики — в шаге 7.

Почему после подключения Cloudflare сервер всё равно падает? Скорее всего, атакуют IP напрямую. Проверьте утечки по шагу 3 и закройте порты по шагу 4.