A DDoS (Distributed Denial of Service) attack floods a target with traffic from thousands of IPs in a botnet. The largest recorded attack in 2025 hit 3.8 Tbps — 500x what a single server can absorb. Effective protection is layered: CDN, WAF, network, application.

DDoS Attack Types

Volumetric (L3/L4) — Bandwidth Attacks

UDP flood, ICMP flood, SYN flood, DNS amplification — the attacker fills your bandwidth. At 100+ Gbps a single server is helpless; upstream filtering (ISP/CDN) is mandatory.

Protocol (L4) — Resource Exhaustion

SYN flood exhausts half-open TCP connections. Slowloris sends HTTP headers slowly to tie up connection slots. Nginx runs out of worker_connections and refuses new requests.

Application (L7) — The Hardest

HTTP flood — requests that look legitimate. An unthrottled /search endpoint that suddenly receives 1000 requests per second will crash the database. Firewalls cannot distinguish legit traffic; WAF and rate limits at the application layer are required.

Layer 1: DNS/CDN (Cloudflare, Fastly, Akamai)

The first line of defence — point DNS at a CDN and hide your server IP. The CDN acts as a proxy and filters L3/L4 floods at the edge. Even Cloudflare's free plan includes unlimited DDoS mitigation.

  • Cloudflare Proxy (orange cloud) must be on
  • The origin IP must not be publicly visible — watch subdomains like mail and API
  • "Under Attack Mode" — JS challenge during a suspected attack
  • Rate Limiting Rules — per URL
  • Bot Fight Mode — blocks scraping
# Allow only Cloudflare IPs
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
    ufw allow from $ip to any port 443 proto tcp
done
ufw deny 443/tcp  # everything else is blocked

Layer 2: Nginx Rate Limiting

Covered in detail in the earlier Nginx article. Essentials: per-IP caps, endpoint-specific caps (login 2r/s, api 5r/s, global 15r/s) and connection limits.

limit_req_zone $binary_remote_addr zone=global:10m rate=15r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=5r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    limit_conn addr 50;
    limit_req zone=global burst=30 nodelay;

    # Slowloris protection
    client_body_timeout 10s;
    client_header_timeout 10s;

    location /api/ {
        limit_req zone=api burst=10 nodelay;
        proxy_pass http://backend;
    }
}

Layer 3: Application Level

Use libraries such as express-rate-limit or Flask-Limiter to add endpoint- and user-level rate limits (after authentication). Protect heavy endpoints (report generation, mail sending) in particular.

const rateLimit = require('express-rate-limit');

// Global
app.use(rateLimit({ windowMs: 60000, max: 120 }));

// Sensitive
app.use('/login', rateLimit({
    windowMs: 900000, max: 5,
    message: 'Too many login attempts. Try again in 15 minutes.'
}));

// Per-user after auth
app.use('/api/export', rateLimit({
    windowMs: 3600000, max: 10,
    keyGenerator: req => req.user.id
}));

Layer 4: Fail2ban + iptables

Fail2ban reads logs and bans attackers; we covered it in its own article. For DDoS, set up custom jails that catch 4xx/5xx floods in the Nginx access log.

Layer 5: OS-Level Hardening

# /etc/sysctl.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.core.netdev_max_backlog = 5000
net.ipv4.ip_local_port_range = 10000 65535

# Apply
sudo sysctl -p

Monitoring and Alerting

Catching a DDoS early is critical. Build a real-time pipeline on the Nginx access log with GoAccess, Grafana Loki or Datadog, and watch these metrics:

  • Requests per second (5x baseline triggers an alert)
  • Unique IPs (10x baseline is suspicious)
  • 4xx/5xx ratio (above 30% is worth investigating)
  • TCP connection count
  • Bandwidth usage

Preparedness Plan

  • Write a runbook — what to do during an attack
  • Keep a Cloudflare API token ready to flip Under Attack Mode in 5 seconds
  • Have geo-block rules prepared for blocking specific countries if needed
  • Plan failover — backup datacenter or DNS records
  • Know your ISP contact for upstream null routing

Conclusion

You do not "stop" a DDoS — you absorb it. The right architecture: Cloudflare absorbs brute force at the edge, Nginx rate limits catch legit-looking L7 traffic, and the application layer is the final line. Every layer must be independent; if one fails the others pick up. KEYDAL helps teams design exactly this kind of multi-layer defence.

Build a DDoS protection architecture

Cloudflare setup, Nginx hardening, monitoring and runbook design Contact us

WhatsApp