Know your attacker · Part 4
SYN floods and volumetric DDoS: what your server can stop, and what it can't
SYN floods exhaust the kernel's half-open queue; amplification attacks fill the link itself. How each shows up on a Linux host, what SYN cookies and sysctl can do, and why a full pipe is your provider's job.
The attacks so far in this series work at the HTTP layer: they need a working TCP connection to your web server. This one goes lower. A SYN flood attacks the TCP handshake itself; a volumetric attack does not care about your server at all — it fills the cable that leads to it. The first you can largely handle on the host. The second you cannot, and it is better to know that before it happens.
The names
- SYN flood — a layer-4 attack on the TCP handshake. Sometimes called a half-open attack.
- UDP flood, ACK flood, GRE flood — raw packet volume at layers 3 and 4.
- Reflection / amplification attacks — named after the protocol abused: DNS amplification, NTP amplification (the old
monlistcommand), memcached amplification, CLDAP, SSDP.
What the attacker wants
To make your server unreachable without speaking a word of HTTP. A SYN flood aims at a resource inside the kernel: the queue of connections being established. A volumetric attack aims at something outside your server entirely — your uplink, your provider’s port, sometimes a whole router upstream.
How a SYN flood works
A TCP connection opens with a three-way handshake: the client sends SYN, the server answers SYN-ACK and remembers the half-open connection, the client completes with ACK. The server keeps those half-open connections in a queue of limited size (governed by net.ipv4.tcp_max_syn_backlog and the listener’s backlog).
A SYN flood sends SYNs, usually from spoofed source addresses, and never sends the final ACK. The server retransmits its SYN-ACK several times (net.ipv4.tcp_synack_retries, 5 by default) before giving up on each one. If SYNs arrive faster than they expire, the queue fills and legitimate clients can no longer connect.
What it looks like
# Half-open connections right now
ss -Hn state syn-recv '( sport = :443 or sport = :80 )' | wc -l
# Kernel counters: listen queue overflows, SYN cookies sent
nstat -az TcpExtListenOverflows TcpExtListenDrops TcpExtSyncookiesSent
And in the kernel log, a line along these lines:
TCP: request_sock_TCP: Possible SYN flooding on port 443. Sending cookies.
Normally syn-recv holds a handful of entries. During a flood it holds thousands, from addresses that look random.
What stops it: SYN cookies
SYN cookies are the kernel’s answer, and they are on by default (net.ipv4.tcp_syncookies = 1). When the queue overflows, the kernel stops storing half-open connections and instead encodes what it needs into the sequence number of its SYN-ACK. A real client’s ACK carries that number back, and the connection is rebuilt from it; spoofed SYNs cost nothing to forget. Check it, and give the queue some room:
# /etc/sysctl.d/60-synflood.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_synack_retries = 2
net.core.somaxconn = 4096
Apply with sysctl --system. Lowering tcp_synack_retries frees half-open slots faster, at the cost of slightly worse connections over very lossy links. somaxconn caps the accept queue each listener can ask for; nginx’s listen ... backlog= and Apache’s ListenBacklog choose their own value up to that cap.
A host can handle a large SYN flood this way. What it cannot handle is a SYN flood so large that it is really a volumetric attack.
How volumetric and amplification attacks work
Here the attacker’s only goal is to send more traffic than your link can carry. Amplification makes that cheap:
- The attacker sends small requests to thousands of public servers that answer over UDP — open DNS resolvers, NTP servers, exposed memcached instances.
- Each request carries a spoofed source address: yours.
- Each server sends its much larger answer to you. A request of a few dozen bytes can trigger an answer tens or thousands of times larger, depending on the protocol.
Your server never asked for any of it. It arrives anyway, and it arrives on a link with a fixed capacity.
Why your firewall cannot help
A firewall on the host decides what to do with packets that have already arrived — that have already crossed your uplink and used its capacity. If 20 Gbit/s are aimed at a 1 Gbit/s port, nftables can drop every attack packet perfectly and your server still sees a saturated link, losing legitimate packets upstream along with the attack. The bottleneck is before the firewall, so the fix has to be before it too.
What it looks like
From inside the host: packet loss, a network interface pinned at line rate (ip -s link, sar -n DEV 1), legitimate connections timing out, and, often, nothing at all — because the provider’s anti-DDoS has already diverted the traffic, or because the host simply went silent. From outside: the server is unreachable, while its console at the provider shows it running.
How to protect yourself
- Use the provider’s mitigation. Large hosting providers filter volumetric attacks in their network, before your port: OVHcloud’s anti-DDoS is included with its servers, Hetzner includes DDoS protection, and on AWS, Shield Standard covers every account. Know what yours does, whether it is always on or triggered, and where to see its history: after an unexplained outage, it is the first place to look.
- Put a CDN in front of web traffic. A CDN with enough capacity absorbs the flood on its edge. It only protects you if attackers cannot find your origin: allow web traffic only from the CDN’s address ranges, and do not leak the origin’s address in DNS records like an old
direct.subdomain or in outgoing mail headers. - Don’t be an amplifier. Make sure your own servers cannot be used against someone else: no open DNS resolver (
allow-recursionlimited to your networks), memcached bound to127.0.0.1with UDP disabled (-U 0, the default since memcached 1.5.6), no NTPmonlist. - Keep SYN cookies on and the sysctl values above, for the attacks that are small enough to reach you.
How Demerzel helps
Plainly: Demerzel does not stop volumetric DDoS, and nothing installed on your server can. The warden bans single addresses, one at a time, in a table on the host — after the traffic has already crossed your link. Against a flood from spoofed or reflected sources, that is the wrong tool. Your provider’s scrubbing and a CDN are the right ones.
What Demerzel does around it:
- It tells you which kind of outage you had. When the agent goes silent, Demerzel dials the host from outside on its listening ports and reports whether it answers. Afterwards, an outage is classified from the evidence: restart if the server booted, sites down if the agent kept reporting but no visitor got in, stopped answering if both went silent while the machine kept running. For that last kind, the post-mortem says what the evidence cannot tell — held web workers or a network cut — and its next steps include checking the provider’s network and anti-DDoS history for the exact window, with the server’s public addresses.
- It finds the services that turn you into an amplifier. Demerzel’s exposure checks flag a datastore or admin service reachable from the internet with no host firewall — memcached, Redis, databases, the Docker API — on the server page, in the Health Score and as an Action.
- It keeps the metrics. CPU, memory and load over time, on the same page as the outage, so a host that went quiet with an idle CPU is not mistaken for one that was overloaded.