До основного вмісту

Захист від DDoS-атак: Nginx, Cloudflare і системні заходи

Безпека · 19.04.2026 · 4 хв читання
Ілюстрація до статті «Захист від DDoS-атак: Nginx, Cloudflare і системні заходи»

DDoS-атаки (Distributed Denial of Service) перевантажують сервер величезною кількістю запитів, роблячи його недоступним для звичайних відвідувачів. Ефективний захист будується на кількох рівнях: мережевий (Cloudflare/CDN), системний (sysctl) і рівень застосунку (Nginx) — жоден шар поодинці не закриває всі сценарії атаки.

Рівень 1: Cloudflare DDoS Protection (рекомендується)

Cloudflare поглинає DDoS-трафік до досягнення вашого сервера, бо весь трафік іде через її мережу точок присутності:

  • Увімкнути Proxy (помаранчева хмара) для DNS-записів A і CNAME — без цього Cloudflare бачить лише DNS-запити, а сам трафік іде напряму на сервер.
  • Security → DDoS → увімкнути HTTP DDoS Attack Protection.
  • Security → WAF → увімкнути Managed Rules.
  • Security Level: High під час атаки, Medium у звичайному режимі.

Рівень 2: Nginx — обмеження з'єднань (на додачу до UFW Firewall)

http {
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=50r/s;

    server {
        limit_conn conn_limit 20;      # Макс 20 з'єднань з одного IP
        limit_req zone=req_limit burst=100 nodelay;
        limit_req_status 429;

        # Тайм-аути для захисту від Slowloris
        client_body_timeout 10;
        client_header_timeout 10;
        keepalive_timeout 5;
        send_timeout 10;
    }
}

Рівень 3: Системна оптимізація (sysctl)

# /etc/sysctl.d/99-ddos-protect.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 5
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.conf.all.rp_filter = 1

sysctl --system

Розбір сигналів атаки в логах

  • 499 у логі Nginx — клієнт обірвав з'єднання, не дочекавшись відповіді; масовий сплеск 499 свідчить про SYN-флуд або переповнену чергу воркерів, а не про повільний застосунок.
  • upstream timed out (110: Connection timed out) — під час атаки рівня застосунку (L7) воркери PHP-FPM зайняті обробкою підроблених запитів і не встигають відповідати реальним користувачам.
  • too many open files у dmesg або логі Nginx — вичерпано ліміт файлових дескрипторів через тисячі одночасних з'єднань; тимчасовий захід — підняти ulimit -n, але це не усуває саму атаку.
  • Resource temporarily unavailable (11: Resource temporarily unavailable) при accept() — черга нових з'єднань переповнена, сервер фізично не встигає приймати нові сокети швидше, ніж їх створює атакувальник.

Реагування на атаку

netstat -tn | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head -20
ss -s

# Швидко заблокувати атакувальний IP
iptables -I INPUT -s ATTACK_IP -j DROP

# Увімкнути режим "Under Attack" у Cloudflare
# Security → Settings → Security Level: I'm Under Attack

Приховування IP за Cloudflare: переконайтеся, що реальний IP сервера не розкривається через DNS-історію, email-заголовки чи інші канали. Cloudflare ефективний лише доки атакувальник не знає реальний IP і не може обстрілювати його напряму, минаючи захист.

Порівняння рівнів захисту

РівеньВід чого захищаєДе налаштовуєтьсяЧи потребує перезавантаження сервера
CloudflareОбʼємні (L3/L4) і частина L7-атакДашборд CloudflareНі
NginxL7: флуд запитами до одного URLКонфіг віртуального хостаНі (reload)
sysctlL4: SYN-флуд, вичерпання сокетівЯдро ОСНі (sysctl --system)

Коли цього набору заходів недостатньо

  • Атака йде напряму на IP сервера, минаючи Cloudflare, — якщо IP витік раніше, DNS-проксування не врятує; потрібно змінювати IP і тримати його в таємниці, або переносити сервер у захищену мережу провайдера.
  • Атака обсягом у сотні гігабіт за секунду — канал самого сервера фізично не пропустить такий трафік навіть з ідеальними правилами Nginx; тут вирішує лише upstream-фільтрація на боці провайдера чи CDN.
  • Атака імітує реальних користувачів через ротацію residential-проксі — простий ліміт за IP не відрізнить їх від живих людей; потрібні поведінкові правила WAF і капча на підозрілих сесіях.

Як перевірити, що захист працює

# Дивимося, що запити справді доходять до Cloudflare, а не в обхід
dig +short example.com
# Очікуємо IP з діапазонів Cloudflare, а не IP вашого сервера

# Перевіряємо спрацювання rate limit на самому Nginx
for i in $(seq 1 60); do curl -o /dev/null -s -w "%{http_code}\n" https://example.com/; done | sort | uniq -c

# Перевіряємо, що параметри sysctl застосувалися
sysctl net.ipv4.tcp_syncookies

Якщо DNS віддає IP з діапазону Cloudflare, частина запитів під час навантажувального тесту повертає 429, а параметри sysctl показують виставлені значення — усі три рівні захисту працюють узгоджено.

Чи була стаття корисною?
← Назад до бази знань Поставити питання підтримці