[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Package to block random SSH login attempts?



Is there any Debian package (or free software outside of Debian) that can
detect random ssh login attempts and blacklist (temporarily or
permanently) the IP address?

portsentry is similar but not quite on point.  As I understand it,
portsentry will block port scanners, but not people attempting random
logins.

What I'd like to do is block a particular IP address if there are more
than, say, 5 attempted logins from nonexistent usernames, and more than
10 failed logins from existent usernames.

I've written the following little hack to do it, but I don't particularly
like running untested hacks as root, and also it'd be preferable if the
blacklisting could happen immediately, rather than as an occasional cron
job.

Thanks for any tips, or critiques of my script:

#!/bin/sh

# maximum attempts for a nonexistent username before the IP address is blocked
MAX_ILLEGAL=3

# maximum attempts for an existent username befroe the IP address is blocked (more generous)
MAX_LEGAL=10

# IP addresses to never block--let's make sure we don't lock ourselves out
DONT_BLOCK='127.0.0.1'

# timestamp for hosts.deny
now=`date -R`

# make sure no one can touch the blocking files other than root
umask 0077

grep "Failed password" /var/log/auth.log | sed "s/^.*Failed password for //g" > recent_failures
grep "illegal user" recent_failures | sed -e "s/^.*[ :]\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)/\1/" -e "s/ .*//g" | grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | sort | uniq -c | sed -e "s/^ *//g" -e "s/ /_/g" > recent_illegals
grep -v "illegal user" recent_failures | sed -e "s/^.*[ :]\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)/\1/" -e "s/ .*//g" | grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" | sort | uniq -c | sed -e "s/^ *//g" -e "s/ /_/g" > recent_legals

for x in `cat recent_illegals | grep -v $DONT_BLOCK`
do
  attempts=${x%_*}
  ip=${x#*_}
  if [ $attempts -ge $MAX_ILLEGAL ]
  then
     if ( ! grep -q $ip /etc/hosts.deny )
     then 
        lookup=`host $ip`
        if ( echo $lookup | grep -q "not found" )
        then
           lookup=`whois $ip | grep -i "name" | head -1`
        fi
        echo \# $now >> /etc/hosts.deny
        echo \# $lookup >> /etc/hosts.deny
        echo \# $attempts failed attempts at nonexistent username >> /etc/hosts.deny
        echo ALL: $ip >> /etc/hosts.deny
        echo >> /etc/hosts.deny
        logger -t password_attempt_checker Banning $ip for nonexistent username attempts.
     fi
  fi
done

for x in `cat recent_legals | grep -v $DONT_BLOCK`
do
  attempts=${x%_*}
  ip=${x#*_}
  if [ $attempts -ge $MAX_LEGAL ]
  then
     if ( ! grep -q $ip /etc/hosts.deny )
     then 
        lookup=`host $ip`
        if ( echo $lookup | grep -q "not found" )
        then
           lookup=`whois $ip | grep -i "name" | head -1`
        fi
        echo \# $now >> /etc/hosts.deny
        echo \# $lookup >> /etc/hosts.deny
        echo \# $attempts failed attempts at valid username >> /etc/hosts.deny
        echo $ip >> /etc/hosts.deny
        echo >> /etc/hosts.deny
        logger -t password_attempt_checker Banning $ip for bad password attempts.
     fi
  fi
done
-- 
Adam Rosi-Kessel
http://adam.rosi-kessel.org



Reply to: