Simple script to cut off bad connections

Questions and answers about how to do stuff
Post Reply
nicola.piazzi
Posts: 389
Joined: 23 Apr 2015 09:45

Simple script to cut off bad connections

Post by nicola.piazzi »

This little simple script can be cutted/pasted in a file called postban.sh and putted in crontab
You must change your parameters only
This periodically scan maillog table for IPs that sent high score spam without having ham in the past and tell to postfix to reject future connections
Cut & paste in your system and verify/change parameters in red :


# 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 MY SQLL ROOT 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}
CLIP=${res1}
S2="SELECT clientip \
FROM mailscanner.maillog \
WHERE timestamp > DATE_SUB(now(), INTERVAL $VMINHAM MINUTE) \
AND clientip = '${res1}' \
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
Post Reply