Using Iptables To Block Brute Force Attacks

Ssh...

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 between successful 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):

cat /proc/net/ipt_recent/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.