SYN cookie is a technique used to resist SYN flood attacks. The technique's primary inventor Daniel J. Bernstein defines SYN cookies as "particular choices of initial TCP sequence numbers by TCP servers." In particular, the use of SYN cookies allows a server to avoid dropping connections when the SYN queue fills up. Instead of storing additional connections, a SYN queue entry is encoded into the sequence number sent in the SYN+ACK response. If the server then receives a subsequent ACK response from the client with the incremented sequence number, the server is able to reconstruct the SYN queue entry using information encoded in the TCP sequence number and proceed as usual with the connection.
To initiate a TCP connection, the client sends a TCP SYN packet to the server. The server responds with a TCP SYN+ACK packet, which includes a sequence number used by TCP to reassemble the data stream. According to the TCP specification, the initial sequence number sent by an endpoint can be any value chosen by that endpoint. Since this sequence number is chosen by the sender, returned by the recipient, and has no predefined internal structure, it can be overloaded to carry additional data. The following outlines one possible implementation, though there is no public standard, so the order, length, and semantics of the fields may vary between SYN cookie implementations.
SYN cookies are initial sequence numbers that are carefully constructed according to the following rules:
The initial TCP sequence number, i.e. the SYN cookie, is computed as follows:
(Note: since m must be encoded using 3 bits, the server is restricted to sending up to 8 unique values for m when SYN cookies are in use.)
When a client sends back a TCP ACK packet to the server in response to the server's SYN+ACK packet, the client must (according to the TCP spec) use n+1 in the packet's Acknowledgement number, where n is the initial sequence number sent by the server. The server then subtracts 1 from the acknowledgement number to reveal the SYN cookie sent to the client.
The server then performs the following operations.
From this point forward, the connection proceeds as normal.
Simple firewalls that are configured to allow all outgoing connections but to restrict which ports an incoming connection can reach (for example, allow incoming connections to a Web server on port 80 but restrict all other ports), work by blocking only incoming SYN requests to unwanted ports. If SYN cookies are in operation, care should be taken to ensure an attacker is not able to bypass such a firewall by forging ACKs instead, trying random sequence numbers until one is accepted. SYN cookies should be switched on and off on a per-port basis, so that SYN cookies being enabled on a public port does not cause them to be recognised on a non-public port. The original Linux kernel implementation misunderstood this part of Bernstein's description and used a single global variable to switch on SYN cookies for all ports; [2] this was pointed out by a research student [3] and subsequently fixed in CVE - 2001-0851. [4]
The technique was created by Daniel J. Bernstein and Eric Schenk in September 1996. The first implementation (for SunOS) was released by Jeff Weisberg a month later, and Eric Schenk released his Linux implementation in February 1997. FreeBSD implements syncookies since FreeBSD 4.5 (January 2002). [5]
static unsigned long tcp_lastsynq_overflow
The solution (as pointed out by D. J. Bernstein in a private communication in response to the above) is to make the variable tcp_lastsynq_overflow local to each listening port, instead of being a global.