Why Your HTTP Server Can’t Block SYN Floods (And What You Can Do)
SYN floods are back in vogue. As DDoS-ing becomes more and more of an industry and the resources necessary for an effective attack become more accessible, SYN flooding has become more popular. Unfortunately, LiteSpeed Web Server (or Apache or Nginx or Lighttpd or Cherokee or Jetty or Tomcat or …) can’t help you with SYN floods. Here’s why and what you can do (including signing up for our free anti-DDoS proxy service): (Check our wiki for simple steps to hardening your kernel against SYN floods. Both the wiki and this article are geared toward hardening a Linux kernel only.)
When SYN Met ACK
SYN floods work by abusing your system’s normal steps for establishing a connection. Normally, a connection is established first at the TCP level and then at the HTTP level. The first thing that happens is the TCP handshake:
1. The client sends a message requesting a connection. This is called a SYN (for synchronize) message.
2. Your kernel sends a SYN-ACK reply, acknowledging the request.
3. The client sends an ACK reply, acknowledging the acknowledgment.
Only after this 3-step TCP handshake is a connection established. Once a connection has been established, the client sends an HTTP request that starts the HTTP-level connection with your HTTP server (be it LSWS or any other server).
The Cold Shoulder
In a SYN flood, your server is bathed in a wash of SYN messages. Your server kernel, the trusting fellow that it is, responds to all these messages in good faith and waits for the clients to make their ACK reply so the connection can be established. The DDoS-ing clients, however, never respond with the third step of the handshake. Instead, they keep sending SYN messages. So your server gets flooded with useless SYN messages while waiting for acknowledgement from clients that never plan on replying. Your socket backlog gets filled up and your system started denying TCP connection requests. And your HTTP server can’t do anything, because none of these connections are even making it to the HTTP level.
Harden Your Heart
The basic trick to blocking SYN floods is getting your kernel to treat connection requests more lightly and give up on requests more quickly. There are three settings that are useful for this: (Quick steps to configuring these settings are found in our wiki.)
- SYN cookies — When your system is under duress, it can start using SYN cookies as an alternative to storing SYN messages: Instead of storing the SYN message and waiting for an ACK response that matches that SYN message, the server can send a cookie with every SYN-ACK response it sends. When a non-DDoS-ing client then sends an ACK message, this message will contain information from the cookie and allow the system to recreate the original SYN message. This allows your system to not get hung up on SYN messages that are never followed up on. (Note: SYN cookies are a method of dealing with SYN floods. Because of the encoding required and because they do not allow many TCP options, SYN cookies are inherently less efficient. Your SYN backlog setting should be set high enough to make sure they are not used for normal traffic.)
- SYN backlog — SYN backlog is the queue of SYN messages you have that are still in the handshake process. Without SYN cookies, when your SYN backlog max is reached, your server will start turning away TCP connection requests. If SYN cookies are enabled, your system will start using SYN cookies when the backlog limit has been met. (Set this limit high enough to make sure SYN cookies are not used for normal traffic.)
- SYN-ACK retries — When the system does not receive a response to it’s SYN-ACK message, it will try again. Lowering the number of times your server retries will allow you to work through attacking SYN messages faster.
Use the following commands to set these values on your current system:
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 2048 > /proc/sys/net/ipv4/tcp_max_syn_backlog
echo 3 > /proc/sys/net/ipv4/tcp_synack_retries
Then add these settings for your /etc/sysctl.conf file to make them persist even after reboot:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 3
Give Them the Wrong Number
The settings listed above will help with less powerful SYN floods, but your kernel is probably just not equipped to deal with really high volume attacks. If you find yourself the target of especially powerful SYN floods, you probably need to enlist a service that will send your traffic to a server specially set up for the job. There are a myriad of such services out there, many costing a pretty penny. If you know the domain being attacked, try our free anti-DDoS proxying first. It allows you to reroute traffic from one domain to our servers for filtering.