Wiki source for AutoBlockSH


Show raw source

%%(bash)
#!/bin/sh
#
# Autoblock 20060120
# /etc/autoblock/autoblock
# Copyright 2006 by Jeff Taylor
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA


#------------------------------------------------------------
# Define file locations, etc
#------------------------------------------------------------
ETH=eth0 # Which interface to set iptables rules
LOG=/var/log/filter # Tail this file for events of interest
TailLines=8 # Lines to track for quickblocks
Quickblock=3 # How many unique IPs request same lookup

GREP=/bin/grep
IPTABLES="/usr/sbin/iptables"
DIR=`dirname $0`
RULES=$DIR/autoblock.rules
BLOCKED=/etc/blocklist
CONFDATE=`ls -l $RULES | cut -b30-45`
# ${#p[@]} will give the count of elements in array p

#------------------------------------------------------------
# Read in the config file
#------------------------------------------------------------
function GetConfig {
if [ ! -f "$RULES" ]; then
echo "Config file $RULES not found!"
exit 1
fi

BLOCKS=-1
while read LINE; do
LINE=${LINE//%#*}
CMD=`echo $LINE | cut -d\ -f1`
VAL=`echo $LINE | cut -d\ -f2-`
if [ "$LINE" ] && [ "$CMD" ] ; then
#VAL=`echo $VAL | sed -e "s/'/\\'/g"`
if [ "$VAL" == "{" ]; then
let "BLOCKS = $BLOCKS +1"
NAME[$BLOCKS]="$CMD"
elif [ "$CMD" == "}" ]; then
X=""
else
VAL=`echo $LINE | cut -d= -f2- | sed 's/^\s*//'`
case "$CMD" in
info)
INFO[$BLOCKS]="$VAL" ;;
time)
TIME[$BLOCKS]="$VAL" ;;
match)
G0=""
until [ "$VAL" == "" ]; do
G1=`echo $VAL | cut -d\| -f1`
VAL=`echo $VAL | cut -d\| -f2-`
if [ "$VAL" == "$G1" ] ; then VAL="" ; fi
if [ "$G0" != "" ] ; then G0="$G0 | " ; fi
G0="$G0$GREP \"$G1\""
done
VAL=$G0
MATCH[$BLOCKS]="$VAL" ;;
source)
SOURCE[$BLOCKS]="$VAL" ;;
mode)
MODE[$BLOCKS]="$VAL" ;;
hits)
if [ "$VAL" == "" ] ; then VAL=0 ; fi
HITS[$BLOCKS]="$VAL" ;;
hittime)
if [ "$VAL" == "" ] ; then VAL=0 ; fi
HITTIME[$BLOCKS]="$VAL" ;;
domain)
G0=`echo $VAL | cut -d= -f2 | sed 's/^ *//' | cut -d\| -f1`
G1=`echo $VAL | cut -d= -f2 | sed 's/^ *//' | cut -d\| -f2`
DOMAIN[$BLOCKS]="sed -e \"s/^.*$G0//\" -e \"s/[$G1].*//\"" ;;
esac
fi
fi
done < $RULES
}

function UpdateIP {
logIP=$1
criticalHits=$2
killDate=$3
hitsDate=$4

padIP=`echo "$logIP " | cut -b-15`
NEWDATE=`date --date +${killDate} +"%b %d %Y %H:%M"`
HITDATE=`date --date +${hitsDate} +"%b %d %Y %H:%M"`
TEST=`grep " $logIP " $BLOCKED`
fwTEST=`$IPTABLES -nL autoblock | grep " $logIP "`

if [ $criticalHits -le 1 ]; then
if [ "$TEST" ]; then
sed "/ $logIP /d" $BLOCKED > $BLOCKED.tmp
mv $BLOCKED.tmp $BLOCKED
# logger -t autoblock "Clearing $logIP"
fi
echo " $padIP $NEWDATE" >> $BLOCKED
if [ ! "$fwTEST" ]; then
$IPTABLES -A autoblock -i $ETH -s $logIP -j autoblock_drop > /dev/null 2>&1
if [ "$criticalHits" == "-1" ] ; then
logger -t autoblock "Quick-Block $logIP until $NEWDATE"
else
logger -t autoblock "Blocking $logIP until $NEWDATE"
fi
fi
#SPAM=`grep -m1 $logIP /var/log/mail`
if [ "$SPAM" ] ; then
logger -t autoblock "FOUND SPAMMER MATCH @ $logIP"
fi
else
hitCount=0
prevHits=""
if [ "$TEST" ]; then
prevHits=`echo "$TEST" | sed 's/[^#]//g'`
hitCount=`echo ${#prevHits}`
sed "/ $logIP /d" $BLOCKED > $BLOCKED.tmp
mv $BLOCKED.tmp $BLOCKED
fi
(( hitCount++ ))
if [ $hitCount -ge $criticalHits ] ; then
echo " $padIP $NEWDATE" >> $BLOCKED
if [ ! "$fwTEST" ]; then
$IPTABLES -A autoblock -i $ETH -s $logIP -j autoblock_drop > /dev/null 2>&1
# logger -t autoblock "Blocking $logIP until $NEWDATE"
logger -t autoblock "Blocking $logIP ($hitCount/$criticalHits)($NEWDATE)"
fi
#SPAM=`grep -m1 $logIP /var/log/mail`
if [ "$SPAM" ] ; then
logger -t autoblock "FOUND SPAMMER MATCH @ $logIP"
fi
else
echo "#$prevHits $padIP $HITDATE" >> $BLOCKED
#logger -t autoblock "Updating $logIP ($hitCount/$criticalHits)($HITDATE)"
fi
fi
return 0
}

GetConfig
if [ "$BLOCKS" == "-1" ]; then
echo "Nothing defined in autoblock.conf!"
exit 1
fi

# This code can be uncommented to show what was read from the config file
# for (( x=0; x<=$BLOCKS; x++ )); do
# echo "${NAME[$x]} -> ${MATCH[$x]}"
# done

#------------------------------------------------------------
# Clean up and read entries from existing list
#------------------------------------------------------------
touch $BLOCKED
$IPTABLES -F
$IPTABLES -F autoblock
$IPTABLES -F autoblock_drop

$IPTABLES -N autoblock 2> /dev/null
$IPTABLES -N autoblock_drop 2> /dev/null
$IPTABLES -A INPUT -j autoblock
# $IPTABLES -A autoblock_drop $LOGLIMIT -j LOG $LOGLEVEL --log-prefix "AutoBlocked: "
$IPTABLES -A autoblock_drop -j DROP

while read IP DATE; do
IP=`echo $IP | cut -d# -f1`
if [ "$IP" ]; then
$IPTABLES -A autoblock -i $ETH -s $IP -j autoblock_drop > /dev/null 2>&1
#echo "Added $IP to firewall"
fi
done < $BLOCKED

#------------------------------------------------------------
# Tail the kernel log file and add new entries to block
#------------------------------------------------------------
tail -n 1 -f $LOG | while read LINE; do
IP=""
for (( x=0; x<=$BLOCKS; x++ )); do
CHK=`eval "echo \"$LINE\" | ${MATCH[$x]}"`
if [ "$CHK" ]; then ### Log entry matches one of our flags
IP=`echo ${LINE#*${SOURCE[$x]}} | cut -d\ -f1`
IP=`echo $IP | cut -d\# -f1`
if [ ${#IP} -lt 7 ] ; then IP="" ; fi
if [ "$IP" ] ; then
UpdateIP "$IP" "${HITS[$x]}" "${TIME[$x]}" "${HITTIME[$x]}"
if [ "${DOMAIN[$x]}" ] ; then
Domain=`eval "echo \"$LINE\" | ${DOMAIN[$x]}"`
#logger "$IP: $Domain"
### Check if someone is pulling the same info from multiple locations
HitIP="|$IP|"
HitNum=1
for (( i=$TailLines; i>0; i-- )); do
j=$(($i-1))
TailIP[$i]=${TailIP[$j]}
TailDomain[$i]=${TailDomain[$j]}
if [ "$Domain" == "${TailDomain[$i]}" ] && [ "${TailIP[$i]}" ] ; then
if [ "`echo $HitIP | grep ${TailIP[$i]}`" == "" ] ; then
HitIP="$HitIP${TailIP[$i]}|"
HitNum=$(($HitNum+1))
# logger -t autoblock $HitIP
fi
fi
done
TailIP[1]=$IP
TailDomain[1]=$Domain

# logger -t autoblock "HitNum=$HitNum"
if [ $HitNum -ge $Quickblock ] ; then
HitIP=`echo $HitIP | cut -d\| -f2-`
xIP=""
until [ ${#HitIP} -lt 2 ]; do
xIP=`echo $HitIP | cut -d\| -f1`
HitIP=`echo $HitIP | cut -d\| -f2-`
if [ "$xIP" ] ; then
UpdateIP "$xIP" "-1" "${TIME[$x]}" "${TIME[$x]}"
fi
done
fi
fi
break # Only want a single hit on anything found in log file
fi
fi
done

CHKDATE=`ls -l $RULES | cut -b30-45`
if [ "$CONFDATE" != "$CHKDATE" ] ; then
GetConfig
CONFDATE=$CHKDATE
logger -t autoblock "$RULES has been updated"
fi
done
%%

----
CategoryDNSBlockList
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki