A ``SYN flood'' is a Denial of Service attack that takes advantage of the TCP ``three way handshake'' protocol. A SYN is a type of TCP packet sent to initiate a connection with a listening TCP port. The port responds with a SYN/ACK to the initiating port, and places the SYN packet in a partial connections queue. When a corresponding ACK packet is received on the listening port, the validated SYN packet is removed from the partial connections queue and an entry is placed in the established connection queue awaiting a socket connection.
A SYN flood occurs when one or more listening TCP ports are sent large numbers of SYN packets. Such attacks could take various forms, most of which do not adversely affect the attacked system. However, the most potentially harmful attack sends SYN packets in which the client address refers to a system which does not exist. In this case, SYN packets remain in the TCP partial connection queue for each listening port that is attacked, unable to complete because the SYN/ACK cannot be routed to a bogus address. If the queues are too small and packets awaiting response remain on the queues, the TCP stack refuses to accept any connections until the bogus packets have timed out.
You can control the size of the TCP queues by setting the tcp_q0limit parameter with the inconfig(ADMN) command. When tcp_q0limit is set to a value greater than 0:
You can safely raise the tcp_q0limit value during an attack.
In the event of an attack, you should ensure that legitimate requests remain in a queue long enough to receive responses and get passed to the established connections queue. The higher the tcp_q0limit value, the less likely legitimate packets will be dropped. However, low-speed or high-latency links increase the time a packet must wait in a queue for response, and slower connections will be at greater risk during an attack.
To estimate a prudent value for tcp_q0limit, you can calculate ``attacks per turnaround''; that is, a function of the rate of attack (bogus SYN packets received per second) and the time required for a legitimate SYN packet to receive a response. You can measure the rate of attack with a packet sniffer. You can estimate the response time by collecting a representative sample of legitimate addresses and sending ping packets to each (SYN/ACK turnaround is probably quicker than ping turnaround given their higher priority of transmission). This will tell you the ``survival rate'' of a client's connection at a given tcp_q0limit value.
If S is the attack rate in packets/millisecond, T is the turnaround
time of a particular client in milliseconds, and Q is the value
of tcp_q0limit, the survival rate of the client's
connection can be calculated as:
R1, survival rate during a single attack = ((Q - 1) / Q)
A, attacks during turnaround = T * S
R, survival rate = R1 ^ A = ((Q - 1) / Q) ^ (T * S)
For example, if bogus SYN packets arrive at a rate of
2000/second or S = 2/millisecond, and a particular client's
turnaround T is 300ms, 600 attacks (A = S * T) arrive while that
client's connection is partially open. If tcp_q0limit
is set to Q = 450, the survival rate would be:
R1 = ((450 - 1) / 450) = 0.9978
R = ((450 - 1) / 450) ^ 600 = 0.2632
or about 26.3%. Increasing tcp_q0limit to 900 would yield:
R1 = ((900 - 1) / 900) = 0.9989
R = ((900 - 1) / 900) ^ 600 = 0.5132
or about 51.3%.
The memory costs of these values depend on the number of listening ports configured. At least 800 bytes are allocated for each partial connection, so the memory consumption = tcp_q0limit value * number of ports * 800. If in this example you had 100 listening ports configured, setting tcp_q0limit to 450 would consume 36MB of memory, while increasing it to 900 would consume 72MB. Note that:
For more information, see
``Using inconfig to change global TCP/IP parameters''
RFC 793 describes the TCP
``Obtaining RFCs from the Internet''.