iptables ddos configuring recent, prevent denial of service attacks (DOS Denial Of Service) Linux (Match recent extension)

Recently has contacted me a companion called Miguel Angel (greetings) to see if he could help out with attacks that are suffering. Obviously I will not use your data for anything in this entry.

In this post we will make a more accurate filtering of incoming communications, to prevent DOS attacks.

In the previous post “iptables ddos limit configuration, prevent denial of service attacks on Linux (Match extension limit)” is shown as filter limiting the number of hits. The great improvement in recent vs limit extension is that recent maintains a list of source IPs communication and limits are set by source IP. The limits imposed limit extension regardless of origin, is an overall limit.

 

An example of a filter for port 22 would be:

Source   
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name port_22 --set -m comment --comment "Begin filtering 22 "
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name port_22 --update --seconds 3600 --hitcount 5 -j LOG --log-prefix "Attack DDOS port 22 "
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name port_22 --update --seconds 3600 --hitcount 5 -j REJECT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m comment --comment "End filtering 22 " -j ACCEPT

What do these lines is:

1- Add the IP (–set option) to “port_22” list, a new communication. If there ip updated list.

2- Upgrade the IP (–update option) in the “port_22” list, sets a limit than 3600 seconds (option –seconds 3600), with a number of hits allowed 5 (option –hitcount 5) and finally writes in the log (-j lOG) the attempted attack. This line does not cut the incoming communication only written to the log.

3- This line is just like line 2, but modifying the target (-j REJECT). This is where communication is rejected if the limit of 5 connections 3600 seconds from the same IP is exceeded.

4- If execution reaches this line is that it has not exceeded the limit, therefore we accept the incoming communication.

In summary this is a typical case of filtering pretty hard, five connections every 3600 seconds from the same IP. In the case of the port 22 is a good limit, because administrative access are few and usually the manager knows what he writes and makes no mistakes on trivialities such as password or user.

The limits must be carefully set them obviously real size them to the number of requests required by the port (eg 80). We also have to be careful because we may have many clients accessing through a NAT, for practical purposes all these communications will be made from the same IP.

A script of one of the servers I manage:

Source   
#!/bin/bash
iptables -F
iptables -A INPUT -m state --state ESTABLISHED,RELATED -m comment --comment "Allow existent connections" -j ACCEPT
iptables -A INPUT -i lo -m comment --comment "Allow internal connetions" -j ACCEPT
iptables -A INPUT -p icmp -m comment --comment "Deny ping " -j REJECT
iptables -A INPUT -m state --state NEW --source 62.64.12.40/32 -m comment --comment "Deny this extenal IP" -j REJECT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW --source 192.168.0.0/28 -m comment --comment "Allow network segment port 22" -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW --source 62.67.18.45/32 -m comment --comment "Allow external IP port 22" -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name port_22 --set -m comment --comment "Begin filtering 22 "
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name port_22 --update --seconds 3600 --hitcount 5 -j LOG --log-prefix "Attack DDOS port 22 "
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name port_22 --update --seconds 3600 --hitcount 5 -j REJECT
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m comment --comment "End filtering 22" -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -m state --state NEW -m recent --name port_53 --set -m comment --comment "Begin filtering 53 "
iptables -A INPUT -p tcp --dport 53 -m state --state NEW -m recent --name port_53 --update --seconds 1 --hitcount 10 -j LOG --log-prefix "Attack DDOS port 53 "
iptables -A INPUT -p tcp --dport 53 -m state --state NEW -m recent --name port_53 --update --seconds 1 --hitcount 10 -j REJECT
iptables -A INPUT -p tcp --dport 53 -m state --state NEW -m comment --comment "End filtering 53" -j ACCEPT
iptables -A INPUT -p udp --dport 53 -m state --state NEW -m recent --name port_53_udp --set -m comment --comment "Begin filtering 53 udp"
iptables -A INPUT -p udp --dport 53 -m state --state NEW -m recent --name port_53_udp --update --seconds 1 --hitcount 10 -j LOG --log-prefix "Attack DDOS port 53 udp "
iptables -A INPUT -p udp --dport 53 -m state --state NEW -m recent --name port_53_udp --update --seconds 1 --hitcount 10 -j REJECT
iptables -A INPUT -p udp --dport 53 -m state --state NEW -m comment --comment "End filtering 53 udp" -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --name port_80 --set -m comment --comment "Begin filtering 80 "
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --name port_80 --update --seconds 60 --hitcount 30 -j LOG --log-prefix "Attack DDOS port 80 "
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m recent --name port_80 --update --seconds 60 --hitcount 30 -j REJECT
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m comment --comment "End filtering 80 " -j ACCEPT
iptables -A INPUT -p tcp --dport 81 -m state --state NEW -m recent --name port_81 --set -m comment --comment "Begin filtering 81 "
iptables -A INPUT -p tcp --dport 81 -m state --state NEW -m recent --name port_81 --update --seconds 60 --hitcount 30 -j LOG --log-prefix "Attack DDOS port 81 "
iptables -A INPUT -p tcp --dport 81 -m state --state NEW -m recent --name port_81 --update --seconds 60 --hitcount 30 -j REJECT
iptables -A INPUT -p tcp --dport 81 -m state --state NEW -m comment --comment "End filtering 81 " -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -m recent --name port_443 --set -m comment --comment "Begin filtering 443 "
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -m recent --name port_443 --update --seconds 60 --hitcount 30 -j LOG --log-prefix "Attack DDOS port 443 "
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -m recent --name port_443 --update --seconds 60 --hitcount 30 -j REJECT
iptables -A INPUT -p tcp --dport 443 -m state --state NEW -m comment --comment "End filtering 443" -j ACCEPT
iptables -A OUTPUT -m comment --comment "Allow outgoing connections" -j ACCEPT
iptables -A FORWARD -m comment --comment "Allow forward connections" -j ACCEPT

Once activated the rules depending on the distribution of Linux, the default is logged in a file or another:

  • Red Hat, CentOS, Fedora in /var/log/messages
  • Debian, Ubuntu in /var/log/kern.log

If we review the log frequently, we know the IPs that we are attacking and add a rule to reject communication from specific IP with:

Source   
iptables -A INPUT -m state --state NEW --source 62.64.12.40/32 -m comment --comment "Deby this external IP" -j REJECT

Again, it is highly recommended to look at iptables man.

Miguel Angel from what I’ve seen you have in your filter systems using recent, but only for port 80 and not written to the log the attempt.

For this reason you can not identify the source IP, and therefore we can not add a rule rejecting this IP in the first place.

The filtering is done in all open ports and writing information to log.

I hope it helps you.

Leave a Reply