Internal DNSBL - use at your own risk

Forum for getting help with Project Gamera, Spamassassin, Clamav, qmail-scanner and other anti-spam tools.
exi1ed0ne
Forum Regular
Forum Regular
Posts: 190
Joined: Sun Nov 20, 2005 4:16 pm
Location: Right Behind You!
Contact:

Internal DNSBL - use at your own risk

Unread post by exi1ed0ne »

Here is an ugly little script I whipped together to create my own DNSBL visible from the normal DNS tools withing Plesk. Basically it looks for all IPs that are responsible for more than two rejected mails for the last day, subtracts IPs that sent at least one good message in the same time frame, then adds DNS entries (A and TXT record) into Plesk. The TXT record has some information about that IP at the time it was listed, as well as the date. My goal wasn't to end spam, but as an exercise in creating an internal block list that was visible to Plesk. A return of 127.0.0.2 is added via the script, and 127.0.0.3 by manual entry.

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
Like I said - UGLY! I thought about hacking up qmail-scanner to spit out an easier to parse line of text in the log file, but that would mean any updates to qmail-scanner would break the script - hence the awk/sed insanity.

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
I HIGHLY recommend testing before you use it to outright block connections. The way I like best is to add it to spamassassin with a score of 0.001 and then parse the qmail-scanner log. Here is my asbl.cf file I used for testing. If you add this to spamassassin unmodified it will query my server, not yours.

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
Feedback is most welcome!
-Andy
Post Reply