Как защитить 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.
- Зарегистрируйтесь на cloudflare.com и нажмите Add a domain. Выберите тариф Free.
- Cloudflare импортирует DNS-записи. Сверьте их с текущими у регистратора: A, AAAA, CNAME, MX, TXT.
- Для записей сайта (
@,www) включите оранжевое облако — статус Proxied. Серое облако (DNS only) трафик не защищает. - У регистратора домена замените NS-серверы на два адреса, которые выдал Cloudflare.
- Дождитесь статуса 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 incomingufw 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 enableufw 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 = 1net.ipv4.tcp_max_syn_backlog = 4096net.ipv4.tcp_synack_retries = 2net.ipv4.tcp_fin_timeout = 15net.core.somaxconn = 4096net.ipv4.conf.all.rp_filter = 1net.ipv4.conf.default.rp_filter = 1net.ipv4.icmp_echo_ignore_broadcasts = 1net.ipv4.conf.all.accept_redirects = 0net.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 = truemaxretry = 5bantime = 1h[nginx-limit-req]enabled = truefilter = nginx-limit-reqlogpath = /var/log/nginx/error.logfindtime = 60maxretry = 10bantime = 1haction = cloudflare-token[cfzone="ID_ЗОНЫ", cftoken="API_ТОКЕН"]
Перезапустите: systemctl restart fail2ban, проверьте: fail2ban-client status nginx-limit-req. Для SSH остаётся обычный бан через iptables — он идёт мимо Cloudflare.
Шаг 7. Что делать, если атака уже идёт
Первое действие — включить Under Attack Mode. Остальное — по результатам диагностики.
- Включите Under Attack Mode (Overview → Quick Actions). Каждый посетитель проходит JS-проверку, боты отсеиваются. Включайте только на время атаки: режим мешает поисковым роботам и API.
- Определите, куда идёт трафик. Посмотрите Security → Events и Analytics в Cloudflare. Если там всплеск — атака идёт через Cloudflare. Если там тихо, а сервер лежит — атакуют IP напрямую.
- Проверьте нагрузку на сервере:
# соединения по состояниям: много SYN-RECV = SYN floodss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -nr
# топ IP по запросам в логе Nginxawk '{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 - Заблокируйте источник в Cloudflare. Custom rule по пути, User-Agent, стране или ASN из логов. Для подозрительных ASN ставьте Managed Challenge, а не Block.
- Разгрузите приложение. Закешируйте атакуемые страницы через Cache Rules, временно отключите тяжёлый поиск и фильтры.
- Если атакуют 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.