Distributed Denial of Service is not a single attack class; it is a family of attack patterns that exploit fundamentally different layers of the network stack and impose fundamentally different mitigation requirements. The defender's challenge is that "DDoS protection" is often discussed as if it were a single capability, when in practice it is a portfolio of distinct controls, each engaged by a distinct attack mechanism, each measured by distinct effectiveness criteria. This analysis covers the attack-class taxonomy across L3, L4, and L7, the mechanics that distinguish each class, the mitigation primitives that actually engage against each, and the configuration disciplines that determine whether the deployed defenses hold under pressure. Mapping these vectors is the foundation for DDoS testing methodology, which exercises each class against live defenses.
The taxonomy: attacks by layer, not by name
Practical DDoS defense begins with categorizing attacks by the protocol layer they exploit rather than by their colloquial names. The categorization governs which mitigation primitive engages, where in the network stack the defense lives, and what observability surface is required to detect the attack in flight.
| Layer | Attack family | Mechanism | Primary mitigation layer |
|---|---|---|---|
| L3 (Network) | Volumetric floods, reflection/amplification | Saturate bandwidth or packet-per-second capacity | Network edge (anycast absorption, BGP blackholing, scrubbing centers) |
| L4 (Transport) | Protocol abuse, SYN, ACK, RST, FIN floods | Exhaust connection-tracking state or kernel resources | Kernel + network edge (SYN cookies, conntrack tuning, edge filtering) |
| L7 (Application) | HTTP floods, slow attacks, application-logic abuse, TLS abuse | Exhaust application capacity using semantically valid requests | Reverse proxy / WAF / application (rate limiting, bot management, behavioral classification) |
The architectural insight is that no single mitigation primitive addresses all layers. A network-edge anycast deployment absorbs L3 volumetric attacks elegantly but is blind to L7 application-logic abuse. A WAF rate-limiting policy mitigates HTTP floods but is irrelevant against an L3 amplification reflection that saturates the upstream link before the request reaches the WAF. Resilient infrastructure requires defenses positioned at each layer; gaps are exploited.
L3 attacks: volumetric and amplification
L3 attacks aim to saturate network capacity at or upstream of the target. The defender's options diminish rapidly with attack volume: 1 Gbps is absorbed by any modest cloud account; 100 Gbps requires deliberate architecture; 1 Tbps requires a mitigation provider with a global anycast network and BGP relationships across major peering exchanges.
Direct volumetric floods generate raw traffic from controlled infrastructure, typically a botnet of compromised devices, and direct it at the target. The attack rate is bounded by the sum of bandwidth available to the attack infrastructure. Direct floods of meaningful scale require thousands of distributed sources; the defender's analytical task is to identify the aggregate as an attack rather than as legitimate traffic from many users.
Reflection/amplification attacks are operationally more interesting. The attacker sends small requests to misconfigured public servers (the reflectors), spoofing the source IP as the target. The reflectors respond, to the spoofed source, with much larger replies. The attacker's bandwidth investment is multiplied by the amplification factor. Several historically significant amplification vectors:
| Reflection vector | Protocol | Amplification factor | Status |
|---|---|---|---|
| Memcached | UDP/11211 | ~10,000-51,000× | Memcrashed 2018; observed at 1.7 Tbps. Mostly mitigated by patched servers binding to localhost. |
NTP monlist | UDP/123 | ~556× | Historic peak vector; largely mitigated by NTP server patches disabling monlist by default. |
| CLDAP | UDP/389 | ~56× | Still active. Exploits Active Directory LDAP exposure. |
| DNS ANY | UDP/53 | ~28-54× | Persistent vector; mitigated by recursive resolvers refusing ANY queries. |
| SSDP | UDP/1900 | ~30× | UPnP-exposed home routers; persistent. |
| NetBIOS | UDP/137 | ~3.8× | Lower amplification, still seen in mixed-vector attacks. |
| Chargen | UDP/19 | ~358× | Niche, legacy. |
| QOTD | UDP/17 | ~140× | Niche, legacy. |
The defender's primitives at L3 are limited and well-known: BGP blackholing (sacrifice the affected IP to save the rest of the network), upstream scrubbing centers (mitigation providers with sufficient ingress capacity to absorb the attack), anycast deployment (distribute the attack load across many regional edge nodes), and at carrier level, source-address validation (RFC 2827 / BCP 38, refuse to forward packets whose source IP does not match the customer's assigned range). Source-address validation is the structural defense against reflection attacks; its uneven deployment across global carriers is the structural reason reflection attacks persist.
L4 attacks: protocol abuse
L4 attacks exploit weaknesses in transport-layer protocols rather than relying on raw bandwidth. They are typically lower-volume than L3 attacks but exhaust different resources: kernel connection-tracking tables, accept queues, ephemeral port ranges, conntrack limits.
SYN flood is the canonical L4 attack. The attacker initiates TCP connections (sends SYN packets) without completing the three-way handshake (never sends the final ACK). Each half-open connection occupies a slot in the kernel's SYN backlog. When the backlog fills, legitimate connections are rejected. The mechanism predates most current defenders by decades; the mitigation is also well-established.
The structural defense is SYN cookies, a kernel feature in which, instead of allocating backlog state on SYN receipt, the server encodes the connection parameters into the initial sequence number of the SYN-ACK reply. When (and if) the ACK arrives, the server reconstructs the connection state from the sequence number. The state cost of an unanswered SYN drops to zero. SYN cookies have a small computational cost and a small functional limitation (TCP options sent in the SYN are forgotten), but for any production server facing the public internet, they should be enabled.
The kernel parameters that actually govern SYN-flood resilience on a Linux server:
# Enable SYN cookies: eliminates SYN backlog as an attack surface
net.ipv4.tcp_syncookies = 1
# Increase the SYN backlog (acts as a buffer before cookies engage)
net.ipv4.tcp_max_syn_backlog = 8192
# Increase the accept queue depth (sockets accepted but not yet handled)
net.core.somaxconn = 65535
# Reduce SYN-ACK retry attempts (lowers state cost of unanswered SYNs)
net.ipv4.tcp_synack_retries = 2
These are not optional configuration on a production system; the defaults on most Linux distributions are conservative for low-load servers and inadequate for any system exposed to internet traffic at scale. Userspace SYN-flood detection at the application layer is, in practice, an exercise in measuring attacks that the kernel should have refused, useful for telemetry but not for mitigation. SYN flood mitigation lives in the kernel.
Other L4 floods, ACK floods, RST floods, FIN floods, exploit connection-tracking state in stateful firewalls and load balancers. Mitigation is largely a question of upstream filtering capacity: an L4 flood that reaches a stateful firewall has already cost CPU and memory on the firewall; the defense is to filter at a stateless edge layer (a load balancer or scrubbing center positioned ahead of stateful infrastructure).
L4 reflection attacks exist (notably NTP and SSDP at UDP, and some TCP-based reflection vectors) and are mitigated by the same network-edge primitives as L3 reflection.
L7 attacks: the hardest class
L7 attacks generate semantically valid HTTP requests. They cannot be filtered by network-layer rules without rejecting legitimate users. They cannot be detected by raw rate alone, because rate-limiting against modern web applications must accommodate legitimate burst traffic, CGNAT-shared client IPs (where many users present the same source IP), and authenticated API patterns that can legitimately consume hundreds of requests per page load. L7 is where DDoS resilience is operationally decided.
HTTP floods generate high volumes of HTTP requests against expensive endpoints. The attacker's goal is not to saturate bandwidth, HTTP requests are small, but to exhaust application capacity. A search endpoint that executes a 200-millisecond database query under attack at 10,000 requests per second represents 2,000 seconds of compute per real-time second; a database with 50 connection slots is exhausted in milliseconds. The attacker's resource cost is small; the defender's resource cost is enormous. The asymmetry is what makes L7 floods effective.
Mitigation requires distinguishing the attack traffic from legitimate traffic. Available primitives:
- Rate limiting at request-per-IP, request-per-session, request-per-ASN, or request-per-cookie granularity. Effective against unsophisticated attacks; defeated by carpet-bombing (low per-IP rates across many IPs) and by attacks routed through real residential-proxy networks.
- Bot management using TLS fingerprinting (JA3, JA4), HTTP/2 settings frame fingerprinting, behavioral signals (mouse movement, request timing patterns), and ML classification trained on known legitimate vs. known adversarial traffic.
- Challenge-response, JavaScript challenge, Managed Challenge, hCaptcha, interposed for traffic flagged as suspicious. High accuracy at the cost of measurable latency added to legitimate users who happen to be flagged.
Slow attacks invert the volumetric model. Rather than overwhelming the application with request volume, slow attacks hold a small number of connections open without ever completing them. Each held connection consumes a worker thread (Apache prefork), an event-loop slot (nginx), or a connection from a connection pool. With enough held connections, legitimate users find no available workers.
The slow-attack family:
- Slowloris sends partial HTTP request headers and periodically sends additional header bytes to prevent connection timeout. Server holds the connection open waiting for the rest of the request. A few thousand Slowloris connections can occupy all worker slots on a mid-sized server.
- Slow POST (R-U-Dead-Yet, RUDY) sends a
Content-Lengthheader indicating a large request body and then transmits the body one byte every several seconds. The server holds the connection waiting for the body. - Slow Read advertises a small TCP receive window and reads response bytes slowly, holding the connection open while the server attempts to deliver the response.
Mitigation requires aggressive HTTP timeout configuration (header read timeout, body read timeout, idle timeout), a reverse proxy that uses async I/O rather than per-connection workers, and ideally a WAF rule that detects the slow-request pattern and severs the connection.
HTTP/2 rapid reset (CVE-2023-44487, disclosed October 2023) is a more recent and architecturally significant abuse. HTTP/2 multiplexes many streams over a single TCP connection. An attacker opens many streams in rapid succession and immediately sends RST_STREAM frames, canceling each stream before the server begins processing. Per stream the attack is invisible; aggregated, the attacker generates an enormous request rate against the server's request-processing pipeline while bypassing the standard connection-level rate limits. The vulnerability affected nearly every HTTP/2 implementation; mitigation required server-side patches limiting concurrent stream initiation and stream cancellation rates.
TLS renegotiation flood abuses the TLS protocol's renegotiation feature. An attacker establishes a TLS connection and repeatedly requests renegotiation, forcing the server to repeat the expensive handshake. Each handshake costs orders of magnitude more CPU than a typical request. Mitigation is to disable client-initiated renegotiation at the TLS layer, supported by every modern TLS implementation but not always enabled by default.
WebSocket connection exhaustion opens many WebSocket connections and holds them. Long-lived connections that consume server-side state are the attack surface; mitigation is per-IP connection limits and idle-connection timeouts.
Application-logic abuse is the most sophisticated L7 class. The attacker generates requests that look indistinguishable from legitimate traffic but exploit application-specific logic:
- Cart abuse, add items to a shopping cart at high volume, exhausting the database storage assigned to anonymous cart sessions
- Credential stuffing, authentication attempts at request volumes just below the application's rate-limit threshold, using leaked credential lists
- Search abuse, Boolean-heavy or wildcard-heavy queries that consume seconds of database CPU per query
- Password reset spam, generates outbound email at scale (and may saturate transactional-email-provider rate limits)
- Payment validation flood, invokes external payment APIs at cost-per-call, monetizing the attack against the target's vendor budget
- API enumeration, paginated reads of expensive endpoints (e.g.,
/api/v1/users?limit=100&offset=N) to exhaust database query budget
Application-logic attacks defeat off-the-shelf WAF rules because the requests are syntactically valid HTTP from real-looking clients. Mitigation requires application-specific custom rules, behavioral baselines per endpoint, and often per-account or per-session anomaly detection. This is the area of DDoS defense in which engineering investment is required regardless of vendor; off-the-shelf protection is necessary but not sufficient.
Detection: why "rate limiting" is an oversimplification
The popular framing of DDoS defense centers on rate limiting. Real defense is more nuanced. The threshold-based rate limit is the floor; everything above it is engineering effort to distinguish the legitimate burst from the adversarial burst.
The defender's signal portfolio:
- Rate, requests per IP, per session, per ASN, per geographic region, per User-Agent, per TLS fingerprint
- Behavioral patterns, request timing distribution (humans don't fire requests in millisecond-perfect cadence), navigation paths (real users follow plausible routes through an application), input patterns (mouse movements, scroll velocity)
- Reputation, known-bad IP lists, known proxy/VPN exit nodes, known cloud-provider IP ranges with high adversarial density (residential proxies are the harder case)
- Cryptographic identity, TLS fingerprinting (JA3/JA4) captures the client TLS handshake configuration in a hash; the hash typically maps closely to a specific tool or library, and adversarial tooling has identifiable fingerprints distinct from real browsers
- HTTP/2 settings frame fingerprinting, analogous to JA3 but at the HTTP/2 layer; modern Cloudflare and AWS WAF expose this as a signal
- Application-context anomaly, per-account login frequency, per-account read patterns, per-session expense (cumulative database time consumed by the session)
The defender's decision is not whether to apply a control but at what threshold and with what action, block, challenge, log, rate-limit, soft-block. Each action has a different false-positive cost; tuning the cost function for a specific application is engineering work that cannot be outsourced to a generic ruleset.
Mitigation primitives by layer
A working defense composes primitives across layers. The composition is more important than the individual primitives.
Network edge (L3/L4):
- Anycast deployment to distribute attack load across regional edges
- Upstream scrubbing centers with sufficient ingress capacity for the expected adversary
- BGP blackholing as a last resort to protect the rest of the network at the cost of the affected IP
- Carrier-level source-address validation (BCP 38) to refuse spoofed packets at network ingress
Kernel layer:
- SYN cookies enabled
- Accept queue depth tuned for expected concurrency
- Connection-tracking limits raised on stateful firewalls
- Ephemeral port range expanded for high-concurrency clients
Reverse proxy / CDN layer (L7):
- WAF rules, managed rule sets as the baseline, custom rules for application-specific logic
- Rate limiting at multiple granularities (IP, session, ASN, region)
- Bot management with TLS fingerprinting
- Cache-policy hygiene, avoid cache-busting query parameters that bypass the CDN
Application layer:
- Connection timeouts (header read, body read, idle) tuned to defeat slow-attack patterns
- Per-account behavioral baselines for high-value endpoints (auth, payment, search)
- Circuit breakers on expensive downstream dependencies (database, external API)
- Graceful degradation modes, serving cached content or static fallbacks when the live path is saturated
Observability:
- Real-time per-endpoint request metrics with sub-second granularity
- Connection-count and connection-state metrics at the load balancer and reverse proxy
- Database query latency percentiles per endpoint (p50, p95, p99, the long tail is where attacks first show up)
- Log retention sufficient to perform post-incident analysis (typical retention of 7 days is inadequate for sophisticated attack investigation)
Where configuration discipline actually lives
The mechanics described in this analysis are well-documented. What separates infrastructure that holds from infrastructure that collapses is not knowledge of the mechanics, it is the configuration discipline applied at each layer. Several patterns recur across post-incident reviews:
WAF rules deployed in COUNT action mode in production. Rules are configured, generate logs, and never enforce. The operating team believes the rules are protecting the application; under attack, the rules log the attack and pass it through. The single most common DDoS-related failure is not absence of controls, it is controls deployed in observation mode rather than enforcement mode.
Origin reachability not constrained at the network layer. When a CDN or scrubbing service is positioned in front of the origin, the origin's IP address must be reachable only from the protective layer's IP ranges. If the origin remains directly reachable from arbitrary internet IPs, an attacker who discovers the origin IP (through historical DNS records, certificate transparency logs, email infrastructure, non-proxied subdomains, or application code paths) bypasses the protective layer entirely. The defense requires AWS security-group or equivalent network-layer enforcement of the source-IP allowlist; the protective layer is structural, not advisory.
Rate limits set to default values. Off-the-shelf rate-limit thresholds catch unsophisticated attacks. Real adversarial traffic operates just below the threshold, by design. Tuning the threshold requires testing against both legitimate burst patterns and adversarial burst patterns; the calibration is application-specific and cannot be lifted from a vendor template.
HTTP/2 rapid reset patches missing or partial. Two years after CVE-2023-44487, deployments running unpatched HTTP/2 implementations are still encountered. The patch ships with most distribution updates but requires explicit application; the failure mode is silent until exploited.
Connection timeouts left at framework defaults. Most web frameworks default to connection timeouts measured in tens of seconds, adequate for normal traffic, exploitable by slow attacks holding thousands of partial requests. Tightening timeouts is a one-line configuration change that materially affects resilience against the entire slow-attack family.
Failover paths untested under adversarial conditions. Disaster-recovery drills validate that failover works when the primary region experiences an availability event. They rarely validate that failover survives an adversary actively exploiting the DNS update window. The attack profile that saturated the primary region follows the DNS update to the failover region within seconds. Without a tested handoff plan that accounts for the failover region's own DDoS posture, failover can compound the outage rather than recover from it.
TLS configuration left to vendor defaults. Disabling client-initiated TLS renegotiation, tuning cipher suite selection for performance under load, configuring TLS session resumption, these are not optional on a production internet-facing system. The configuration surface area is larger than most teams account for.
The engineering discipline is to treat each layer's controls, network edge, kernel parameters, WAF rules, application timeouts, TLS configuration, observability, as independent hypotheses about how the infrastructure responds to adversarial traffic, each independently testable, none of which can be assumed correct without validation under realistic load.
The asymmetry that determines who holds
DDoS attacks are not new science. SYN cookies have shipped in the Linux kernel since 1996. BCP 38 on source-address validation has been an IETF best practice since 2000. Slowloris was demonstrated by Robert Hansen in 2009. Memcached amplification was mitigated in 2018 by binding the daemon to localhost. HTTP/2 rapid reset (CVE-2023-44487) was disclosed and patched within weeks of discovery. Every attack vector documented in this analysis has a defense that has existed for years or decades.
The reason DDoS outages persist is structural, not technical. The defenses live across seven layers, network edge, kernel, reverse proxy, WAF, application, TLS, observability, and resilient infrastructure is infrastructure where each of those layers has been audited against the relevant attack class and confirmed to be enforcing rather than logging. Most enterprise stacks have all seven layers deployed. Most have not audited them in the last twelve months.
The structural asymmetry of DDoS defense is this: the attacker invents the attack once, deploys it at scale, and extracts value from every misconfigured target. The defender configures the response once, walks away, and absorbs catastrophe from every configuration drift that follows. WAF rules age into COUNT action mode after a refactor that nobody re-audited. Sysctls revert to distribution defaults on a kernel upgrade. Security groups loosen during a deployment three quarters ago that was supposed to be temporary. Connection timeouts stay at framework defaults because the framework defaults were never reviewed. The attack class hasn't changed since the 1990s. The configuration changes every release.
Most DDoS outages are not the result of new attack techniques. They are the result of old configurations that quietly stopped enforcing what they were configured to enforce. The discipline that determines resilience is not detection, every modern stack detects. It is verification: periodic, structured, applied to the specific attack classes documented above, against the specific infrastructure deployed today. The attack mechanics are documented. The configurations are not. The asymmetry is corrigible. The work is in the audit.
