I saw some recent postings about how people control spam.  I thought I
would pass along my perl script that I use to help with this.  Some
things are needed in order for this to work.

1. freebsd (although certainly easily modified for others)
2. perl
3. procmail
4. sendmail using anti-spam
5. root access

Procmail simply needs to use many of the filters that were presented on
this list, but the most powerful weapon is with sendmail.  I use code
that I found from sendmail.org which rejects domains found in a text
file.  This text file contains the domains that sendmail rejects during
my fetchmail retrievals.  By default, it uses /etc/spamdomains.txt.  I
currently have over 750 domains which have been added.

When you run this script it grabs the senders domain from your spam box
and adds these domains to your sendmail /etc/spamdomains.txt file.  It
restarts sendmail too.  You must restart sendmail in order to have the
new list activated.  It also checks for safe domains which you can add.
Safe domains are domains which should never be added even if they are
found in your spam box.  It will remove duplicates and sort the list as
well.  Please use at your own discretion.  Your spam box will also be
purged each time this is run.  So do not put ANYTHING in this mail box
you want to save.

It's a very fast way to keep updating your system with domains you want
to reject.  Adding users to block is also an option but is not part of this
script.  I try not to add users since spam seems to never come from the
same person twice.

You could also run this script from cron once you feel comfortable
enough.


#!/usr/bin/perl
# By: Corey Gaffney

use Mail::Address;

### Environment Variables ##########
$mail="/home/cgaff/mail/spam";
$spam_list="/etc/spamdomains.txt";

@safe_domains= ("amazon.com",
                "home.com",
                "interaccess.com",
                "yahoo.com",
                "flashcom.com");

#####################################

my @unique;
my @spamtoadd;
my @newspam;
my $check;
my $from_host;
my $from_hostc;
my %seen;

verify_os();
verify_user();
main();
kill_sendmail();

sub verify_os{

# Verify OS - FreeBSD only
@operating_system=`/usr/bin/uname`;
        foreach $os(@operating_system){
        chomp($os);
                if ($os ne "FreeBSD"){
                        print "You must run this script on FreeBSD\n";
                        exit;
                }
        }
}

# Verify ID - Super user only
sub verify_user{
@user=`/usr/bin/id`;
        foreach $id(@user){
        chomp($id);
                @idsplit=split(/\s+/,$id);
                $eid=$idsplit[0];
                if ($eid ne "uid=0(root)"){
                        print "Must be superuser to execute script\n";
                        exit;
                }
        }
}

sub main{

open (MAIL,$mail) || die "Cannot open $mail\n";

# Lets make sure we have mail in the spam mailbox
open (MCOUNT,$mail); 
@spamcount=<MCOUNT>;
close(MCOUNT);

if (@spamcount < 1){
        print "No spam to process - exiting\n";
        exit;
}

while ( $check = <MAIL> ){

        if ($check =~ m/^From:/){

                ($line,$from) = split(/^From:\s+/, $check);
                $object = (Mail::Address->parse($from))[0];
                $from_hostc = $object->host;

                $from_host = lc $from_hostc; #convert all to lowercase
                push @spamtoadd, "$from_host";
        }
}
close(MAIL);

# Remove safe domains from spam list
foreach $safe_domains(@safe_domains){
        @spamtoadd = grep {$_ ne $safe_domains} @spamtoadd;
}

# Put unique spam domains into another array
@unique = do {my %h; grep {!$h {$_} ++} @spamtoadd};

open (ILIST,$spam_list) || die "Cannot open $spam_list\n";
@ilist=<ILIST>;
        foreach  $list(@ilist){
        chomp($list);
        push(@original_list,$list);
        }
close(ILIST);

                # Find elements in A that aren't in B

                @seen{@original_list} = ();

                foreach $email(@unique) {
                push(@newspam, $email) unless exists $seen{$email}
                }

                @unique_sorted = sort @newspam;

                # Make sure spam we add is unique - do not add
                # duplicates
                # Remove bland lines before pushing to array

                foreach $from_host_unique(@unique_sorted){
                        unless ($from_host_unique =~ /^\s*$/){
                        push(@new_sorted_array,$from_host_unique);

                        print "Added $from_host_unique\n";
                        }
                }

push(@original_list,@new_sorted_array);
@final_sorted_array=sort @original_list;

# Make sure we are not writing an empty array
$count=@final_sorted_array;
        if ($count <= 1){
                print "Something went wrong!! - bailing\n";
                print "Array final_sorted_array too small!\n";
                exit;
        }

# Generate new spam domains file
open(SPAMLIST,">$spam_list") || die "Cannot open $spam\n";
foreach $newspamlist(@final_sorted_array){
        print SPAMLIST "$newspamlist\n";
}
close(SPAMLIST);

# Remove all email from spam box
open(CLEANSPAMBOX,">$mail") || die "Cannot open $mail\n";
print CLEANSPAMBOX;
close(CLEANSPAMBOX);
}       # Close sub main


sub kill_sendmail {

@processes=`/bin/ps acx`;
$sendmail="alive";

        foreach $procs(@processes){
                if ($procs =~ "sendmail"){
                        @split = split (/\s+/, $procs);
                        $ptokill=$split[0];
                        `/bin/kill $ptokill`;
                }
                else {
                $sendmail="dead";
                }
        }
}

unless ($sendmail =~ "dead"){
        kill_sendmail();
}

if ($sendmail =~ "dead"){
        `/usr/sbin/sendmail -bd &`
}

-- 
Best Regards,
Corey

Reply via email to