Attacks & threats

6 min readUpdated

What is a SYN flood attack?

Quick answer

A SYN flood is a denial-of-service attack that abuses the way TCP opens a connection. The attacker sends a stream of SYN packets, the first step of the handshake, but never sends the final acknowledgement, so the server keeps each half-finished connection in memory waiting for a reply that never arrives. The connection table fills up, and genuine visitors are refused because there is no room left to accept them. It needs very little bandwidth, which is what makes it attractive to attackers and easy to miss on a traffic graph.

01The handshake it abuses

Every TCP connection starts with three packets, the three-way handshake defined in RFC 9293. The client sends SYN ("I want to connect"), the server replies SYN-ACK ("go ahead") and reserves memory for the connection, and the client answers ACK ("connected"). Only then does data flow. While the server waits for that last ACK, the connection sits in the SYN-RECEIVED state.

The vulnerability is in the middle step: the server commits resources after the first packet, before it has any proof the client is real. A SYN flood simply never sends the third packet. It is a weakness of TCP specifically; UDP has no handshake to abuse, a difference covered in TCP vs UDP.

Normal handshake vs. SYN flood
normal:                      flood:
  client → SYN                 attacker → SYN
  server → SYN-ACK   (waits)   server   → SYN-ACK   (waits…)
  client → ACK                 (nothing ever comes back)
  → connected                  → slot held until timeout

  one slot, briefly            thousands of slots, up to 63 s each
                               on Linux defaults

02Why so little traffic does so much damage

A SYN packet is tiny: 40 to 60 bytes at the IP layer, depending on its options. A few thousand per second is a rounding error on a gigabit link, so bandwidth graphs stay flat while the server is already refusing connections: the load is counted in packets per second rather than bits.

What runs out is not bandwidth but state. Each half-open connection occupies an entry in the SYN backlog. On Linux, tcp_max_syn_backlog starts at 128 on low-memory machines and grows with RAM, and with the default of five SYN-ACK retries a half-open connection is retransmitted for 31 seconds and finally abandoned after 63. A sustained flood refills those entries far faster than they expire.

It remains one of the most common network-layer attacks. Cloudflare's DDoS report for the third quarter of 2025 lists SYN floods among the leading vectors, behind UDP and DNS floods.

03Spoofed sources make blocking useless

Because the attacker never needs to receive the SYN-ACK, the source address in the SYN packet can be anything at all. Attackers randomise it, so each packet appears to come from a different host.

That defeats address-based blocking twice over: there is no small set of addresses to ban, and any address you do ban probably belongs to an innocent third party whose address was forged. Worse, the victim's SYN-ACK replies go to those forged addresses, so the attack sprays unsolicited traffic at bystanders, the same backscatter that arrives elsewhere as a reflected SYN-ACK flood.

The root fix sits upstream. Networks that apply BCP 38 ingress filtering refuse to forward packets with source addresses that do not belong to them, which stops spoofing where it starts. Until every network does, the victim has to assume the addresses are forged.

04A thirty-year-old attack

According to RFC 4987 the weakness was known to researchers by 1994, and a description with an exploit tool was published in Phrack in 1996. By September that year it was being used in the wild: a SYN flood starting on 6 September shut down mail service at Panix, an internet provider in New York. Daniel J. Bernstein proposed SYN cookies on 16 September 1996, and Eric Schenk released a Linux implementation in February 1997.

RFC 4987, published in 2007, is still the reference survey of mitigations: larger backlogs, shorter timeouts, recycling the oldest half-open entry, SYN caches, SYN cookies and filtering. It concludes that SYN caches can be on by default while SYN cookies should not be, and notes that the two combine, with cookies sent once the cache is full. Linux takes a similar line: it keeps compact state for half-open connections and switches to cookies only when the backlog overflows.

05SYN cookies: the actual fix

The standard defence inverts the problem. Instead of allocating memory when the SYN arrives, the server encodes the connection state into the sequence number it sends back in the SYN-ACK, a cryptographic value derived from the connection details, called a SYN cookie.

No state is stored. If the client is real it returns the ACK, the server verifies the cookie mathematically, and only then builds the connection. If the client never replies, nothing was ever allocated and nothing needs cleaning up. The attack stops costing the server anything.

The trade-off is documented in RFC 4987: commonly implemented cookie schemes cannot carry every TCP option, such as window scaling and selective acknowledgement. That is one reason Linux only sends cookies when the backlog overflows. With net.ipv4.tcp_syncookies set to 1, the default, cookies engage under pressure; a value of 2 sends them unconditionally.

  • SYN cookies: the primary defence, on by default in Linux for when the backlog overflows
  • SYNPROXY: the firewall answers the handshake with cookies itself and only passes completed connections to the server
  • A larger backlog buys time but does not solve it alone
  • Shorter SYN-ACK timeouts free slots faster, at some cost to slow clients
  • Per-source connection limits help only against unspoofed attacks
  • Upstream filtering, because a large enough flood still saturates the link itself; see how to stop a DDoS attack
SYNPROXY in front of port 443 (nftables, validated with nft -c and loaded in a netns)
# sysctl: net.ipv4.tcp_syncookies=1  net.ipv4.tcp_timestamps=1
#         net.netfilter.nf_conntrack_tcp_loose=0
# mss and wscale must match what your server itself advertises
table inet syn_guard {
    chain prerouting {
        type filter hook prerouting priority raw; policy accept;
        tcp dport 443 tcp flags syn notrack
    }
    chain input {
        type filter hook input priority filter; policy accept;
        tcp dport 443 ct state invalid,untracked synproxy mss 1460 wscale 7 timestamp sack-perm
        ct state invalid drop
    }
}

06How to tell you are being hit

The application-logs row is the one that misleads people most. Because the connections never complete, nothing reaches the web server, so the access log shows a drop in traffic while the site is unreachable.

It also separates a SYN flood from a Slowloris attack. Slowloris completes the handshake and then holds connections open with deliberately slow requests, so it shows up as established connections and stalled requests. A SYN flood shows up as half-open entries and an empty log. To tell any flood apart from a traffic spike or an origin fault, work through signs of a DDoS attack.

SignalWhat you would see
Half-open connectionsLarge and growing count in the SYN-RECV state
BandwidthNormal: the giveaway that it is not volumetric
Source addressesHuge variety, often no repeats at all
Application logsQuiet: the requests never complete a handshake
User reportsTimeouts and refused connections, not slow pages
Checking a Linux host (commands run on Debian 12; filter checked with tcpdump -d)
# half-open connections right now
ss -Hnt state syn-recv | wc -l

# cookie activity and accept-queue overflows since boot
nstat -az TcpExtSyncookiesSent TcpExtSyncookiesRecv \
          TcpExtSyncookiesFailed TcpExtListenOverflows TcpExtListenDrops

# configured backlog of each listener (the Send-Q column)
ss -lnt

# watch the SYNs themselves (IPv4): SYN set, ACK not set
tcpdump -ni eth0 -c 50 'tcp dst port 443 and tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn'

Questions

Frequently asked questions

No. It is a protocol attack. It exhausts connection state rather than bandwidth, which is why it can take a server down with traffic levels that look completely unremarkable on a graph.

Common cookie schemes cannot preserve every TCP option negotiated in the handshake, such as window scaling and selective acknowledgement, which can reduce performance for the connections affected. Linux limits the impact by using cookies only when the backlog overflows. That is a good trade when the alternative is being offline.

A stateful firewall often makes it worse, because it also has to track every half-open connection and has its own table to exhaust. Filtering has to happen before the link is saturated, on a network with the capacity to absorb it.

The source addresses are forged and usually randomised per packet. There is no meaningful list to block, and blocking them punishes innocent hosts whose addresses were spoofed.

On Linux, read net.ipv4.tcp_syncookies with sysctl. A value of 1, the default, sends cookies when the backlog overflows, and the TcpExtSyncookiesSent counter shown by nstat tells you whether they have actually been used.

Sources

Sources and verification

tcpdump filter checked with tcpdump 4.99.3 (tcpdump -d); SYNPROXY ruleset syntax-checked with nft -c and loaded in an isolated network namespace (nft 1.0.6); ss, nstat and sysctl commands run on Debian 12, October 2026.

  1. 01RFC 9293: Transmission Control Protocol (TCP) · IETF
  2. 02RFC 4987: TCP SYN Flooding Attacks and Common Mitigations · IETF
  3. 03SYN cookies · D. J. Bernstein
  4. 04IP Sysctl (tcp_syncookies, tcp_max_syn_backlog, tcp_synack_retries) · kernel.org
  5. 05Synproxy · nftables wiki
  6. 06RFC 2827 (BCP 38): Network Ingress Filtering · IETF
  7. 07DDoS threat report for 2025 Q3 · Cloudflare

Last updated