I recently have “honour” to be a part of the team which mitigated SYN flood attack to Czech news sites (of course not all, but one of the greatest and best). :)
You can read more about issue here in English or here in Czech.
Technical details about attack are now part of the investigation but basically this was form of a SYN flood based DDoS originating from Russia (we know it now, but we did not knew before). There were spoofed headers so it looked like traffic is going from many locations (e.g. Switzerland).
So, first and very brutal method is to block international traffic – you should consult this with upstream provider. It is always better for effectiveness to blackhole traffic on upstream routers. Unfortunately this helped only during phase one of attack.
But let’s dig deeper into a problem. How does this attack is created and realized?
I will use GNU/Linux based examples as I’m much better with this OS than with MS Windows. But concept applies to almost every OS.
SYN flood is based on resource exhaustion on target system (well, every DoS or DDoS is based on this concept).
Attacker achieves this by abusing thing called three way handshake, which means in normal conditions:
1. the client requests a connection by sending a SYN (synchronize) message to the server;
2. the server acknowledges this request by sending SYN-ACK back to the client;
3. the client responds with an ACK, and the connection is established.
This is kind a core of TCP communication (and I took it from Wikipedia).
A SYN flood attack works by not responding to the server with the expected ACK code. The malicious client can either simply not send the expected ACK, or by spoofing the source IP address in the SYN, causing the server to send the SYN-ACK to a falsified IP address – which will not send an ACK because it “knows” that it never sent a SYN. (this is from Wikipedia too, you can try to read it by yourself
There are a few countermeasures you can implement on your GNU/Linux box:
1. enable SYN cookies (this works on FreeBSD too):
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
2. check how many entries you have in your conntrack table:
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_count
3. check how much entries can be stored in your conntrack table:
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max
4. if you are lucky and you have dedicated GNU/Linux firewall you can adjust number of conntrack entries.
Basic formula: CONNTRACK_MAX = RAMSIZE (in bytes) / 16384 / (X / 32) where X is your number of bits in pointer (yes, it is 32 or 64 for most systems).
5. modify number of buckets in hash table. You can find it in:
cat /proc/sys/net/ipv4/netfilter/ip_conntrack_buckets
which is only read only alias for module parameters in:
cat /sys/module/ip_conntrack/parameters/hashsize
Formula for hashsize is: CONNTRACK_MAX = HASHSIZE * 8.
6. disable conntrack for certain destination IP and port
iptables -t raw -A PREROUTING -d <server IP> -p tcp --dport 80 -j NOTRACK iptables -t raw -A PREROUTING -s <server IP> -p tcp --sport 80 -j NOTRACK
I did not knew that there is this option and I could not switch conntrack completely off because I needed to do NAT (oh how I hate it) to keep production on-line.
During peak of the attack conntrack table has this kind of growth (there are some stupidities in graph as we have been adjusting settings without changing monitoring):
After communication with upstream provider, and with tuning of conntrack (especially disabling for HTTP traffic) problem was gone.
By the way, this kind of attack is pretty lame, and for media at all: this is not a hacking attack. You can’t spot real hack. ;)