Search code examples
sshfirewalliptables

iptables SSH brute force protection


I have an iptables firewall with the default INPUT policy set to DROP. I'm using this for slowing down SSH brute force attempts. The problem is that if I leave the last line in, the previous rules don't trigger and all SSH traffic is accepted. If i leave it out, packets from bad IPs get dropped, but I also can't connect to SSH myself. To my understanding, iptables is sequential, so it should only reach the last rule if it hasn't triggered any of the previous rules. What I am trying to say in the last line is "if your IP isn't on the SSH_BRUTEFORCE list, go on through. What am I doing wrong ?

iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP

iptables -N SSHSCAN

iptables -A INPUT -i ens3 -p tcp -m tcp --dport 22 -m state --state NEW -j SSHSCAN

iptables -A SSHSCAN -m recent --set --name SSH_BRUTEFORCE --rsource
iptables -A SSHSCAN -m recent --update --seconds 360 --hitcount 10 --name SSH_BRUTEFORCE --rsource -j LOG --log-prefix "Anti SSH-Bruteforce: " --log-level 2
iptables -A SSHSCAN -m recent --update --seconds 360 --hitcount 10 --name SSH_BRUTEFORCE --rsource -j DROP
iptables -A SSHSCAN -m recent --rcheck --name SSH_BRUTEFORCE -j ACCEPT

Solution

  • You can start with rate-limiting for example:

    /usr/sbin/iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set /usr/sbin/iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

    If you want to log the drops then

    /sbin/iptables -N LOGDROP

    /sbin/iptables -A LOGDROP -j LOG

    /sbin/iptables -A LOGDROP -j DROP

    iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set

    iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j LOGDROP

    source is here https://www.rackaid.com/blog/how-to-block-ssh-brute-force-attacks/

    Also I would recommend to move the default port to something else and like @larsks suggested I would deny login with password and only accept keys.