[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: setting up spamassassin



also sprach dman <dsh8290@rit.edu> [2002.01.16.0333 +0100]:
> 1)  Why is spamassassin trying to create a preferences file in /?

$HOME isn't set in the script. does exim already have the recipient
user by the time the filter is called?

> 2)  How can users have their own preferences files?  It doesn't seem
>     possible with this setup since either SA is run as 'mail' or every
>     user on the system must be 'privilege'.

there you go, that's the problem. spamassassin is actually designed to
be run by a user. period.

if you want to do it globally, you have a global prefs file.

here's my solution:

i decided i am going to use procmail for delivery (remember my post
about a .forward and Maildir capable MDA? i ditched .forward for good).

but instead of telling postfix/local to use procmail as MDA (by that
time, it knows the recipient, it calls the MDA as the recipient user), i
wrote a perl-script. and made use of Mail::SpamAssassin, which is still
wicked slow (spamassassin is), but it's way faster than the command
invocation.

cat << EOF > /usr/local/sbin/deliver-mail
#!/usr/bin/perl -w

use strict;
use Mail::Audit;
use Mail::SpamAssassin;
use Mail::Address;

for my $i qw(HUP INT QUIT) {
  $SIG{$i} = sub {
    print "deliver-mail: caught SIG$i, trying to defer...\n";
    exit 75;
  };
}

sub defer ($) {
  my $txt = shift;
  print "deliver-mail: $txt";
  exit 75;
}

my $home = $ENV{HOME};
my $audit = Mail::Audit->new;

unless (-f "$home/.no-spamfilter") {
  my $configroot = "/etc/";
  my $rules = $configroot."spamassassin.cf";
  my $prefs = $configroot."spamassassin.prefs";

  -d $configroot or defer "the configroot directory is invalid: $configroot.";
  -r $rules or defer "cannot access the rules file: $rules.";
  -r $prefs or defer "cannot access the prefs file: $prefs.";

  my $assassin = Mail::SpamAssassin->new({
   rules_filename  => $rules,
   userprefs_filename => $prefs,
   dont_copy_prefs  => 1
  });

  my $status  = $assassin->check($audit);

  if (-f "$home/.no-spamreport") {
    my @yes_or_no = qw(No Yes);
    my $hits  = $status->get_hits;
    my $required = $status->get_required_hits;
    my $tests  = $status->get_names_of_tests_hit;

    $audit->replace_header("X-Spam-Status", $yes_or_no[$status->is_spam].
      ", hits=$hits required=$required tests=$tests");
    $audit->replace_header("X-Spam-Flag", "YES") if $status->is_spam;
  }
  else {
    $status->rewrite_mail();
  }
}

$audit->pipe("/usr/bin/procmail DEFAULT=$home/.maildir/");
EOF

yes, i am using global prefs, but user prefs are possible. set
dont_copy_prefs to 0, and leave the {rules,userprefs}_filename
parameters out.

it's nice, because users can touch files ~/.no-spamfilter to completely
disable spamassassin for themselves, and a file ~/.no-spamreport will
just cause the "X-Spam-Flag: YES" header, not the subject line change
and SA report in the body.

in postfix, this is done like so:

  home_mailbox =
  mailbox_command = /usr/local/sbin/deliver-mail
  forward_path =

setting $forward_path to none is important only if you want to prevent
users from circumventing the spamfilters with .forward (postfix still
honours it, if present, despite mailbox_command). i wanted to implement
accounting on top of this with this method, but haven't gotten around to
do it yet.

i am sure exim can do that too. but if you want to do it on a userlevel,
you have to do it after exim decides who's supposed to receive it. and
if you want to prevent the /.spamassassin.rc file creation, then simply
set HOME in your script to /etc/spamassassin.

and don't forget the -P option!

-- 
martin;              (greetings from the heart of the sun.)
  \____ echo mailto: !#^."<*>"|tr "<*> mailto:"; net@madduck
  
"even if you persuade me, you won't persuade me."
                                                       -- aristophanes

Attachment: pgpFMnOLoxFAL.pgp
Description: PGP signature


Reply to: