Spamfilter: Unterschied zwischen den Versionen

Aus Hostsharing Wiki
Zur Navigation springen Zur Suche springen
(angelegt)
 
(Option headers nicht sinnvoll)
 
(18 dazwischenliegende Versionen von 6 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
Einrichtung, Konfiguration und Optimierung eines Spamfilters auf den Hostsharing Servern.


Einrichtung, Konfiguration und Optimierung eines Spamfilters.


Der Spamfilter Spamassasin ist bei HS vorinstalliert. Er kann wie auf der Seite [[Procmail]] beschrieben eigebunden werden.


= Spamassasin Konfigurieren =
= Spamassassin Konfigurieren =


= automatische Mitteilungen über aussortierte Emails =  
Der Spamfilter "Spamassassin" ist bei HS vorinstalliert und kann wie auf der Seite [[Procmail]] beschrieben für eine Mailbox eingebunden werden.
Alternativ kann "spamc", das Kommando zur Nutzung des Spamassassin-Daemon, auch einfach in der Datei ".forward" eines Mail-Users aufgerufen werden:
 
<syntaxhighlight lang=bash>
"|/usr/bin/spamc -U /var/run/spamd -e /usr/lib/dovecot/deliver"
</syntaxhighlight>
 
Der Effekt: Spammassassin schreibt seine Testergebnisse in die Headerzeilen jeder E-Mail und leitet die E-Mails weiter an das Programm "deliver" aus dem Dovecot-Paket. Das Sortieren von Spam-EMail in einen Spam-Ordner lässt ich mit Sieve-Filtern umsetzten.
 
ToDo: Anpassung Konfiguration, Filtertraining
 
= Mitteilungen über aussortierte Emails erzeugen lassen =
 
Spamcheck Verzeichnis im Homeverzeichnis anlegen,
 
<syntaxhighlight lang=bash>
mkdir spamcheck
cd spamcheck
</syntaxhighlight>
 
und dort drei Skriptdateien anlegen und deren Voreinstellungen anpassen:
 
<syntaxhighlight lang=bash line>
cat > check <<EOF
#!/bin/sh
#----------------------------------------------------------------------------------------
# send spam mailfolder infomail
# (c) 04/2004 by ff, webmaster@ff-newmedia.net
#----------------------------------------------------------------------------------------
#set -x
version="0.4 0405201035 (modified)"
mailuser=$1
mailpath="Maildir/.Spam/"
checkmaildir="spamcheck/checkmaildir"
listmaildir="spamcheck/listmaildir"
mailhost="h02"
maildomain="hostsharing.net"
purgetime="7"
 
if ($checkmaildir $mailpath)
    then
        mailbox_status=`$listmaildir $mailpath`
# send infomail
(
echo "From: spamcheck <admin@xyz00.$maildomain>"
        echo "To: $mailuser <$mailuser@$mailhost.$maildomain>"
        echo "Subject: Status des Spam-Ordners"
echo
        echo
        echo "$mailbox_status"
echo
        echo
    echo "Bitte pruefen ob evtl. erwuenschte Nachrichten aussortiert wurden."
echo "Zugriff auf das Postfach ist IMAP oder Webmail moeglich."
        echo "(https://webmail.hostsharing.net)"
        echo
        echo
echo "-- "
echo "created by spamcheck $version"
    )|/usr/lib/sendmail $mailuser@$mailhost.$maildomain
else
    exit 1
fi
 
exit 0
EOF
</syntaxhighlight>
 
<syntaxhighlight lang=bash line>
cat > checkmaildir <<EOF
#!/usr/bin/perl
#----------------------------------------------------------------------------------------
# send spam mailfolder infomail - check if maildir exists
# (c) 05/2004 by ff, webmaster@ff-newmedia.net
# based on mdfrm (c) 1996, Matthew C. Mead
#----------------------------------------------------------------------------------------
 
$maildir = shift;
 
if (!$maildir) {
    $maildir = $ENV{'MAILDIR'};
}
 
if (!$maildir) {
    $maildir = "$ENV{'HOME'}/.Maildir";
}
 
$maildir =~ s/^=/$ENV{'HOME'}\/Mail\//;
 
# Kein Spamordner vorhanden - Errorcode 1
if (!(-d $maildir && -r $maildir && -x $maildir && -d "$maildir/cur" &&
      -r "$maildir/cur" && -x "$maildir/cur" && -d "$maildir/new" &&
      -r "$maildir/new" && -x "$maildir/new")) {
    exit 1;
}
 
# Anderenfalls nachsehen ob Mails vorhanden sind
opendir(DIR, "$maildir/cur");
@tmpfiles = map{$_ = "$maildir/cur/$_"} grep{!/(^\.$)|(^\.\.$)/} readdir(DIR);
@msgfiles = @tmpfiles;
closedir(DIR);
opendir(DIR, "$maildir/new");
@tmpfiles = map{$_ = "$maildir/new/$_"} grep{!/(^\.$)|(^\.\.$)/} readdir(DIR);
push(@msgfiles, @tmpfiles);
closedir(DIR);
 
# Wenn keine Mails vorhanden - Errorcode 1
if (!@msgfiles) {
    exit 1;
}
 
# Wenn Mails vorhanden - Errorcode 0
exit 0;
EOF
</syntaxhighlight>
 
<syntaxhighlight lang=bash line>
cat > listmaildir <<EOF
#!/usr/bin/perl
#----------------------------------------------------------------------------------------
# send spam mailfolder infomail - list maildir contents
# (c) 05/2004 by ff, webmaster@ff-newmedia.net
# based on mdfrm (c) 1996, Matthew C. Mead.
#----------------------------------------------------------------------------------------
$hours = 24; #Anzeigen von Mails, deren mtime hoechstens $hours Stunden in der Vergangenheit liegt
 
use Date::Parse;
use Date::Format;
 
$maildir = shift;
 
if ($maildir eq "-h") {
    print "usage: mdfrm /path/to/Maildir\n";
    print "      mdfrm =Maildir == mdfrm ~/Mail/Maildir\n";
    print "      otherwise, mdfrm defaults to \$MAILDIR\n";
    print "      otherwise, mdfrm defaults to ~/.Maildir\n";
    exit;
}
 
if (!$maildir) {
    $maildir = $ENV{'MAILDIR'};
}
 
if (!$maildir) {
    $maildir = "$ENV{'HOME'}/.Maildir";
}
 
$maildir =~ s/^=/$ENV{'HOME'}\/Mail\//;
 
if (!(-d $maildir && -r $maildir && -x $maildir && -d "$maildir/cur" &&
      -r "$maildir/cur" && -x "$maildir/cur" && -d "$maildir/new" &&
      -r "$maildir/new" && -x "$maildir/new")) {
    # faellt weg, da checkmaildir bereits ueberprueft
    # print "Kein Spamordner in \"$maildir\" vorhanden. Sie haben offensichtlich noch keine Spammails erhalten.\n";
    exit 1;
}
 
opendir(DIR, "$maildir/cur");
@tmpfiles = map{$_ = "$maildir/cur/$_"} grep{!/(^\.$)|(^\.\.$)/} readdir(DIR);
@msgfiles = @tmpfiles;
closedir(DIR);
opendir(DIR, "$maildir/new");
@tmpfiles = map{$_ = "$maildir/new/$_"} grep{!/(^\.$)|(^\.\.$)/} readdir(DIR);
push(@msgfiles, @tmpfiles);
closedir(DIR);
 
@msgs = ( );
 
foreach $file (@msgfiles) {
    # wirkliches Alter der Mail
    $mtime = (stat($file))[9];
 
    $from = "";
    $subject = "";
    $date = 0;
    $hits = 0;
   
    open(INPUT, sprintf("zcat %s |",$file));
 
FILEINPUT:
    while(<INPUT>) {
if (/^From:\s+(.*)$/i) {
    $from = $1;
    next FILEINPUT;
}
if (/^Subject:\s+(.*)$/i) {
    $subject = $1;
    next FILEINPUT;
}
if (/^Date:\s+(.*)$/i) {
    $date = $1;
    next FILEINPUT;
}
if (/^X-Spam-Status: Yes, hits=+(.*)$/i) {
    $hits = $1;
    next FILEINPUT;
}
if (/^\s*$/) {
    last FILEINPUT;
}
if ($from && $subject && $date && $hits) {
    last FILEINPUT;
}
 
    }
 
    close(INPUT);
 
    @tmp = ( str2time($date), $from, $subject, $mtime, $hits );
    push(@msgs, [ @tmp ]);
}
   
$oldest = time - $hours * 3600; # Berechnen des Timestamps now - $hours
 
$o = 0;
 
foreach $msg (@msgs){
    if ($msg->[3] >= $oldest) { # Innerhalb der letzten $hours aussortierte Mails
    $o++;
    }
 
    $i++; # alle Mails
}
 
if ($i==0) { # Wenn keine Mail da sind, Errorcode 1
    exit 1;
}
 
print("Insgesamt befinden sich ", $i, " E-Mails in Ihrem Trash-Ordner.\n");
print("In den letzen ", $hours, " Stunden wurden ", $o, " Spam-E-Mails
aussortiert.\n\n");
if ($o==0) { exit 0; }
print("Datum (mtime)  Absender              Betreff                      Hits\n");
print("-----------------------------------------------------------------------");
 
    foreach $msg (sort {$b->[3] <=> $a->[3]} @msgs) { # Sortierung vorher auf 0/0
if ($msg->[3] >= $oldest) {
        if ($msg->[1] =~ /\s*"*([^"]*)"*\s*\<[a-zA-Z0-9._%-=]+@[a-zA-Z0-9._%-=]+\>/) {
$from = $1;
        } elsif ($msg->[1] =~ /[a-zA-z0-9._%-=]+@[a-zA-Z0-9._%-=]+.*\("*([^"]*)"*\)/) {
$from = $1;
    } else {
$from = $msg->[1];
    }
 
    # Datum ausgeben
    if (time2str("%d",$msg->[3]) <=> $olddate) {
    print("\n");
    } 
   
    # Urspruengliches aus der Mail extrahiertes Datum, sinnlos weil oft gefaelscht
    # printf("%-12s  ", time2str("%d.%m.%y %H:%M",$msg->[0]));
    printf("%-12s  ", time2str("%d.%m.%y %H:%M",$msg->[3]));
   
        $olddate = time2str("%d",$msg->[3]);   
 
    # From ausgeben
        if (length($from) <= 20) {
printf("%-20s  ", $from);
    } else {
printf("%-.20s  ", $from);
    }
   
    # um *****SPAM***** bereinigtes Subject ausgeben
    @sub = $msg->[2];
    if (length(@sub) <= 27) {
printf("%-27s  ", @sub);
    } else {
printf("%-.27s  ", @sub);
    }
   
    # Punkte
    if (length($msg->[4]) <= 4) {
printf("%-4s\n", $msg->[4]);
    } else {
printf("%-.4s\n", $msg->[4]);
    }
   
 
}
    }
 
exit 0;
EOF
</syntaxhighlight>
 
Und diese ausführbar machen:
<syntaxhighlight lang=bash>
chmod a+x check checkmaildir listmaildir
</syntaxhighlight>
 
Anschließend einen [[Cron]]job anlegen, der check für den Mailboxuser aufruft:
 
<syntaxhighlight lang=bash>
#Spam Verzeichnis checken
51 5 * * * sleep $[ ($RANDOM % 120) ]; spamcheck/check xyz00-otto
</syntaxhighlight>


= Automatisches löschen aussortierter Emails =
= Automatisches löschen aussortierter Emails =
ToDo: Emails nach einer bestimmten Zeit löschen.
----
[[Kategorie:HSDoku]]
[[Kategorie:Installationsanleitungen]]
[[Kategorie:Software]]
[[Kategorie:Glossar]]

Aktuelle Version vom 8. August 2024, 13:42 Uhr

Einrichtung, Konfiguration und Optimierung eines Spamfilters auf den Hostsharing Servern.


Spamassassin Konfigurieren

Der Spamfilter "Spamassassin" ist bei HS vorinstalliert und kann wie auf der Seite Procmail beschrieben für eine Mailbox eingebunden werden. Alternativ kann "spamc", das Kommando zur Nutzung des Spamassassin-Daemon, auch einfach in der Datei ".forward" eines Mail-Users aufgerufen werden:

"|/usr/bin/spamc -U /var/run/spamd -e /usr/lib/dovecot/deliver"

Der Effekt: Spammassassin schreibt seine Testergebnisse in die Headerzeilen jeder E-Mail und leitet die E-Mails weiter an das Programm "deliver" aus dem Dovecot-Paket. Das Sortieren von Spam-EMail in einen Spam-Ordner lässt ich mit Sieve-Filtern umsetzten.

ToDo: Anpassung Konfiguration, Filtertraining

Mitteilungen über aussortierte Emails erzeugen lassen

Spamcheck Verzeichnis im Homeverzeichnis anlegen,

mkdir spamcheck
cd spamcheck

und dort drei Skriptdateien anlegen und deren Voreinstellungen anpassen:

cat > check <<EOF
#!/bin/sh
#----------------------------------------------------------------------------------------
# send spam mailfolder infomail
# (c) 04/2004 by ff, webmaster@ff-newmedia.net
#----------------------------------------------------------------------------------------
#set -x
version="0.4 0405201035 (modified)"
mailuser=$1
mailpath="Maildir/.Spam/"
checkmaildir="spamcheck/checkmaildir"
listmaildir="spamcheck/listmaildir"
mailhost="h02"
maildomain="hostsharing.net"
purgetime="7"

if ($checkmaildir $mailpath)
    then
        mailbox_status=`$listmaildir $mailpath`
	# send infomail
	(
	echo "From: spamcheck <admin@xyz00.$maildomain>"
        echo "To: $mailuser <$mailuser@$mailhost.$maildomain>"
        echo "Subject: Status des Spam-Ordners"
	echo
        echo
        echo "$mailbox_status"
	echo
        echo
    	echo "Bitte pruefen ob evtl. erwuenschte Nachrichten aussortiert wurden."
	echo "Zugriff auf das Postfach ist IMAP oder Webmail moeglich."
        echo "(https://webmail.hostsharing.net)"
        echo
        echo
	echo "-- "
	echo "created by spamcheck $version"
    )|/usr/lib/sendmail $mailuser@$mailhost.$maildomain
else
    exit 1
fi

exit 0
EOF
cat > checkmaildir <<EOF
#!/usr/bin/perl
#----------------------------------------------------------------------------------------
# send spam mailfolder infomail - check if maildir exists
# (c) 05/2004 by ff, webmaster@ff-newmedia.net
# based on mdfrm (c) 1996, Matthew C. Mead
#----------------------------------------------------------------------------------------

$maildir = shift;

if (!$maildir) {
    $maildir = $ENV{'MAILDIR'};
}

if (!$maildir) {
    $maildir = "$ENV{'HOME'}/.Maildir";
}

$maildir =~ s/^=/$ENV{'HOME'}\/Mail\//;

# Kein Spamordner vorhanden - Errorcode 1
if (!(-d $maildir && -r $maildir && -x $maildir && -d "$maildir/cur" &&
      -r "$maildir/cur" && -x "$maildir/cur" && -d "$maildir/new" &&
      -r "$maildir/new" && -x "$maildir/new")) {
    exit 1;
}

# Anderenfalls nachsehen ob Mails vorhanden sind
opendir(DIR, "$maildir/cur");
@tmpfiles = map{$_ = "$maildir/cur/$_"} grep{!/(^\.$)|(^\.\.$)/} readdir(DIR);
@msgfiles = @tmpfiles;
closedir(DIR);
opendir(DIR, "$maildir/new");
@tmpfiles = map{$_ = "$maildir/new/$_"} grep{!/(^\.$)|(^\.\.$)/} readdir(DIR);
push(@msgfiles, @tmpfiles);
closedir(DIR);

# Wenn keine Mails vorhanden - Errorcode 1
if (!@msgfiles) {
    exit 1;
}

# Wenn Mails vorhanden - Errorcode 0
exit 0;
EOF
cat > listmaildir <<EOF
#!/usr/bin/perl
#----------------------------------------------------------------------------------------
# send spam mailfolder infomail - list maildir contents
# (c) 05/2004 by ff, webmaster@ff-newmedia.net
# based on mdfrm (c) 1996, Matthew C. Mead.
#----------------------------------------------------------------------------------------
$hours = 24; #Anzeigen von Mails, deren mtime hoechstens $hours Stunden in der Vergangenheit liegt

use Date::Parse;
use Date::Format;

$maildir = shift;

if ($maildir eq "-h") {
    print "usage: mdfrm /path/to/Maildir\n";
    print "       mdfrm =Maildir == mdfrm ~/Mail/Maildir\n";
    print "       otherwise, mdfrm defaults to \$MAILDIR\n";
    print "       otherwise, mdfrm defaults to ~/.Maildir\n";
    exit;
}

if (!$maildir) {
    $maildir = $ENV{'MAILDIR'};
}

if (!$maildir) {
    $maildir = "$ENV{'HOME'}/.Maildir";
}

$maildir =~ s/^=/$ENV{'HOME'}\/Mail\//;

if (!(-d $maildir && -r $maildir && -x $maildir && -d "$maildir/cur" &&
      -r "$maildir/cur" && -x "$maildir/cur" && -d "$maildir/new" &&
      -r "$maildir/new" && -x "$maildir/new")) {
    # faellt weg, da checkmaildir bereits ueberprueft
    # print "Kein Spamordner in \"$maildir\" vorhanden. Sie haben offensichtlich noch keine Spammails erhalten.\n";
    exit 1;
}

opendir(DIR, "$maildir/cur");
@tmpfiles = map{$_ = "$maildir/cur/$_"} grep{!/(^\.$)|(^\.\.$)/} readdir(DIR);
@msgfiles = @tmpfiles;
closedir(DIR);
opendir(DIR, "$maildir/new");
@tmpfiles = map{$_ = "$maildir/new/$_"} grep{!/(^\.$)|(^\.\.$)/} readdir(DIR);
push(@msgfiles, @tmpfiles);
closedir(DIR);

@msgs = ( );

foreach $file (@msgfiles) {
    # wirkliches Alter der Mail
    $mtime = (stat($file))[9];

    $from = "";
    $subject = "";
    $date = 0;
    $hits = 0;
    
    open(INPUT, sprintf("zcat %s |",$file));

FILEINPUT:
    while(<INPUT>) {
	
	if (/^From:\s+(.*)$/i) {
	    $from = $1;
	    next FILEINPUT;
	}
	
	if (/^Subject:\s+(.*)$/i) {
	    $subject = $1;
	    next FILEINPUT;
	}
	
	if (/^Date:\s+(.*)$/i) {
	    $date = $1;
	    next FILEINPUT;
	}
	
	if (/^X-Spam-Status: Yes, hits=+(.*)$/i) {
	    $hits = $1;
	    next FILEINPUT;
	}
	
	if (/^\s*$/) {
	    last FILEINPUT;
	}
	
	if ($from && $subject && $date && $hits) {
	    last FILEINPUT;
	}

    }

    close(INPUT);

    @tmp = ( str2time($date), $from, $subject, $mtime, $hits );
    push(@msgs, [ @tmp ]);
}
    
$oldest = time - $hours * 3600; # Berechnen des Timestamps now - $hours

$o = 0;

foreach $msg (@msgs){
    if ($msg->[3] >= $oldest) { # Innerhalb der letzten $hours aussortierte Mails
    $o++;
    }

    $i++; # alle Mails
}

if ($i==0) { # Wenn keine Mail da sind, Errorcode 1
    exit 1;
}

print("Insgesamt befinden sich ", $i, " E-Mails in Ihrem Trash-Ordner.\n");
print("In den letzen ", $hours, " Stunden wurden ", $o, " Spam-E-Mails
aussortiert.\n\n");
if ($o==0) { exit 0; }
print("Datum (mtime)   Absender              Betreff                      Hits\n");
print("-----------------------------------------------------------------------");

    foreach $msg (sort {$b->[3] <=> $a->[3]} @msgs) { # Sortierung vorher auf 0/0
	if ($msg->[3] >= $oldest) {
    	    if ($msg->[1] =~ /\s*"*([^"]*)"*\s*\<[a-zA-Z0-9._%-=]+@[a-zA-Z0-9._%-=]+\>/) {
		$from = $1;
    	    } elsif ($msg->[1] =~ /[a-zA-z0-9._%-=]+@[a-zA-Z0-9._%-=]+.*\("*([^"]*)"*\)/) {
		$from = $1;
	    } else {
		$from = $msg->[1];
	    }

	    # Datum ausgeben
	    if (time2str("%d",$msg->[3]) <=> $olddate) {
    		print("\n");
	    }   
	    
	    # Urspruengliches aus der Mail extrahiertes Datum, sinnlos weil oft gefaelscht
	    # printf("%-12s  ", time2str("%d.%m.%y %H:%M",$msg->[0]));
	    printf("%-12s  ", time2str("%d.%m.%y %H:%M",$msg->[3]));
    
    	    $olddate = time2str("%d",$msg->[3]);    

	    # From ausgeben
    	    if (length($from) <= 20) {
		printf("%-20s  ", $from);
	    } else {
		printf("%-.20s  ", $from);
	    }
    
	    # um *****SPAM***** bereinigtes Subject ausgeben
	    @sub = $msg->[2];
	    if (length(@sub) <= 27) {
		printf("%-27s  ", @sub);
	    } else {
		printf("%-.27s  ", @sub);
	    }
	    
	    # Punkte
	    if (length($msg->[4]) <= 4) {
		printf("%-4s\n", $msg->[4]);
	    } else {
		printf("%-.4s\n", $msg->[4]);
	    }
	    

	}
    }

exit 0;
EOF

Und diese ausführbar machen:

chmod a+x check checkmaildir listmaildir

Anschließend einen Cronjob anlegen, der check für den Mailboxuser aufruft:

#Spam Verzeichnis checken
51 5 * * * sleep $[ ($RANDOM % 120) ]; spamcheck/check xyz00-otto

Automatisches löschen aussortierter Emails

ToDo: Emails nach einer bestimmten Zeit löschen.