A SYN flood attack isn’t about overwhelming a server with completed connections; it’s about weaponizing the initial handshake.
Let’s see it in action. Imagine a web server, webserver.example.com, listening on port 80. A legitimate user’s browser initiates a TCP connection like this:
- Client -> Server:
SYN(sequence number 12345) - Server -> Client:
SYN-ACK(sequence number 67890, acknowledgment 12346) - Client -> Server:
ACK(acknowledgment 67891)
This completes the handshake. Now, picture a SYN flood:
- Attacker -> Server:
SYN(sequence number 12345) - Server -> Attacker:
SYN-ACK(sequence number 67890, acknowledgment 12346)
The server, expecting the final ACK, allocates resources for this half-open connection. But the attacker never sends the ACK. Instead, they send another SYN, often with a spoofed source IP address, making it look like a new, distinct client. The server replies with another SYN-ACK, again waiting for the final ACK that will never come. This repeats, with the server’s connection table filling up with these half-open connections, each consuming memory and CPU cycles. Eventually, legitimate clients trying to connect will see their SYN packets ignored or dropped because the server has no more resources to track new connections.
The core problem this solves is the server’s trust in the initial SYN packet. TCP’s three-way handshake is designed for reliable connection establishment, but it’s vulnerable to abuse because the server commits resources before the client has fully committed. The attacker exploits this by never completing the commitment, leaving the server in a perpetual state of waiting.
Internally, the server maintains a SYN backlog queue. When a SYN arrives, the server checks if it has space. If so, it sends a SYN-ACK and places the connection in a "half-open" state, often in this backlog queue or a related data structure. If the final ACK arrives within a certain timeout period (typically 30 seconds to a few minutes, depending on the OS and configuration), the connection is established, and the entry is removed. If the timeout expires, the entry is discarded. In a SYN flood, the queue fills up with these timed-out entries, preventing new, legitimate connections from being added.
The primary levers you control on a server are:
- SYN Backlog Size (
net.ipv4.tcp_max_syn_backlog): This is the most direct control. It dictates how many half-open connections the kernel will queue. Increasing this allows the server to tolerate more half-open connections before refusing newSYNpackets. - SYN-ACK Retransmission Timeout (
net.ipv4.tcp_synack_retries): This value, often implicit in the kernel’s behavior, determines how many times the server will retransmit itsSYN-ACKbefore giving up on a half-open connection. A lower number means the server gives up faster, freeing up resources sooner, but this can also drop legitimate connections during network congestion. - SYN Cookies (
net.ipv4.tcp_syncookies): This is a critical defense. When enabled, instead of allocating memory for a half-open connection, the server sends a specially craftedSYN-ACKpacket. This packet contains a "cookie" derived from the client’s IP, port, and a secret server-side key, along with a sequence number. If the client is legitimate, it will respond with anACKpacket that includes this cookie and an incremented sequence number. The server can then reconstruct the connection state without having stored anything during the initialSYN-ACKexchange. This effectively offloads the state management to the client.
Let’s look at typical configurations and how to adjust them (on Linux):
To view current settings:
sysctl net.ipv4.tcp_max_syn_backlog
sysctl net.ipv4.tcp_syncookies
To increase the SYN backlog size (e.g., to 4096, a common value for busy servers):
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=4096
This change is temporary and will be lost on reboot. To make it permanent, add net.ipv4.tcp_max_syn_backlog = 4096 to /etc/sysctl.conf or a file in /etc/sysctl.d/.
To ensure SYN cookies are enabled (they usually are by default, value 1):
sudo sysctl -w net.ipv4.tcp_syncookies=1
Again, make this permanent in sysctl.conf if needed.
When SYN cookies are enabled, the server doesn’t just send a predictable SYN-ACK. It encodes information into the sequence number of the SYN-ACK. This sequence number isn’t just an incrementing value; it’s a cryptographic hash that includes the client’s IP address, the client’s port, the server’s port, and a secret key known only to the server. When the client sends back the final ACK, it includes this sequence number. The server can then decode this sequence number, verify its integrity, and if valid, use it to reconstruct the connection state. This means the server doesn’t need to store anything until it receives that valid ACK, making it incredibly resilient to SYN floods because it doesn’t waste memory on fake connections.
The next problem you’ll encounter is dealing with attacks that aren’t just about overwhelming the SYN backlog but also consume network bandwidth and application resources through more sophisticated means, like HTTP floods.