We can use the iptables recent module to write some iptables rules that can block brute force attacks. In order to use this method you need a kernel and iptables installation that includesipt_recent. If your linux distribution doesn’t include the ipt_recent module or you are using a custom compiled kernel you might need to first include the iptables recent patch that can be found on the author’s website or in the iptables patch-o-matic area. If you are using Debian/Ubuntu you don’t need to do anything special as this is already included in your system.
Let’s see how we can use the iptables recent module to block brute force attacks agains ssh. Let’s see a simple example:
iptables -N SSHSCAN iptables -A INPUT -p tcp --dport 22 -m state **--state NEW** -j SSHSCAN iptables -A SSHSCAN -m recent --set --name SSH iptables -A SSHSCAN -m recent --update **--seconds 300** **--hitcount 3** --name SSH -j DROP
This will basically allow only 3 NEW connections (as matched by the state NEW) in the timeframe of 300sec (5min). Any new connection will be automatically dropped.
The main disadvantage of using this method is that it will not make any distinction betweensuccessful and failed logins. If you are not careful and open too many connections yourself you might found yourself locked out. One walk-around for this issue is to whitelist our own administrative ips (still if we can do this for all the locations that need to connect to the system, then we can protect ourselves with simple firewall rules and we don’t need this added complexity). So at least for the hosts that we can (static ips) we should do this (replace with as many lines needed containing $WHITE_LIST_IP):
iptables -N SSHSCAN ** iptables -A INPUT -p tcp --dport 22 -s $WHITE_LIST_IP -j ACCEPT** iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSHSCAN iptables -A SSHSCAN -m recent --set --name SSH iptables -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
Even if we lock ourselves out, our existing connections will remain up since we are matching only on NEW connections. If needed we can take appropriate actions.
In case we want to have the blocked hosts logged, then we will have to add another iptables rule:
iptables -N SSHSCAN iptables -A INPUT -p tcp --dport 22 -s $WHITE_LIST_IP -j ACCEPT iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSHSCAN iptables -A SSHSCAN -m recent --set --name SSH iptables -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-level info --log-prefix "SSH SCAN blocked: " iptables -A SSHSCAN -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP
You can peek at the internal database kept by the module, by looking inside:/proc/net/ipt_recent/* (DEFAULT will contain default matches; in our example the name of the file is SSHSCAN):
This solution is very effective and easy to implement. You just add the needed iptables rules to your existing firewall setup and you are set. Still, it has many limitations when compared with the other methods shown: like limited time frames, it will not differentiate against failed/successful logins, etc.