classesvolumetric / protocol / application / abuselayers3, 4, 7
Sort by what exhausts first (bandwidth / kernel table / CPU-backend), layer, and whether it looks like real traffic. Volumetric drowns the link; protocol/state exhausts finite tables (half-open conns, conntrack); application is cheap requests triggering expensive work; abuse is well-formed traffic you identify, not rate-drop.
the map
| class | layer | runs out | examples |
| Volumetric | L3/4 | bandwidth | UDP flood, amplification/reflection, ICMP flood |
| Protocol / state | L3/4 | a kernel table | SYN flood, ACK/RST flood, fragmentation, conntrack fill |
| Application | L7 | CPU / backend | HTTP flood, Slowloris, HTTP/2 Rapid Reset, cache-bust |
| Bots & abuse | L7 | your business logic | credential stuffing, scraping, scalping, AI crawlers |
cost asymmetry. Higher layer = cheaper to send, costlier to serve: one crafted L7 request is a few bytes for the attacker and a DB query + template render + backend round-trip for the server. So L7/bot defense is identification, not out-muscling volume.
SYN floodRFC 4987amplificationreflection off open UDP services
SYN flood: send the opening SYN, never complete the handshake; each pins a half-open-table slot until timeout. Amplification/reflection: small spoofed-source query to an open UDP service (DNS/NTP/memcached); the large reply lands on the spoofed victim.
a SYN segment - the half-open primitive
A real TCP SYN to port 443 (source/dest are RFC 5737 doc addresses). The whole attack is this one packet, sent by the million with spoofed sources so the SYN-ACKs go nowhere and the handshakes never finish.
SYN cookies. Store no half-open state; encode the connection into the SYN-ACK ISN (a MAC over the tuple + a slow timer). The client ACK returns it; the server recomputes and reconstructs the connection. Nothing to exhaust (RFC 4987).
a DNS amplification query - small in, huge out
A 36-byte ANY query with an EDNS0 option advertising a 4096-byte UDP buffer. Spoof the source to the victim and the multi-kilobyte answer is delivered to them, not you.
amplification factors (why UDP reflection scales)
| service | port | bandwidth factor |
| DNS (ANY) | 53 | ~28-54x |
| NTP (monlist) | 123 | ~557x |
| SSDP | 1900 | ~30x |
| CLDAP | 389 | ~56-70x |
| memcached | 11211 | ~10,000-51,000x |
root cause: source spoofing. Reflection works only because the source IP is forgeable and the reflector answers anyone.
BCP 38 / RFC 2827 edge ingress filtering (drop packets whose source can't come from that link) starves every amplification attack; not universally deployed.
slow attackshold connections openRapid ResetCVE-2023-44487
Packets are valid HTTP; cost is server-side work. Floods hit uncached/expensive endpoints (search, login). Slow attacks (Slowloris, slow-read, slow-POST) pin worker threads/connections with a trickle of bytes, starving the pool at near-zero bandwidth. HTTP/2 multiplexing added a vector:
HTTP/2 Rapid Reset - a frame that cancels itself
The client opens a stream (HEADERS) then immediately cancels it with an RST_STREAM. The request is fully processed server-side but never counts against the max-concurrent-streams limit, so one connection can churn tens of thousands of requests/second. This is the RST_STREAM frame: a 9-byte HTTP/2 frame header + a 4-byte error code.
Rapid Reset (CVE-2023-44487, 2023). The largest L7 DDoS on record at the time - it exploited a spec-legal behavior, not a bug, so every HTTP/2 implementation was affected at once. Mitigation is counting resets and reused streams per connection and killing abusive ones, plus capping request rate independent of the stream-concurrency limit. Its cousin, the CONTINUATION flood (2024), abuses unbounded header CONTINUATION frames the same way.
slow attacks. Slowloris drops a thread-per-connection server from one laptop. Defense: event-driven servers, aggressive header/body timeouts, a reverse proxy that fully buffers the request before origin.
the hard partit looks like real trafficyou can't drop by volume
Well-formed, low-rate, distributed across residential proxy pools (real home IPs rented via malware/SDK networks), so IP reputation and rate limits barely dent it. Defense = distinguishing automated from human.
the abuse catalog
credential stuffingreplaying leaked user/pass pairs to find reuse -> account takeover (ATO)
cardingtesting stolen card numbers against a checkout, cents at a time
scrapingharvesting content/prices; now includes the surge of AI training crawlers
scalpingbots hoarding limited inventory (tickets, drops, GPUs) faster than humans
API abuseusing an API exactly as designed, just far too much / not as intended
AI crawlers. LLM training/retrieval bots scrape at soft-DDoS volumes: ignore robots.txt, rotate residential IPs, forge browser UAs. The clearest current case for fingerprint-based ID -- UA says "Chrome," the TLS/HTTP fingerprint says "Python library."
problemIP is shared, UA is a free-text lieanswerJA4+ fingerprints
IP is unreliable (CGNAT, proxies, shared cloud) and the User-Agent is client-set free text. Fingerprint how the client speaks instead: TLS handshake shape, HTTP/2 settings, TCP options -- revealed by the library regardless of what it claims.
a JA4 fingerprint, decomposed
JA4 (the TLS ClientHello half of JA4+) hashes the negotiated capabilities into a stable, human-skimmable string. This is real Chrome:
t13d1516h2_8daaf6152771_02713d6af862
t13d1516h2the readable part: t=TCP, 13=TLS 1.3, d=SNI present, 15 cipher suites, 16 extensions, ALPN h2
8daaf6152771sha256[:12] of the sorted cipher-suite list
02713d6af862sha256[:12] of the sorted extensions + signature algorithms
JA4 vs JA3. JA3 hashed raw order-sensitive fields into one MD5 -- perturbed by GREASE + extension-shuffling, so a client could randomize its own fingerprint. JA4 sorts before hashing (defeats shuffling), strips GREASE, keeps a readable prefix -> stable + skimmable. JA4+ suite: JA4H (HTTP), JA4T/JA4TS (TCP), JA4S (ServerHello), JA4X (cert).
fingerprints spoof too. curl-impersonate / utls reproduce a real browser's ClientHello -- a match is strong evidence, not proof. State of the art combines fingerprint + behavior (timing, ordering, challenge-solving); no single signal is trusted alone.
capture it: pick these ClientHellos out of live traffic in
capture & filter -- display filter
tls.handshake.type == 1.
principledefense in deptheach layer removes work before the next
Stack cheap filters ahead of expensive ones so each layer sheds load first. Outside-in:
the layers
edge / networkAnycast spreads the load across many sites; scrubbing centers absorb volume; BGP flowspec + RTBH (remote-triggered blackhole) drop floods upstream; CDNs serve cached bytes so attacks never reach origin
transportSYN cookies, connection + rate caps, conntrack tuning - survive the state-exhaustion class
applicationWAF rules, rate limiting (token-bucket / sliding-window), challenges (JS, CAPTCHA, proof-of-work), fingerprint + reputation blocking, bot management
architecturalcache everything cacheable, degrade gracefully under load, tarpit + honeypot the obvious offenders, autoscale with a cost ceiling
proof-of-work challenges (Anubis, mCaptcha) make every client burn CPU-ms before service -- negligible per human, ruinous per bot at scale. Inverts the L7 asymmetry: the attacker pays per request.
rate limiting. Token-bucket allows bursts then throttles; sliding-window smooths; per-fingerprint / per-account beats per-IP against proxy pools. Honeypot endpoints/addresses (the ipv6-fun canary) turn any hit into a high-confidence hostile signal.
attack costrentable by the hourthe loopspoof ↔ detect, forever
Asymmetric economics. DDoS-as-a-service: booter/stresser rentals by the hour; residential-proxy pools of millions of real IPs. Defense = anycast capacity + scrubbing contracts + engineering time. Attacker pays cents; defender pays a retainer.
obscurity is not a control. Hiding an address/subdomain/fingerprint buys time and cuts noise, but anything discoverable is found and anything static is predicted. The controls are the ones you can reason about: rate, identity, challenge, capacity.
the loop doesn't converge. Better fingerprinting (JA4) -> better spoofing (uTLS) -> behavioral/multi-signal detection -> ... Durable posture: raise attacker cost + your observability faster than they adapt. Detect -> identify -> mitigate -> observe -> repeat.