54. DDoS shapes and mitigations
54.1 The three layers of DDoS
| Layer | Examples | Measured in | Goal |
|---|---|---|---|
| Volumetric (L3/4) | UDP/ICMP flood, amplification/reflection (DNS, NTP, memcached, CLDAP, SSDP), carpet bombing | bits/s (Gbps–Tbps) | saturate the pipe / transit |
| Protocol / state exhaustion (L3/4) | SYN flood, ACK flood, RST flood, fragmented-packet flood, nf_conntrack exhaustion, TLS renegotiation |
packets/s, connections/s, table entries | exhaust CPU, NIC pps, firewall/LB state |
| Application (L7) | HTTP(S) request flood, "cache-busting" random query strings, expensive-endpoint targeting (search, login, GraphQL), Slowloris, HTTP/2 Rapid Reset (CVE-2023-44487) | requests/s, concurrency | exhaust app workers, DB, downstream APIs |
54.2 Volumetric mitigation
- You cannot absorb a 1 Tbps flood on a 10 Gbps uplink. Mitigation has to happen upstream / in the cloud: an anycast scrubbing network (Ch. 50) spreads the attack across hundreds of Tbps of global capacity, filters, and forwards clean traffic (via GRE/L2 tunnel or by being your CDN/proxy).
- BGP tools: RTBH (Remotely Triggered Black Hole — announce the victim
/32with a blackhole community so transit drops all its traffic; the target goes fully dark but the rest of your network survives) and Flowspec (push fine-grained drop/rate-limit filters — "drop UDP/53 responses > 1400 bytes to this /24" — into upstream routers). - Kill amplification at the source: BCP 38 everywhere; no open resolvers;
disable NTP
monlist; keep memcached off UDP and off the internet. - On your edge: XDP/eBPF drop of obvious junk (spoofed ranges, malformed, disallowed protocols) at line rate before the stack; drop IP fragments if your services don't need them.
54.3 Protocol/state mitigation
- SYN cookies + SYN proxy + large backlogs (Ch. 52).
- Drop
INVALID(Ch. 53); rate-limitNEWper source; raisenf_conntrack_maxorNOTRACKstateless services. - NIC/pps: RSS across all queues, XDP filtering, hardware flow steering; ensure you're not single-CPU-softirq-bound (Ch. 48).
- Fragmentation floods:
net.ipv4.ipfrag_high_thresh, or drop fragments at XDP.
54.4 Application-layer mitigation
- Rate limiting: per-IP, per-token/API-key, per-URL, sliding-window or token- bucket, at the edge proxy/WAF/CDN. Careful with shared NAT/CGNAT IPs — prefer keying on auth identity or a proof-of-work/JS challenge for anonymous traffic.
- Caching: serve as much as possible from cache so the origin never sees the flood; defeat cache-buster query strings by normalizing/ignoring unknown params.
- Challenge: JS challenge, CAPTCHA, Proof-of-Work, or cryptographic attestation (Privacy Pass) for suspicious clients; keep good clients on a fast path.
- Concurrency & timeouts: per-connection request timeouts (Slowloris), request/second and in-flight caps per connection, cap HTTP/2 concurrent streams and RST_STREAM rate (Rapid Reset), body-size and header-count limits.
- Load shedding & prioritization: when overloaded, shed anonymous/low-value
traffic first (return cheap 429/503 with
Retry-After), protect logged-in users and health checks; circuit-break to downstreams so the DB isn't dragged down. - Autoscaling is a cost amplifier if it scales into the attack — cap it and combine with shedding.
54.5 Anti-amplification in protocols you operate
- DNS: Response Rate Limiting (RRL),
minimal-responses, refuseANY/ returnHINFO(RFC 8482), disable recursion for the internet, EDNS buffer 1232. - QUIC: the 3× amplification limit and address validation via Retry tokens (built into the protocol — make sure your library enforces it).
- NTP/SNMP/SSDP/memcached/CLDAP: don't expose to the internet; if you must, disable the amplifying query types.
54.6 Preparation checklist (the real mitigation)
- Contract/enable an upstream scrubbing/CDN provider before an attack; know how to trigger it (BGP swing, DNS change, always-on).
- Know your numbers: uplink Gbps, edge pps ceiling, LB conn-table size, app RPS capacity, DB QPS ceiling.
- Have RTBH and Flowspec procedures with your transit providers, tested.
- Dashboards + alerts on: inbound bps/pps by protocol, SYN rate, conntrack
count,
ListenDrops, 5xx/429 rate, upstream latency. - Runbooks: "volumetric UDP" / "SYN flood" / "HTTP flood on /search" each with concrete first moves.
- Rate limits and caching already deployed (not "we'll turn them on during the attack").
- Separate control-plane/admin access paths so you can still operate.
54.7 War story
An e-commerce site was hit with ~180 Gbps of DNS + CLDAP reflection during a sale. The transit link (2×10 Gbps) was saturated instantly — nothing on the host mattered. The on-call triggered the pre-arranged BGP swing to the scrubbing provider (announce prefixes from the scrubber, GRE tunnel back for clean traffic); within ~4 minutes clean traffic flowed and the site recovered. Post-mortem actions: move to always-on anycast proxy (no swing delay), publish Flowspec templates with transit, and add RRL to the authoritative DNS. Lesson: volumetric defense is an upstream capability you arrange in advance; host tuning is irrelevant once your pipe is full.
Try it yourself (observability)
# Traffic by protocol, live:
sudo iftop -i eth0 # or: nload, bmon
sudo tcpdump -i eth0 -nn -c100000 -w /tmp/s.pcap ; \
tshark -r /tmp/s.pcap -q -z io,phs # protocol hierarchy: what's flooding?
nstat -az | grep -Ei 'InReceives|InDiscards|SyncookiesSent|ListenDrops|TCPBacklogDrop'
watch -n1 'cat /proc/net/softnet_stat' # col2 drops, col3 time_squeeze rising = pps overload
sudo conntrack -S # insert_failed / drop rising = state exhaustion
# app edge:
tail -f access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head # top talkers