SA-Learn erweiterung


stevie

New Member
Hallo,

ich nutze den sa-wrapper von Huschi ohne Probleme. Vielen Dank dafür.
Da ich demnächst die Methode zum Spam/Ham lernen für meine Kunden veröffentlichen will, möchte ich sicherstellen, das nur die Mails von meinen Kunden/Domains gelernt werden. Dafür habe ich das Wrapper Skript von Huschi erweitert. Da ich nicht viel Perl Erfahrungen habe, gehe ich davon aus, das eventuell noch Optimierungen möglich sind. Funktionieren tut das Skript aber auch so. Ideen und Verbesserungen sind herzlich willkommen.

Damit das Skript den Sender kennt, muss dieser übergeben werden. Da ich qmail benutze, passe ich dazu die .qmail datei des postfachs an und füge $SENDER hinzu.

vim /srv/vpopmail/domains/mail.domain.com/ham/.qmail
Code:
|/var/qmail/bin/preline /usr/local/bin/sa-wrapper.pl --ham $SENDER
vim /srv/vpopmail/domains/mail.domain.com/spam/.qmail
Code:
|/var/qmail/bin/preline /usr/local/bin/sa-wrapper.pl --spam $SENDER

Anpassung des sa-wrapper Skripts:
Die im Skript umgesetzte Methode mit einem "die" funktioniert nicht sehr gut. Dadurch werden die Mails als nicht erfolgreich zugestellt wieder in die Queue gelegt. Darum ändere ich das Skript so, das nur bei korrekter Senderdomain sa-learn aufgerufen wird. Somit wird die Mail korrekt zugestellt. Ansonsten gibt es eine Benachrichtigung, dass der Sender abgewiesen wurde, welches in der Log zu sehen ist.
Des Weiteren möchte ich automatisch die rcptohosts Datei als Grundlage der zugangsberechtigten Domains auslesen. Das ist für mich dynamischer und damit praktischer.


vim /usr/local/bin/sa-wrapper.pl
Code:
#!/usr/bin/perl -w
# Time-stamp: <05 April 2004, 13:37 home>
#
# sa-wrapper.pl
#
# SpamAssassin sa-learn wrapper
# (c) Alexandre Jousset, 2004
# This script is GPL'd
#
# Thanks to: Chung-Kie Tung for the removal of the dir
#            Adam Gent for bug report
#
# v1.2

use strict;
use MIME::Tools;
use MIME::Parser;

my $DEBUG = 0;
my $LOGFILE = '/var/log/sa-learn.log';
my $UNPACK_DIR = '/var/spool/unpack';
my $SA_LEARN = '/usr/bin/sa-learn';
my $RCPTOHOSTS ='/etc/qmail/rcpthosts';

open RCPTHOSTF,"<",$RCPTOHOSTS or die $!;
my @DOMAINS = <RCPTHOSTF>;
chomp(@DOMAINS);
#my @DOMAINS = qw/gtmp.org winnink.org /;
close RCPTHOSTF or die $!;
#print "domains: @DOMAINS"; #DEBUG

my $SENDERNALLOWED = 0;

my ($spamham, $sender) = @ARGV;
#print "Sender: $sender"; #DEBUG

sub recurs
{
        my $ent = shift;

        if ($ent->head->mime_type eq 'message/rfc822') {
                if ($DEBUG) {
                        #unlink "/tmp/spam.log.$$" if -e "/tmp/spam.log.$$";
                        open(OUT, "|$SA_LEARN -D $spamham --single >>$LOGFILE 2>&1") or die "Cannot pipe $SA_LEARN: $!";
                } else {
                        open(OUT, "|$SA_LEARN $spamham --single") or die "Cannot pipe $SA_LEARN: $!";
                }

                $ent->bodyhandle->print(\*OUT);

                close(OUT);
                return;
        }

        my @parts = $ent->parts;

        if (@parts) {
                map { recurs($_) } @parts;
        }
}

my ($domain) = $sender =~ /\@(.*)$/;
unless (grep { $_ eq $domain } @DOMAINS) {
#       die "I don't recognize your domain !"; # This causes the mail to be denied and stucked in queue -> ignore
#       print "domain: $domain"; #DEBUG
        $SENDERNALLOWED = 1;
}

if ($DEBUG) {
        MIME::Tools->debugging(1);
        open(STDERR, '>>/tmp/spam_err.log');
}
my $parser = new MIME::Parser;
$parser->extract_nested_messages(0);
$parser->output_under($UNPACK_DIR);

my $entity;
eval {
        $entity = $parser->parse(\*STDIN);
};

if ($@) {
        die $@;
} else {
        #if sender is allowed we do sa-learn
        if ($SENDERNALLOWED == 0){
        recurs($entity);
        }
        else{
        print "Sender not allowed: $sender, $SENDERNALLOWED";
        }
}

$parser->filer->purge;
rmdir $parser->output_dir;
 
Ich hätte noch eine Idee.
Noch besser wäre es, wenn der SMTP schon entscheidet, ob das sa-wrapper Skript für diese Postfächer ausgeführt wird.
Ist dies mit Qmail möglich?
 

Back
Top