K
K
Kirill Firsov2013-11-16 14:47:43
Debian
Kirill Firsov, 2013-11-16 14:47:43

How to block all SYN_RECV connections in iptables?

There is a terrible SYN-FLOOD on the server, it is necessary to block all SYN_RECV connections.
Now I just block by IP:

netstat -n4 | grep SYN_RECV  | awk {'print $5'} | awk -F ':' {'print $1'} | sort | uniq -c | awk {'print $2'} | xargs -t -l iptables -A INPUT -p tcp -j DROP -s

But there are already about 10k IPs in iptables and we need to do it differently.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
DerBlogger, 2013-11-16
@Isis

SYN_RECV is the state of the tcp connection during the three-handshake, meaning that the server has received a packet with the SYN flag (connection request) set, sent a SYN/SYN-ACK to the client, and is expecting a packet with the ACK flag from the client.
Since the ACK from the client (in our case, from the attacking host) does not come, the connection hangs until it is killed by timeout. As long as such a connection exists in the system, it consumes resources, which can create a precedent for slowing down the system.
Thus, in order to prevent such connections from being created, it is necessary to weed out from them objectionable beforehow the system allocates resources for them. In your case, you need to filter all incoming packets with the SYN flag set and drop those that do not suit us. A legitimate user will not create ten connections every second, but an attacker will.
Accordingly, you need to find out the pattern (frequency, number of requests, etc.) that allows you to distinguish between a legitimate host and an attacker in your particular case, and create rules in accordance with it.
Generally speaking, in your case, I think the problem can be solved using the recent module in iptables. I am sure that its functionality will be enough for you. You can get by with a few rules. The algorithm should be applied like this:
1. First, allow incoming tcp traffic on connections in the ESTABLISHED and RELATED states (conntrack module).
2. Open the necessary ports, allowing packets to pass according to these rules only if:
- the SYN flag is set (option --syn );
- the connection is in the NEW state (module conntrack );
- the limit of connections from one ip-address has not been exceeded ( recent module ).
More or less like this:

iptables -A INPUT -p tcp -m multiport --dports 80,443 --syn -m conntrack --ctstate NEW -m recent --name webtraffic --update --seconds 5 --hitcount 16 -j DROP

iptables -A INPUT -p tcp -m multiport --dports 80,443 --syn -m conntrack --ctstate NEW -j ACCEPT

The first rule will only be applied to packets with the SYN flag set, which come from a single IP address with a rate of more than 16 packets within 5 seconds. This rule will reject the flood.
The second rule will pass packets that do not match the previous rule (legitimate traffic).
Of course, everything needs to be adapted to your conditions and workload. See man iptables-extensions for details on modules . I strongly recommend that you read the description of the recent module for a better understanding.
3. Drop all other tcp traffic either with a separate rule or with the default policy.
Also, so that legitimate users are not thrown away when trying to connect, you can increase the queue of SYN packets in sysctl, in accordance with the available system resources. The net.ipv4.tcp_max_syn_backlog parameter is responsible for this , and to reduce the timeout for connections in the SYN_RECV state, which is the responsibility of the net.netfilter.nf_conntrack_tcp_timeout_syn_recv parameter .
Recommended parameters are individual for each system. I use these:
net.ipv4.tcp_max_syn_backlog = 262144
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 20

E
EvilMan, 2013-12-17
@EvilMan

The new kernels have SYN-PROXY support, which can help YOU a lot.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question