:: SSH brute force banning script ::
Références
Installation et configuration
Note : Ce script est une version modifiée de celui fourni par robzr sur le forum OpenWrt.
Créer le fichier /usr/sbin/dropBrute.sh et copier le contenu suivant :
#!/bin/sh
# ------------------------------------------------------------------------------
# dropBrute.sh : minimalist OpenWRT/dropbear ssh brute force attack banning script
# ------------------------------------------------------------------------------
# initial release by robzr
# ------------------------------------------------------------------------------
# Installation steps:
# 1) Edit the variables in the header of this script to customise for your environment.
# 2) Insert a reference for this rule in your firewall script before you accept ssh.
# This will block the brute force attack until the IP is banned by the script.
# iptables -N logndrop
# iptables -N dropBrute
# iptables -A logndrop -j LOG
# iptables -A logndrop -j DROP
# iptables -A input_rule -p tcp --dport 22 -i eth1 -m state --state NEW -m recent --set
# iptables -A input_rule -p tcp --dport 22 -i eth1 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j logndrop
# iptables -A input_rule -p tcp --dport 22 -j dropBrute
# 3) Run the script periodically out of cron:
# echo '*/10 * * * * /usr/sbin/dropBrute.sh 2>&1 >> /tmp/dropBrute.log' >> /etc/crontabs/root
# 4) If cron is not enabled, you'll also need to run the following:
# /etc/init.d/cron enable && /etc/init.d/cron start
# ------------------------------------------------------------------------------
# To whitelist hosts or networks, simply add a manual entry to the lease
# file with a leasetime of -1. This can be done with the following syntax:
# echo -1 192.168.1.0/24 >> /tmp/dropBrute.leases
# A static, or non-expiring blacklist of a host or network can also be
# added, just use a lease time of 0. This can be done with the following syntax:
# echo 0 1.2.3.0/24 >> /tmp/dropBrute.leases
# ------------------------------------------------------------------------------
# =========================== CUSTOMIZABLE VARIABLES ===========================
# Debug mode (let empty to disable, debug = '')
debug='1'
# How many bad attempts before banning.
allowedAttempts=3
# How long IPs are banned for (in seconds)
secondsToBan=86400
# the "lease" file - defaults to /tmp which does not persist across reboots
# Note: here, USB key is mounted on /tmp/cache. This way, leases file persists across reboots
leaseFile=/tmp/cache/dropBrute.leases
# Iptables chain that drop commands will go into.
iptChain=dropBrute
# IP Tables drop & whitelist rules
iptDropRule='-j DROP'
iptWhiteRule='-j RETURN'
# Default leasefile entries
[ -f $leaseFile ] || cat <<__EOF__>>$leaseFile
-1 192.168.1.0/24
__EOF__
# Path to iptables command
ipt='/usr/sbin/iptables'
# ======================= END OF CUSTOMIZABLE VARIABLES ========================
# ------------------------------------------------------------------------------
[ `date +'%s'` -lt 1320000000 ] && echo System date not set, aborting. && exit -1
$ipt -N $iptChain >&/dev/null
now=`date +'%s'`
nowPlus=$((now + secondsToBan))
echo ------ Starting dropBrute on `date` \($now\)
# find new badIPs (method 1)
[ "$debug" ] && echo Looking for bad IPs \(method 1\)
for badIP in `logread | fgrep dropbear | egrep -i 'login attempt for nonexistent user'\|'bad password attempt for'| sed 's/^.*from //' | sed 's/:.*$//' | sort -u` ; do
[ "$debug" ] && echo - Working on $badIP
n=`logread | fgrep dropbear | egrep -i 'login attempt for nonexistent user'\|'bad password attempt for'|sed 's/^.*from //'|sed 's/:.*$//' | fgrep $badIP | wc -l`
if [ $n -ge $allowedAttempts ] ; then
[ "$debug" ] && echo ... KO \($n occurences\)
# if there is not a lease, add it
if [ $(egrep -c $badIP$ $leaseFile) -eq 0 ] ; then
echo $nowPlus $badIP >> $leaseFile
[ "$debug" ] && echo ... Adding new lease for $badIP
else
[ "$debug" ] && echo ... Lease for $badIP already exists
fi
else
[ "$debug" ] && echo ... Ok \($n occurences\)
fi
done
# find new badIPs (Method 2)
[ "$debug" ] && echo Looking for bad IPs \(method 2\)
for fuzzyIP in `logread | fgrep dropbear | egrep -i 'Child connection from' | sed 's/^.*from //' | sed 's/:.*$//' | sort -u` ; do
n=0
[ "$debug" ] && echo - Working on $fuzzyIP
for fuzzyPs in `logread | fgrep dropbear | egrep -i 'Child connection from' | fgrep $fuzzyIP | sed 's/^.*dropbear\[//' | sed 's/\]:.*$//' | sort -u` ; do
nbPs=`logread | egrep -i 'Exit before auth' | fgrep $fuzzyPs | wc -l`
n=$((n+nbPs))
done
if [ $n -ge $allowedAttempts ] ; then
[ "$debug" ] && echo ... KO \($n occurences\)
# if there is not a lease, add it
if [ $(egrep -c $fuzzyIP $leaseFile) -eq 0 ] ; then
echo $nowPlus $fuzzyIP >> $leaseFile
[ "$debug" ] && echo ... Adding new lease for $fuzzyIP
else
[ "$debug" ] && echo ... Lease for $fuzzyIP already exists
fi
else
[ "$debug" ] && echo ... Ok \($n occurences\)
fi
done
# now parse the leaseFile
[ "$debug" ] && echo Parsing the leasefile
cat $leaseFile | while read lease ; do
leaseTime=`echo $lease|cut -f1 -d\ `
leaseIP=`echo $lease|cut -f2 -d\ `
# when used with the iptables example on the top a return rule is not needed
if [ $leaseTime -lt 0 ] ; then
if [ `$ipt -S $leaseChain|egrep \ $leaseIP/32\ \|\ $leaseIP\ |fgrep -- "$iptWhiteRule"| wc -l` -lt 1 ] ; then
#[ "$debug" ] && echo Adding new whitelist rule for $leaseIP
#$ipt -I $iptChain -s $leaseIP $iptWhiteRule
true
fi
elif [ $leaseTime -ge 1 -a $now -gt $leaseTime ] ; then
[ "$debug" ] && echo - Expiring lease for $leaseIP
$ipt -D $iptChain -s $leaseIP $iptDropRule
$ipt -D $iptChain -s $leaseIP -j LOG --log-prefix "dropBrute "
sed -i /$leaseIP/d $leaseFile
elif [ $leaseTime -ge 0 -a `$ipt -S $leaseChain|egrep \ $leaseIP/32\ \|\ $leaseIP\ |wc -l` -lt 1 ] ; then
[ "$debug" ] && echo - Adding new rule for $leaseIP
$ipt -I $iptChain -s $leaseIP $iptDropRule
$ipt -I $iptChain -s $leaseIP -j LOG --log-prefix "dropBrute "
fi
done < $leaseFile
echo ------ Ending dropBrute on `date` \(`date +'%s'`\)