honesty makes me have to say that I didn't read all 12 pages, skipped the middle part, so this post might make no sense at all. Please ignore if so.
I also noticed the SSH stuff, and I made a script to kick them out for a day after 15 attempts. I know it's *no* protection mechanism, so please look 2 posts up and do what's said there, but following the 90% reasoning: the script just reduces the chance that they might succeed a little, and just reduces the mess in your /var/log/messages or /var/log/auth.
To run this script you will need a working iptables and 'at' (emerge at).
Code: Select all
#!/bin/sh
# vim:ts=4:sw=4:tw=0
# Ruurd Koons 24th April 2005
# This script scans for failed login attempts and pushes the IP of
# frequent failing clients on the iptables list, which are removed
# using an at job afterwards. The main purpose of this script is
# to stop ssh login attacks in an early stage of the process.
# Design note: it seems that a grep in front of awk activates input
# buffering, which delays the actual awk processing. The piped
# greps below are only because of this reason done in awk itself.
# grep sshd | grep "Failed password" | grep -o -e "\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}" |
SCANFILE="/var/log/messages";
LOGFILE="/var/log/banned_scanners";
if [ "$1" != "" ];
then
comm="$1";
else
comm="tail --max-unchanged-stats=5 --follow=name $SCANFILE";
fi
if [ "$2" == "-d" ];
then
debug=1;
else
debug=0;
fi
$comm | awk -v debug="$debug" -v logfile="$LOGFILE" '
BEGIN { treshold = 15; timeout = 30 * 60; }
{
if ($5 ~ /^sshd\[[0-9]+\]:$/ &&
$0 ~ /Failed password/ &&
$(NF - 3) ~ /[0-9]([0-9][0-9]?)?\.[0-9]([0-9][0-9]?)?\.[0-9]([0-9][0-9]?)?\.[0-9]([0-9][0-9]?)?$/)
{
$0 = $(NF - 3);
if ($0 ~ /^::ffff:/) $0 = substr($0, 8);
if (debug + 0 != 0) print $0, attempt["count"$0], attempt["time"$0];
attempt["count"$0] += 1;
if (systime() - attempt["time"$0] > timeout) {
attempt["count"$0] = 1;
}
attempt["time"$0] = systime();
if (attempt["count"$0] > treshold &&
$0 !~ /0+\.0+\.0+\.0+/ &&
$0 !~ /255/)
{
if (debug + 0 == 0) {
print systime() " " $0 >> logfile;
system("iptables -A INPUT -j DROP --source " $0);
system("echo iptables -D INPUT -j DROP --source " $0 " | at now + 1 day >& /dev/null");
} else {
print systime() " " $0;
}
attempt["time"$0] = null;
attempt["count"$0] = null;
}
}
}
END { }
' &
The log that is written allows for later use such as permanent banning of returning IP's or distribution between serveral hosts in for instance a university network.
To recap what the script does:
- it adds the IP to the iptables INPUT chain when an IP fails to login using SSH
* over 15 times
* within 30 minutes
- the 'ban' lasts currently one day
- the ban is recorded in a small logfile, where the IP is prepended by the current UNIX epoch time
The main reason to ban only for a day is to keep the iptables chain small, as it will grow rapidly if you ban all, and most of them never come back after a day (from my experience).
I thought I'd share my script, maybe someone likes it also.
Cheers!