Blacklist emails with DCC through a Perl script


DCC is a wonderful tool, but it needs to be fed constantly.
After going through the process of blacklisting a few emails that weren’t tag as spam, I found myself in a not so lazy position. We don’t like that … so we wrote a Perl script to kind of automate this process. (yes, we talk in plural since we are feeling quite majestic today)

The process is actually fairly simple, and this should be practically the biggest reason to automate this process.
DCC will create a text file for every email it checks (whether you like it or not), in /var/dcc/log. The bottom of those files contain variables and HEX values which are required to white- or blacklist messages in the DCC server.

Example of a text file generated by DCC (such the bottom actually):

### end of message body ########################
dccifd  global-log  

X-DCC-musashi-Metrics: musashi.moretrix.com 32702; bulk Body=many Fuz1=many
                            reported: 1 spam          checksum  server wlist
                       IP: e475b896 492c60fc efecb432 6e29e3c5
                 env_From: c339fff7 216652a7 36a8ffa4 692ca3c1
                     From: 21eadc86 d5fa588e 2de85418 e2e18829
          substitute helo: e34e261c 6c7e0450 454065a8 a19f7b6c          many
               Message-ID: 48f0f506 f391cb50 5c9a8033 ff5c6bbb
                 Received: 4683ff3f 121cf370 ffb45478 dad90632
                     Body: 9b8a1cda 67a889ba 5d78d440 3b27da17       1
                     Fuz1: 27c25f69 0894e8b9 b5efa920 959aef57       1
                     Fuz2: 84451221 40f95ad5 fe80b2ef a0d1e5fd       1
     substitute mail_host: 956f550f f8dadf7e 38637790 756f8240

result: reject

In most cases, black- or whitelist entries will be created based on the fields ‘Body’, ‘Fuz1’ or ‘Fuz2’ (or all three will be added), but it is also possible to create criteria based on ‘IP’, ‘From’, …

Quick Overview of the process:

  1. Locate the correct text file in /var/dcc/log
  2. Grab the fields you want to white- or blacklist
  3. prefix these fields with either ‘many hex’ or ‘ok’
  4. Add those fields to the corresponding file in /var/dcc

In my case, I’ve created a file called /var/dcc/blacklist_spam which is included from /var/dcc/whiteclnt

The script goes as follows:

use strict;
use warnings;

use Getopt::Long;

my $fields = 'Body,Fuz1,Fuz2';
my $result = GetOptions("fields=s", $fields);

my $criteria = @ARGV;

chdir '/var/dcc/log' or die "Kak: $!";
my @blacklist;
foreach my $crit (@{$criteria}){
        print "criteria: $critn";
        open my $grep, '-|', "grep -l '$crit' *" or die "Kak: $!";
        my @files = <$grep>;
        close $grep;

        foreach my $file (@files){
                $fields =~ s/,/|/g;
                open my $grep, '-|', "egrep '^ *($fields)' $file" or die "Kak: $!";
                my @hexes = <$grep>;
                close $grep;

                map { s/^s*/manythext/; s/((S+s*){7}).*/$1/; } @hexes;
                push @blacklist, @hexes

open my $blacklist, '>>', '/var/dcc/blacklist_spam' or die "Kak: $!";
print {$blacklist} $_ foreach @blacklist;
close $blacklist;

print "Written " . scalar @blacklist . " to /var/dcc/blacklist_spamnn";

The criteria I use in order to search the emails is usually the Message-ID field, since this should be a unique identifier.

# dcc_block 20101008111306.31259.876787136.swift@email.addemar.com
Previous Post

Monitor resources on a UNIX machine (with Perl)

Next Post

A services watchdog written in Perl

Related Posts