All DDoS Definitions
DDoS Testing Definition

Conntrack Exhaustion

Conntrack exhaustion is usually described as a symptom of a large flood, and a DDoS test is what shows that description is incomplete. The table fills at whatever connection rate the attacker picks, cheap low-bandwidth flows included, because the cost is one entry per flow and has nothing to do with bits per second. When the table is full, a stateful device stops accepting new flows while the link still looks idle.

Conntrack exhaustion: one table entry per flow Attacker thousands of flows each low-bandwidth one entry per flow Stateful firewall: nf_conntrack table one entry per tracked flow full at nf_conntrack_max: no room for a new flow New legit flow arrives dropped: table full Table full new flows dropped log: table full The cost is per-flow table state, not bandwidth, so modest packet rates still exhaust it. A test finds the connection rate that saturates the table and whether nf_conntrack_max, timeouts, and offload hold. BlackNeuron
Conntrack exhaustion: many low-bandwidth flows each consume one nf_conntrack entry until the table fills to nf_conntrack_max, after which new legitimate flows are dropped

What the connection-tracking table is

The connection-tracking table (nf_conntrack in the Linux kernel) holds one entry for every flow a stateful firewall, NAT gateway, or load balancer is following. Netfilter needs that state to know a returning packet belongs to a connection it already allowed, and Network Address Translation needs it to reverse the translation on the way back. The table is finite. Its ceiling is nf_conntrack_max, sized by the kernel from available memory at boot, often only tens or a few hundred thousand entries on a default install. Under the hood it is a hash: nf_conntrack_buckets sets the number of hash slots, and nf_conntrack_max defaults to four times that bucket count. A stock server frequently boots with a hashsize in the low tens of thousands and a ceiling to match, a figure chosen from RAM rather than from the number of flows the box will really carry. Once every row is taken, the kernel drops the next new flow and logs nf_conntrack: table full, dropping packet.

An entry is per flow, not per byte, and every protocol counts. A UDP flood creates conntrack entries just as a TCP one does, each held for its protocol's timeout. So an attacker needs no volume. A stream of new connections, or new UDP 5-tuples, arriving faster than timeouts let old entries expire walks the count up to the ceiling while the interface graph stays flat.

How long each entry survives is the other half of the arithmetic. nf_conntrack_udp_timeout defaults to 30 seconds, but nf_conntrack_tcp_timeout_established defaults to 432000 seconds, a full five days. Once a TCP flow reaches the established state its row is held for that window unless the connection closes cleanly with a FIN or RST, so an attacker who opens connections and leaves them open parks entries the kernel will not reclaim on any timescale that helps mid-flood. The count only ratchets upward.

Conntrack exhaustion: one entry per flow, every protocol counts New flows, TCP and UDP alike nf_conntrack table one entry per 5-tuple flow nf_conntrack_max table full: new flow dropped, NAT stalls A shared table: throwaway flows evict the room real sessions need BlackNeuron
Animated conntrack exhaustion: new flows of any protocol each claim one entry in the nf_conntrack table until it reaches nf_conntrack_max, after which a new legitimate flow is dropped and NAT stalls

Why it matters under attack

What makes conntrack exhaustion nasty is that the table is shared. Conntrack is one table serving all traffic through the box, so a flood of throwaway flows evicts room that legitimate connections need, and unrelated services behind the same firewall start timing out. Because NAT rides on the same table, a gateway that exhausts conntrack stops translating: outbound sessions for the whole network fail, not only the ones under attack.

Like the TCP connection flood it resembles, the damage usually lands on the middlebox first. A stateful firewall or NAT gateway tracks state for everything behind it and typically carries a smaller nf_conntrack_max than the sum of what the servers could handle, so it hits the wall while the origin still has headroom. Whichever hop carries the smallest table sets the ceiling, and it is rarely the one that was sized for capacity.

What a DDoS test measures

A test characterizes the connection rate at which the table saturates, not the bandwidth. It drives new flows, TCP or UDP, and watches the live count climb toward nf_conntrack_max, reading it from /proc/sys/net/netfilter/nf_conntrack_count or listing the table directly with conntrack -L, and recording both the rate at which drops begin and which device in the path logs them first.

Then it checks the controls meant to hold the line: whether nf_conntrack_max and the hash size are tuned for the real flow count rather than left at a boot default, whether per-source connection limits and shorter timeouts reclaim entries fast enough under a flood, and whether flow offload (a hardware or software flowtable that bypasses conntrack for established flows) actually engages. Pinning down whether the box ran out of table or ran out of pipe, and at which hop, is what DDoS resilience testing exists to establish.