#!/bin/sh

##################################################
#                    SSHD Audit                  #
#                                                #
# Last update: 10/04/2006                        #
# Version: 1.01                                  #
##################################################

SSHD_LOG=/var/log/auth.log
TEMP_FILE=/tmp/ip_ban
TAIL_LIMIT=100
ALLOWED_FAIL=4
IP_MEMORY=20
MAIL_TO=root@localhost
MAIL_SUBJ="SSHD Audit"

# Nothing to be modified below this line.

PATH=/bin:/sbin:/usr/bin:/usr/sbin

umask 077

if [ ! -f $TEMP_FILE ]; then
	touch $TEMP_FILE
fi

IP_TABLE=`tail -n $TAIL_LIMIT $SSHD_LOG | grep "Failed password" | sed 's/.*from //' | awk '{ print $1 }' | sort | uniq -c`

IP_COUNT=`echo "$IP_TABLE" | awk '{ print $1 }'`
IP_TABLE=( `echo "$IP_TABLE" | awk '{ print $2 }'` )
INDEX=0
MSG=""

for COUNT in $IP_COUNT; do

	# Too many fails from this IP.
	if [ "$COUNT" -gt "$ALLOWED_FAIL" ]; then

		# Let's see if we've already banned this IP.
		if [ ! "`grep ^${IP_TABLE[$INDEX]}\$ $TEMP_FILE`" ]; then

			# Add to ban list.
			echo ${IP_TABLE[$INDEX]} >> $TEMP_FILE

			# Ban IP with IPTables.
			MSG="$MSG\nBanning ${IP_TABLE[$INDEX]}..."
			iptables -I INPUT --source ${IP_TABLE[$INDEX]} -j DROP

			# More than IP_MEMORY banned IPs? Unban one.
			if [ "`cat $TEMP_FILE | wc -l`" -gt "$IP_MEMORY" ]; then
				UNBAN_IP=`head -n 1 $TEMP_FILE`
				tail -n $IP_MEMORY $TEMP_FILE > $TEMP_FILE.tmp
				mv -f $TEMP_FILE.tmp $TEMP_FILE

				MSG="$MSG\nUnbanning $UNBAN_IP..."
				iptables -D INPUT --source $UNBAN_IP -j DROP
			fi
		fi
	fi

	# INDEX+1
	(( INDEX += 1 ))

done

if [[ "$MSG" && "$MAIL_TO" ]]; then
	echo -e "SSHD Audit info:\n\n$MSG" | mail -s "$MAIL_SUBJ" $MAIL_TO
	#echo -e "$MSG"
fi
