A script to add ssh attackers to the iptables drop list
I have had significant attacks, up to five per day, that are automated against my sshd. I need to keep sshd up as I often access my mail and other items from away sites. But I don't want others to access my site. I have in my AllowUsers only my personal and selected other user accounts that need outside/in access. I specifically excluded root as a possible access.
But it concerned me when automated ssh logins are attempted (obviously just running a brute force log-in script.) Most of these try root, test, administrator or some such user early in the attack, and I put a script up to tail the /var/log/secure file and DROP those connecting IPs (using iptables).
Perusing the past few month's activity, I've noticed that most of these attacks came from sites without reverse DNS zones, and caused many entries in the log (AUTHPRIV) like this:
" ... Could not reverse map address 184.108.40.206. "
using an automated login attempt script as the times were very closely contiguous with user names arranged in a sort order.
As I sometimes log in from an unresolvable ip address, I set up a script to allow only three failed log in attempts before locking that particular ip out of my machine permanently. As I wanted them out even over reboots, a file of these badactors is included in my root directory and included in my iptables set up script run during bootup.
From resolvable ips, I still got automated scripts with lots of user names. I then added a section to limit bad login names to five (thinking that I have had bad terminals in countries that use odd keyboards and have had troubles getting my own login correct.)
My system includes three pieces: an awk script to detect attacks, a bash script to update (append to DROP chain) and a bash script to tie it all together. Updating to more recent packages have caused some minor changes in these scripts over the years, mostly in the field locations output from the secure tail. A recent change in Fedora 9 to rsyslog from syslog required a change to rsyslog.conf. And the newer inotail in lieu of tail required the the weekly cron logrotate make the log rotation a copy-truncate operation instead of the default mv. ( I felt the inotail state change was less expensive in cpu use than tail polling.)
Note that it is necessary to add an iptables entry early in your INPUT chain to -j to a new chain called badactors. I set this up like this:
echo "--------------Check for demonstrated Bad Actors Hacks attempted --------------------"
$IPTABLES -F badactors > /dev/null 2>&1 || $IPTABLES -N badactors
echo " badactors are dynamically added when found -- Flushed on restart "
$IPTABLES -A INPUT -i $LOCALIF -j badactors
And I populate it with this on reboot:
# Insert previous badactors if existing in /root
[ -f /root/badactors ] && . /root/badactors
This "badactors" file grows with time and very few offenders repeat after a day or two. I just edit the file and delete fifty or a hundred of the earlier entries. If they return, they will be added again.
Adding DROP entries to iptables keeps my machine free of these annoying interlopers.
As a second tier defense, I have added an "AllowUsers" argument keyword to my sshd_config listing all users that are allowed to login through ssh. If the firewall is breached, this entry restricts the application. A very recent addition is the last section of the awk script trying to detect what was called on one security list a "slow and low" attack. This section was added 9/9/08 and has not caught an attacker yet. I am not sure it works or that it is even useful if it should work. I do prefer to drop attackers at the firewall in case they have other applications in mind to attack. I consider the firewall my first defense.