Almost 24 hours per day, The Linux Fix is inundated with FTP and SSH brute force attempts to our server farm. This has compromised a few our our customer’s accounts from time to time, and I decided it was time to come up with a solution.
The problem is tricky–we must leave FTP and SSH open to the entire world, but at the same time be selective on what we black list. How do you make that determination? Strictly on bad login credentials?
We could, but that would mean that we’d inadvertently lock out real users. A better solution we found has to do with timing connection attempts. With IPTables, we can keep a counter based upon source IP–and track how many new socket attempts are made within a certain span of time. For instance, if we detect the IP address 1.2.3.4 making 5 connection attempts within 60 seconds, there is a darn good chance it isn’t someone mistyping a password.
Here is how we did it, based upon another script we found out in the Internets:
#!/bin/bash /sbin/iptables -N SSH /sbin/iptables -N SSH_BLACKLIST /sbin/iptables -A SSH_BLACKLIST -m recent --name SSH_COUNTER --set -j LOG --log-level warn --log-prefix "Blocked: " /sbin/iptables -A SSH_BLACKLIST -j REJECT /sbin/iptables -A SSH -m recent --name SSH_COUNTER --update --seconds 300 -j REJECT /sbin/iptables -A SSH -m recent --name SSH --rcheck --seconds 60 --hitcount 5 -j SSH_BLACKLIST /sbin/iptables -A SSH -m recent --name SSH --rcheck --seconds 2 -j LOG --log-level warn --log-prefix "Added: " /sbin/iptables -A SSH -m recent --name SSH --update --seconds 2 -j REJECT /sbin/iptables -A SSH -m recent --name SSH_COUNTER --remove -j LOG --log-level warn --log-prefix "Removed: " /sbin/iptables -A SSH -m recent --name SSH --set -j ACCEPT /sbin/iptables -A INPUT -m state --state NEW -p tcp -m tcp --dport 22 -j SSH
This creates two new tables, SSH and SSH_BLACKLIST. Upon the intial connection attempt, the IP is added to the SSH_COUNTER counter. If the same IP address is seen again within 60 seconds, it is duly noted–however no action is taken until the hitcount reaches 5. In that case, the rules jump to the SSH_BLACKLIST table, it is logged, and subsequent connections from that IP are dropped for 5 minutes until things calm down. In order to do this for FTP, just rename the targets as appropriate and change the target port to 21 on the last line.
The nice thing about this set up is that it is auto-cleaning. After 5 minutes of no activity, the counter forgets about the IP address and things return to normal. We’ve found that this is just enough protection to drastically reduce bruteforce attempts, yet not get in the way of normal usage by our customers. Over time, this has become our favorite technique and we’ve begun to implement it on any Internet-facing machine with open SSH ports.

Recent Comments