Caveats:
1. Perl would almost certainly be a better choice, but my perl-fu is weak
2. IPs are pretty stale - up to 24 hours old
3. Roach motel design - IPs go in, but they don't come out
4. Probably won't work on any system but mine.
5. Did I mention it is pretty ugly? And slow.
6. Designed for my email traffic. Yours is different.
7. One good email negates blacklisting
8. Limited time horizon for pseudo-reputation evaluation
9. Requires qmail-scanner to REJECT messages. If you aren't having qmail-scanner reject, then all you will do is waste cpu.
10. It will cause you to lose email (duh), break your system, date your sister, shoot your dog, and set fire to your house. You've been warned!
OK, now to it!
Step 1:
Create the directory /var/spool/qscan/rep - this will act as the working directory for the script, as well as keep a record of ham IPs and spam IPs/hit count per day.
Step 2:
I had to adjust the maillog.processed file to rotate daily. Mine was originally set to rotate every 3 days. Just make sure you run the script before maillog.processed is rotated off, or all you'll end up parsing is an empty file.
Step 3:
Create a suitable domain in plesk with only DNS turned on. Optional: I removed all default DNS entries except for the NS and A records.
Step 4:
Add the following script to /etc/cron.daily (I prefixed the name with "00" to make sure it is run before maillog.processed is rotated off.) You will need to modify it to work in your environment.
Code: Select all
#/bin/bash
# DNSBL list generator for Plesk
# Andy Sutton - sutton@nefw.net
today=`date +%Y%m%d`
workdir='/var/spool/qscan/rep'
logloc='/usr/local/psa/var/log'
logfile='maillog.processed'
#Generate list of more than one rejected and any clear IP addresses
cat $logloc/$logfile | grep Clear | awk '{print $6}' | sed -e 's/Clear\:RC\:\([0-1]\)(//' | \
sed -e 's/)\:SA\:\([0-1]\)(/ /' | awk '{print $1}'| sort | uniq > $workdir/hamip_$today
cat $logloc/$logfile | grep SPAM-REJECTED | awk '{print $6}' | sed -e 's/SA\:SPAM-REJECTED\:RC\:0(//' | \
sed -e 's/)\:SA\:1(/ /' | awk '{print $1}' | sort | uniq -c | sort -n | grep -v " 1 " > $workdir/spamip_$today
# Give 'em a pass for even one ham message
awk >$workdir/dns_file 'NR==FNR{arr[$1];next}!($2 in arr)' $workdir/hamip_$today $workdir/spamip_$today
# Feed 'em into Plesk DNS
while read i; do
j=`echo $i | awk '{print $2 }'`
k=`echo $j | sed -e 's/\./ /g' | awk '{print $4"."$3"."$2"."$1}'`
l=`echo $i | awk '{print $1 }'`
m=`dig $k.in-addr.arpa ptr +short | tr '\n' ' '`
/usr/local/psa/bin/dns -a dnsbl.pessimists.net -a $k -ip 127.0.0.2 >/dev/null 2>&1
/usr/local/psa/bin/dns -a dnsbl.pessimists.net -txt "Added: $today IP: $j Hits: $l Names: $m" -domain $k >/dev/null 2>&1
done < $workdir/dns_file
# Cleanup
rm $workdir/dns_file
You can query my setup at dnsbl.pessimists.net, but please be gentle! You can test with the following commands, where 127.0.0.2 are test records that will always return something:
Code: Select all
host 2.0.0.127.dnsbl.pessimists.net
host -t TXT 2.0.0.127.dnsbl.pessimists.net
Code: Select all
header RCVD_IN_ASBL eval:check_rbl('asbl-lastexternal', 'dnsbl.pessimists.net.', '127.0.0.2')
describe RCVD_IN_ASBL Received via relay listed in Pessimists.net RBL - script genned
score RCVD_IN_ASBL 0.0001
tflags RCVD_IN_ASBL net
header RCVD_IN_ASMBL eval:check_rbl('asmbl-lastexternal', 'dnsbl.pessimists.net.', '127.0.0.3')
describe RCVD_IN_ASMBL Received via relay listed in Pessimists.net RBL - manual add
score RCVD_IN_ASMBL 0.0001
tflags RCVD_IN_ASMBL net