Hardening your TCP/IP Stack Against SYN Floods
Denial of service (DoS) attacks launch via SYN floods can be very problematic for servers that are not properly configured to handle them. Proper firewall filtering policies are certainly usually the first line of defense, however the Linux kernel can also be hardened against these types of attacks. This type of hardening is useful for SYN floods that attempt to overload a particular service with requests (such as http) as opposed to one that intends to saturate the server’s network connection, for which a firewall is needed to guard against.
Definition of a SYN Flood
TCP connections are established using a 3-way handshake. Attackers desiring to start a SYN flood will spoof their IP address in the header of the SYN packet sent to the server, so that when the server responds with it’s SYN-ACK packet, it never reaches the destination (from which an ACK would be sent and the connection established). The server leaves these unestablished connections in a queue for a pre-determined period of time after which they are simply discarded. However if enough of these “fake” connections gum up the queue (backlog) , it can prevent new, legitimate requests from being handled. Linux has a relatively small backlog queue by default, and keeps half-open requests in the queue for up to 3 minutes! Thus the need for tweaking the way the Linux kernel handles these requests is born.
Protecting your Server
The Linux kernel allows you to directly change the various parameters needed to mitigate against SYN flood attacks
This sets the kernel to use the SYN cookies mechanism , use a backlog queue size of 2048 connections, and the amount of time to keep half-open connections in the queue (3 equates to roughly 45 seconds).
Making the Changes Persist
To make these changes persist over consecutive reboots, we need to tell the sysctl system about these modified parameters. We use the /etc/sysctl.conf file to do so. We will add the following lines to the bottom of the file:
# TCP SYN Flood Protection
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 3