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.
Cloudflare setup, Nginx hardening, monitoring and runbook design Contact us