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
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.