I wanted to install something that would auto-block IPs from people trying to brute-force ssh passwords. fail2ban and similar scripts aren't available since they are written in Python which is a bit heavyweight for OpenWRT. logtrigger looks nice but I don't see a package for it and I don't feel like cross compiling it and installing it. So I wrote a short shell script which more or less does the job, and though I'd share it.
It's lightweight, runs out of cron, and it's all self contained in one file including documentation. It's written in busybox ash and should work completely out of the box with no additional packages required.
The list of banned hosts can optionally persistent across reboots, you can permanently whitelist (or blacklist) hosts or networks, and the default expiration time ("lease time") is easily set.
#!/bin/sh # # dropBrute.sh by robzr # # minimalist OpenWRT/dropbear ssh brute force attack banning script # # Installation steps: # # 1) Optionally 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, something like: # # iptables -N dropBrute # iptables -I input_rule -i br-wan -p tcp --dport 22 -j dropBrute # iptables -I input_rule -i br-wan -p tcp --dport 22 -m state --state NEW -m limit --limit 6/min --limit-burst 6 -j ACCEPT # # 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 184.108.40.206/24 >> /tmp/dropBrute.leases # How many bad attempts before banning. Only the log entries from the # current day are checked. allowedAttempts=10 # How long IPs are banned for after the current day ends. # default is 7 days secondsToBan=$((7*60*60*24)) # the "lease" file - defaults to /tmp which does not persist across reboots leaseFile=/tmp/dropBrute.leases # This is the iptables chain that drop commands will go into. # you will need to put a reference in your firewall rules for this iptChain=dropBrute # the IP Tables drop rule iptDropRule='-j DROP' # the IP Tables whitelist rule iptWhiteRule='-j RETURN' # You can put default leasefile entries in the following space. # Syntax is simply "leasetime _space_ IP_or_network". A leasetime of -1 is a # whitelist entry, and a leastime of 0 is a permanent blacklist entry. [ -f $leaseFile ] || cat <<__EOF__>>$leaseFile -1 192.168.1.0/24 __EOF__ # End of user customizable variables (unless you know better :) ) ipt='/usr/sbin/iptables' [ `date +'%s'` -lt 1320000000 ] && echo System date not set, aborting. && exit -1 $ipt -N $iptChain >&/dev/null today=`date +'%b %d'` now=`date +'%s'` nowPlus=$((now + secondsToBan)) echo Running dropBrute on `date` \($now\) # find new badIPs for badIP in `logread|egrep "^$today"|fgrep dropbear|egrep 'login attempt for nonexistent user'\|'bad password attempt for'|sed 's/^.*from //'|sed 's/:.*$//'|sort -u` ; do found=`logread|egrep "^$today"|fgrep dropbear|egrep 'login attempt for nonexistent user'\|'bad password attempt for'|sed 's/^.*from //'|sed 's/:.*$//'|fgrep $badIP|wc -l` if [ $found -gt $allowedAttempts ] ; then if [ `egrep \ $badIP\$ $leaseFile|wc -l` -gt 0 ] ; then [ `egrep \ $badIP\$ $leaseFile|cut -f1 -d\ ` -gt 0 ] && sed -i 's/^.* '$badIP\$/$nowPlus\ $badIP\/ $leaseFile else echo $nowPlus $badIP >> $leaseFile fi fi done # now parse the leaseFile while read lease ; do leaseTime=`echo $lease|cut -f1 -d\ ` leaseIP=`echo $lease|cut -f2 -d\ ` if [ $leaseTime -lt 0 ] ; then if [ `$ipt -S $leaseChain|egrep \ $leaseIP/32\ \|\ $leaseIP\ |fgrep -- "$iptWhiteRule"| wc -l` -lt 1 ] ; then echo Adding new whitelist rule for $leaseIP $ipt -I $iptChain -s $leaseIP $iptWhiteRule fi elif [ $leaseTime -ge 1 -a $now -gt $leaseTime ] ; then echo Expiring lease for $leaseIP $ipt -D $iptChain -s $leaseIP $iptDropRule sed -i /$leaseIP/d $leaseFile elif [ $leaseTime -ge 0 -a `$ipt -S $leaseChain|egrep \ $leaseIP/32\ \|\ $leaseIP\ |wc -l` -lt 1 ] ; then echo Adding new rule for $leaseIP $ipt -A $iptChain -s $leaseIP $iptDropRule fi done < $leaseFile
(Last edited by robzr on 6 Nov 2011, 22:45)