This script can be used if you have mailscanner in mysql database that record 
results of spamassassin activity and postfix as mta






# postban.sh
# Temporary Ban SpamOnly Ip
# -------------------------
#
# This script create a table for postfix that ban IPs that made high spam 
results only
#
# 1) Put this script anywhere and set your parameters
# 2) Put in crontab a line like this to run every 15 minutes :
# 0/15 * * * * /batch/postban.sh
# 3) Modify your main.cf in postfix at this line like here and then postfix 
reload :
# smtpd_client_restrictions = (OTHER YOUR PARAMETERS) check_client_access 
hash:/etc/postfix/postban_access



# Start time
start=`date +%s`

# Parameters
ROOTPWD=YOUR MYSQL PWD
VSCORESPAM=9 # Search for IP that have more than VSCORESPAM score
VMINSPAM=3600 # In the last VMINSPAM minutes
VSCOREHAM=5 # But exclude if the ip sent message that have less than VSCOREHAM
VMINHAM=14400 # In the last VMINHAM minutes
# In the default config it block ip that sent email that have more than score 9
# for 3600 mins (24 hours) from last event, but exclude if this ip have a mail 
sent
# in the last 10 days (14400 mins) that have a score less than 5
VLOGFILE=/batch/postban.log # Logfile position
VACCFILE=/etc/postfix/postban_access # Access file position
RJMESSAGE="Il server utilizzato invia troppo spam" # Reject Message
CMDPOSTMAP="/usr/sbin/postmap /etc/postfix/postban_access" # Postmap command

# Date & Time
NOW=$(date +"%m-%d-%Y %r")

# Touching log file
touch $VLOGFILE

# Main selection query, table mailscanner
S1="SELECT clientip \
FROM mailscanner.maillog \
WHERE timestamp > DATE_SUB(now(), INTERVAL $VMINSPAM MINUTE) \
AND spamwhitelisted = 0 \
AND clientip NOT LIKE '10.%' \
AND clientip NOT LIKE '192.168.%' \
AND sascore > $VSCORESPAM \
GROUP BY clientip;"

echo "# Generated by postban.sh " $start > $VACCFILE
f=0;ff=0
res1=($(mysql -N -u root -p${ROOTPWD} -e "${S1}"))
cnt=${#res1[@]}
for (( i=0 ; i<${cnt} ; i++ ))
do
#echo "Found line " $i " " ${res1[i]}
CLIP=${res1[i]}
S2="SELECT clientip \
FROM mailscanner.maillog \
WHERE timestamp > DATE_SUB(now(), INTERVAL $VMINHAM MINUTE) \
AND clientip = '${res1[i]}' \
AND sascore < $VSCOREHAM \
GROUP BY clientip;"
#echo $S2
res2=$(mysql -N -u root -p$ROOTPWD -se "$S2")
#echo $res2
let "f++"
if [[ $res2 == "" ]] ; then
let "ff++"
#echo "Not found ham so write spam ip " $CLIP
echo $CLIP " REJECT " $RJMESSAGE >> $VACCFILE
fi

done

# Postmap (doing postmap is enough to get new ip table without refreshing)
eval $CMDPOSTMAP

# Logging
end=`date +%s`
runtime=$((end-start))
echo $NOW " Found" $f "spam ip," $ff "with no ham in the past written in reject 
table, time elapsed:" $runtime "sec." >> $VLOGFILE

# Truncating logfile
tail -n 500 $VLOGFILE > $VLOGFILE.tmp
mv $VLOGFILE.tmp $VLOGFILE

Reply via email to