DDoS Attack Mitigation: Practical Response Guide
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://ipfyi.com/iframe/guide/ddos-attack-mitigation/" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://ipfyi.com/guide/ddos-attack-mitigation/
Add a dynamic SVG badge to your README or docs.
[](https://ipfyi.com/guide/ddos-attack-mitigation/)
Use the native HTML custom element.
Identify DDoS attack types, take immediate mitigation steps, implement rate limiting, use CDN protection, and apply BGP blackholing and scrubbing center techniques.
Identifying Attack Types
Before you can mitigate a DDoS attack, you must identify what kind of attack you are facing. Different attacks require fundamentally different responses.
Volumetric attacks overwhelm your bandwidth capacity:
| Attack | Layer | Amplification | Peak Sizes |
|---|---|---|---|
| UDP flood | L3/L4 | 1x | 100+ Gbps |
| DNS amplification | L3/L4 | 50-60x | 600+ Gbps |
| NTP amplification | L3/L4 | 556x | 400+ Gbps |
| SSDP amplification | L3/L4 | 30x | 100+ Gbps |
| Memcached (CVE-2018-1000115) | L3/L4 | 51,000x | 1.7 Tbps (Akamai 2018 record) |
Protocol attacks exhaust server state:
| Attack | Layer | Target |
|---|---|---|
| SYN flood | L4 | TCP connection table |
| ACK flood | L4 | Firewall state table |
| Fragmented packet flood | L3/L4 | IP reassembly buffers |
| Ping of death | L3 | OS kernel (historical) |
Application layer attacks exhaust server resources:
| Attack | Layer | Target |
|---|---|---|
| HTTP flood | L7 | Web server CPU/memory |
| Slowloris | L7 | HTTP connections (slow headers) |
| RUDY | L7 | HTTP connections (slow POST) |
| DNS query flood | L7 | DNS resolver CPU |
| TLS exhaustion | L6 | SSL handshake CPU |
Rapid identification:
# Check network traffic volume (is it volumetric?)
# On the server:
ifstat -i eth0 1 10 # Network throughput per second
sar -n DEV 1 10 # More detailed
# Check connection state (is it protocol-level?)
ss -s # Socket statistics summary
# Look for: many SYN_RECV = SYN flood
# Many TIME_WAIT = ACK flood or connection exhaustion
# Check application layer (is it HTTP flood?)
sudo tail -f /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20
# Look for a single IP or small set of IPs making thousands of requests
Immediate Response Steps
The first 15 minutes of an attack determine whether you survive it or not.
# Step 1: Confirm it is an attack, not organic traffic
# Check traffic volume vs. normal baseline
netstat -i
cat /proc/net/dev # Raw interface stats
# Step 2: Identify the attack source(s)
sudo tcpdump -i eth0 -n -c 1000 -w /tmp/attack.pcap
tcpdump -r /tmp/attack.pcap -n 'ip' | awk '{print $3}' | sort | uniq -c | sort -rn | head -20
# Step 3: Null route the most abusive IPs immediately
# Linux: black hole a specific IP (traffic accepted but discarded)
sudo ip route add blackhole 192.0.2.100/32
# Null route multiple IPs from a list
while read ip; do
sudo ip route add blackhole "$ip/32"
done < /tmp/attack_ips.txt
# Step 4: Apply temporary rate limiting to buy time
sudo iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j DROP
sudo iptables -I INPUT -p tcp --dport 80 -m limit --limit 1000/second --limit-burst 2000 -j ACCEPT
sudo iptables -I INPUT -p tcp --dport 80 -j DROP
# Step 5: Contact your hosting provider / upstream
# They can apply upstream ACLs or activate scrubbing at their edge
# Have your ASN, IP range, and traffic type ready
SYN flood specific:
# Enable SYN cookies (absorbs SYN floods without state table exhaustion)
sudo sysctl -w net.ipv4.tcp_syncookies=1
# Increase the SYN backlog queue
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=4096
# Reduce SYN-ACK retries (drop half-open connections faster)
sudo sysctl -w net.ipv4.tcp_synack_retries=2
# Make permanent in /etc/sysctl.conf
echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_max_syn_backlog = 4096" >> /etc/sysctl.conf
Rate Limiting and Filtering
Rate limiting reduces the impact of application layer attacks without blocking legitimate users.
Nginx rate limiting:
# /etc/nginx/nginx.conf — define rate limit zones
http {
# Limit requests per IP: 10 requests per second
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
# Limit concurrent connections per IP
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
# Apply rate limit: allow bursts of 20 before enforcing limit
limit_req zone=api burst=20 nodelay;
# Limit to 20 simultaneous connections per IP
limit_conn conn_limit 20;
# Return 429 (Too Many Requests) instead of 503
limit_req_status 429;
limit_conn_status 429;
}
}
iptables rate limiting (L4):
# Limit new TCP connections to 25 per second per IP
sudo iptables -I INPUT -p tcp --dport 80 -m state --state NEW \
-m recent --set --name HTTP_NEW
sudo iptables -I INPUT -p tcp --dport 80 -m state --state NEW \
-m recent --update --seconds 1 --hitcount 25 --name HTTP_NEW -j DROP
# Block IPs making more than 100 connections
sudo iptables -I INPUT -p tcp --dport 80 \
-m connlimit --connlimit-above 100 -j REJECT --reject-with tcp-reset
# Rate limit ICMP flood
sudo iptables -I INPUT -p icmp --icmp-type echo-request \
-m limit --limit 10/second --limit-burst 20 -j ACCEPT
sudo iptables -I INPUT -p icmp --icmp-type echo-request -j DROP
Geo-blocking (when attack is regionally concentrated):
# Install geoip module
sudo apt install xtables-addons-common libnet-cidr-lite-perl
# Block a country (use ISO 3166-1 alpha-2 code)
sudo iptables -I INPUT -m geoip --src-cc CN -j DROP
CDN-Based Protection
A CDN placed in front of your origin server absorbs volumetric attacks at the edge, before traffic reaches your infrastructure.
Cloudflare (most widely used):
# After proxying through Cloudflare:
# 1. Enable "I'm Under Attack" mode (IUAM) immediately
# Cloudflare Dashboard → Security → Settings → Security Level → "I'm Under Attack"
# This presents a JavaScript challenge to all visitors
# 2. Create firewall rules to block attack patterns
# Cloudflare Dashboard → Security → WAF → Custom Rules
# Example: Block requests with empty User-Agent
# (http.user_agent eq "")
# 3. Rate limiting rules
# Security → Rate Limiting → Create Rule
# Match: URI path = /api/*
# Requests: >100 per 10 seconds
# Action: Block for 1 hour
# 4. Lock down origin to only accept Cloudflare IPs
# This prevents attackers from bypassing Cloudflare by hitting origin directly
# Cloudflare IP ranges: https://www.cloudflare.com/ips/
# iptables rule to only allow Cloudflare
for ip in $(curl -s https://www.cloudflare.com/ips-v4); do
sudo iptables -I INPUT -p tcp --dport 80 -s "$ip" -j ACCEPT
sudo iptables -I INPUT -p tcp --dport 443 -s "$ip" -j ACCEPT
done
sudo iptables -A INPUT -p tcp --dport 80 -j DROP
sudo iptables -A INPUT -p tcp --dport 443 -j DROP
AWS Shield Standard and Advanced:
AWS Shield Standard is automatically included with all AWS accounts and protects against L3/L4 volumetric attacks. Shield Advanced adds L7 protection and 24/7 DDoS response team access.
# Enable AWS WAF rate limiting (if on ALB or CloudFront)
aws wafv2 create-rate-based-rule \
--scope REGIONAL \
--name RateLimitRule \
--metric-name RateLimitRule \
--rate-key IP \
--rate-limit 2000 \
--action '{"Block":{}}'
BGP Blackholing
BGP blackholing (RTBH — Remotely Triggered Black Hole) is an upstream filtering technique where you advertise a /32 route tagged with a specific BGP community that causes upstream routers to drop all traffic to that destination IP.
How it works:
- You announce a /32 prefix (your attacked IP) to your upstream provider.
- You tag it with the provider's blackhole community (e.g.,
65535:666for many providers, or provider-specific). - The upstream router adds a null route for that /32 — traffic is dropped at the upstream, before reaching your bandwidth.
# Cisco IOS: announce a blackhole route with community
router bgp 65001
network 192.0.2.100 mask 255.255.255.255 route-map BLACKHOLE-TAG
route-map BLACKHOLE-TAG permit 10
set community 65535:666 additive
# Null route the host locally
ip route 192.0.2.100 255.255.255.255 Null0
# Different providers use different blackhole communities:
# Hurricane Electric: 6939:666
# Telia: 1299:7 (S-RTBH) or 1299:666
# Cogent: 174:666
# Most providers document these in their IRR records or NOC pages
Destination blackholing vs. source blackholing (SRTBH):
- Destination blackholing — Drops all traffic TO your IP. Stops the attack but also blocks legitimate users. Use as a last resort.
- Source blackholing (SRTBH) — Drops traffic FROM specific source IPs. Requires knowing the source and your provider supporting it. More surgical.
Scrubbing Centers
Scrubbing centers are specialized facilities that receive your traffic, filter out attack traffic, and forward clean traffic to your server.
Commercial scrubbing services:
| Provider | Capacity | Approach |
|---|---|---|
| Cloudflare Magic Transit | 100+ Tbps edge | BGP advertisement + anycast |
| Akamai Prolexic | 20 Tbps | BGP diversion to scrubbing centers |
| Radware | Multiple Tbps | On-premise + cloud hybrid |
| Lumen (CenturyLink) | 2+ Tbps | Carrier-level scrubbing |
How scrubbing works:
- During an attack, you re-announce your IP prefix via BGP to point to the scrubbing center.
- Attack traffic (volumetric) hits the scrubbing center's massive ingress capacity.
- The scrubbing center applies stateful inspection and filters attack packets.
- Clean traffic is forwarded to your actual servers via a GRE tunnel or MPLS circuit.
- After the attack ends, you revert the BGP announcement to resume normal routing.
# GRE tunnel from scrubbing center to your server (typical setup)
# On your server (the "clean" traffic destination):
sudo ip tunnel add gre1 mode gre remote SCRUBBING_CENTER_IP local YOUR_SERVER_IP ttl 255
sudo ip link set gre1 up
sudo ip addr add YOUR_ATTACKED_IP/32 dev gre1
sudo ip route add SCRUBBING_CENTER_IP via YOUR_GATEWAY
Post-Incident Analysis
After the attack ends, a structured analysis prevents recurrence and improves future response time.
Attack characterization:
# Analyze the pcap captured during the attack
tcpdump -r /tmp/attack.pcap -n | \
awk '{print $3}' | \
cut -d. -f1-4 | \
sort | uniq -c | sort -rn > /tmp/source_ips.txt
# Summarize by /24 (likely botnet source distribution)
cat /tmp/source_ips.txt | \
awk '{print $2}' | \
cut -d. -f1-3 | \
sort | uniq -c | sort -rn | head -20
# Peak traffic volume
# Check your bandwidth graphs in your monitoring system
# Grafana, Netdata, Zabbix, CloudWatch
# Check server logs for application-layer attack signatures
grep "HTTP/1" /var/log/nginx/access.log | \
awk '{print $1, $7}' | \ # IP and URL
sort | uniq -c | sort -rn | head -50
Post-incident checklist:
- Document attack start/end time, peak volume, attack type.
- Record what mitigations were applied and in what order.
- Calculate time-to-mitigate and time-to-recovery.
- Identify gaps: Were monitoring alerts timely? Was the runbook clear?
- Update runbooks with what worked and what did not.
- Implement permanent controls based on attack patterns:
- Add WAF rules for HTTP patterns seen in attack traffic
- Increase scrubbing subscription tier if overwhelmed
- Pre-negotiate blackhole communities with upstreams
- Configure auto-trigger for future attacks (BGP communities on threshold)
Metrics to track:
| Metric | Target |
|---|---|
| Time to detect | < 5 minutes |
| Time to triage | < 15 minutes |
| Time to mitigate L3/L4 | < 30 minutes |
| Time to mitigate L7 | < 1 hour |
| False positive rate on blocks | < 1% of legitimate users |