Thursday 1 September 2016

Protection against SYN Flooding with SYNPROXY

The problem: SYN Flood attacks (while quite unsophisticated in nature) can be devastating to systems that do not have the relevant protection mechanisms in place - the basic premis behind a SYN flood attack is to exhaust the connection state table with invalid (or partially established handshakes) from (more often than not) spoofed sources.

For example

A synproxy is a mechanism for protection against SYN flooding and is built into (or implemented rather) many popular firewalls like iptables / pfsense (pf) and so on.

The basic principle of a synproxy is as follows:

1. The client send an initial SYN to the server.

2. When this packet hits the firewall on the server it is marked with an 'UNTRACKED' state.

3. A SYN ACK is sent back to the client and then upon the final ACK from the client the connection is validated.

4. If the connection is valid the synproxy then automatically initiate a three-way handshake with the real server (e.g. apache) by spoofing the SYN packets so that the real server will see the connecting client. Otherwise the connection will be marked as 'INVALID' and be dropped.

5. Communication is then left for the client and real server to perform between themselves.

We can setup synproxy with iptables as follows (we will use apache running on port 80 in this example):

we need to tweak the kernel by ensuring that the connection tracking system is stricter it it's categorization:

sudo sysctl -w net/netfilter/nf_conntrack_tcp_loose=0

and tcp timestamps:

sysctl -w net/ipv4/tcp_timestamps=1

and finally ensured it survives a reboot:

sysctl -p

Proceed by ensuring that the packets destined for apache are not tracked:

sudo iptables -t raw -A PREROUTING -i eth0 -p tcp --dport 80 --syn -j NOTRACK

And then redirect the traffic destined for apache to synproxy:

iptables -A INPUT -i eth0 -p tcp -m tcp --dport 80 -m state --state INVALID,UNTRACKED -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460

and instruct iptables to drop any invalid packets with:

sudo iptables -A INPUT -m state --state INVALID -j DROP

Increasing the connection table capacity in CentOS 7

Another consideration is to increase the connection tracking table capacity - firstly by increasing the has size (this is for RHEL/CentOS):

echo 1200000 > /sys/module/nf_conntrack/parameters/hashsize

and then setting the table size:

sudo sysctl net.netfilter.nf_conntrack_max=2000000

(My default on Debian 8 was 15388 and on CentOS 7 262144)

Note: On Debian systems I had to load the nf_conntrack module by adding a reference to 'nf_conntrack' within /etc/modules and reboot the system for changes to take effect.



Post a Comment