1. Please take a little time for this simple survey! Thank you for participating!
    Dismiss Notice
  2. Dear Pleskians, please read this carefully! New attachments and other rules Thank you!
    Dismiss Notice
  3. Dear Pleskians, I really hope that you will share your opinion in this Special topic for chatter about Plesk in the Clouds. Thank you!
    Dismiss Notice

Train Spamassassin in IMAP

Discussion in 'Plesk for Linux - 8.x and Older' started by inc595, Oct 23, 2008.

  1. inc595

    inc595 Guest

    0
     
    I re-wrote my bash version into perl. It creates junk, ham_learn and spam_learn directories in all mailboxes. You can then use move spam messages to spam_learn directory to train spamassassin just as you would in the Plesk control panel. Then do the same to non-spam or "ham" mail by moving some mail to the ham_learn.

    The first time the script is run it will check to see if the directories exist. If they do not then it will create them. If they do exist it will then learn from the mail in them. Ham mail is moved back to the inbox and spam mail is deleted. Any mail already tagged as spam is moved into the junk dir and then removed after 15 days.


    Simply ceate the script /usr/local/sbin/psa-sa_learn.pl and set permissions
    Code:
    vi /usr/local/sbin/psa-sa_learn.pl
    chmod +x /usr/local/sbin/psa-sa_learn.pl
    
    Then paste in the following
    Code:
    #!/usr/bin/perl
    
    use Switch;
    use File::Copy;
    
    $version="Plesk Spamassassin Learn Version 0.3 --writen by inc595";
    $maildir="/var/qmail/mailnames";
    $mode=$ARGV[0];
    
    if ( "$ARGV[1]" != "" ) {
       $domainlist=$ARGV[1];
       print $domainlist;
    }else{
       @dmnlist=</var/qmail/mailnames/*>;
       foreach $dmn (@dmnlist) {
          split(/\//, $dmn);
          push (@domainlist, $_[4]); 
       }
    }
    
    switch ($mode) {
       case /-n|-t|-j/ {
          learn();
       }
       case /-v|-V/ {
            print $version;
       }
       case "--help" {
          print "Description: 
    This script creates ham_learn and spam_learn directories in all mailboxes.
    If users are using webmail or IMAP they can train spamassassin by moving
    mail to ham_learn to for good mail and spam_learn for spam mail.\n
    Usage: psa-sa_learn.sh [OPTION] | All domains
    \tpsa-sa_learn.sh [OPTION] example.com | Single domain
    -n\t\tNormal mode\tRun live and silent.
    -t \t\tTest mode\tRun without making change.
    \t\t\t\tand display what would happen.
    -v \t\t\tDisplay Version information.\n";
       }
       else { print "psa-sa_learn.pl: missing file argument\nTry \'psa-sa_learn.pl --help\' for more information."; }
    }
    
    #subs
    sub learn(){
       foreach $domain (@domainlist) {
          foreach $mailname (`ls $maildir/$domain | grep -v .spamassassin | grep -v .qmail-default | grep -v user_prefs | grep -v auto-whitelist | grep -v bayes* | grep -v "@mbox.quota" | grep -v "*qmail*"`){
             chomp($maildir);
             chomp($mailname);
             $path="$maildir/$domain/$mailname";
             $jpath="$path/Maildir/.junk";
             if (-d $jpath ) {
                switch ($mode) {
                   case "-t" { print "Junk directory exists.\n$jpath\n"; }
                   case "-j" {
                      create_qmail();
                      create_procmail();
                   }
                }
             }else{
                switch ($mode) {
                   case "-t" { print "Junk directory does not exist.\nCreating $jpath\n"; }
                   case "-n" {
                      mkdir("$jpath", 0700) || print $!;
                      mkdir("$jpath/cur", 0700) || print $!;
                      mkdir("$jpath/new", 0700) || print $!;
                      mkdir("$jpath/tmp", 0700) || print $!;
                      open(MDF, ">>$jpath/maildirfolder");
                      chmod(0600, "$jpath/maildirfolder");
                      open(CIA, "$jpath/courierimapacl");
                         print CIA "owner aceilrstwx";
                      close (CIA);
                      chmod(0644, "$jpath/courierimapacl");
                      `chown -R popuser:popuser $jpath`;
                      create_qmail($path);
                      create_procmail($path);
                   }
                }
             }
             foreach $type ( 'spam', 'ham' ) {
                $mpath="$path/Maildir/.$type\_learn";
                if ( -d $mpath ) {
                   switch ($mode) {
                      case "-t" {
                         print "$type directory exists.\n$mpath\n";
                         if ( `ls -l $mpath/cur/ | wc -l` != 1 ) {
                            print "Not empty; learning $type.\n";
                            print "/usr/local/psa/admin/sbin/spammng --bayes --mailname=$mailname@$domain --$type=$mpath/cur/*\n";
                            if ( $type eq 'spam' ) {
                               print "rm $mpath/cur/*\n";
                               print "$mpath/cur/* for $mailname@$domain has been deleted\n";
                            }elsif ( $type eq 'ham' ) {
                               print "mv $mpath/cur/*  $maildir/$domain/$mailname/Maildir/cur\n";
                               print "$mpath/cur/* for $mailname@$domain has been moved to the inbox\n";
                            }else{
                               print "You should not see me\n";
                            }
                         }else{
                            print "Directory empty; skipping $type.";
                         }
                      }
                      case "-n" {
                         if ( `ls -l $mpath/cur/ | wc -l` != 1 ) {
                            `/usr/local/psa/admin/sbin/spammng --bayes --mailname=$mailname@$domain --$type=$mpath/cur/*`;
                            if ( $type eq 'spam' ) {
                               unlink ("$mpath/cur/*");
                            }elsif ( $type eq 'ham' ) {
                               $oldlocation="$mpath/cur/*";
                               $newlocation="$maildir/$domain/$mailname/Maildir/cur";
                               `mv $oldlocation $newlocation`;
                            }else{
                               print "You should not see me";
                            }
                         }
                      }
                   }   
                }else{
                   switch ($mode) {
                      case "-t" { print "Directory does not exist;\nCreating $mpath\n"; }
                      case "-n" {
                         mkdir("$mpath", 0700) || print $!;
                         mkdir("$mpath/cur", 0700) || print $!;
                         mkdir("$mpath/new", 0700) || print $!;
                         mkdir("$mpath/tmp", 0700) || print $!;
                         open(MDF, ">>$mpath/maildirfolder");
                         chmod(0600, "$mpath/maildirfolder");
                         open(CIA, "$mpath/courierimapacl");
                            print CIA "owner aceilrstwx";
                         close (CIA);
                         chmod(0644, "$mpath/courierimapacl");
                      }
                   }
                }
             }
          }
       }
    }
    
    sub create_qmail() {
    $file="$path/.qmail";
    $forward=`grep '&' $file`;
       open(QM, ">$file");
       print QM "| /usr/local/psa/bin/psa-spamc accept
    |preline /usr/bin/procmail -m -o .procmailrc
    |find ./Maildir/.junk/cur -type f -mtime +15 -exec rm {} \\;
    $forward";
       close(QM);
       `chown popuser:popuser $file`;
    }
    
    sub create_procmail($pth) {
       $file="$path/.procmailrc";
       print "$file\n";
       open(PROC, ">$file");
       print PROC "
    MAILDIR=$maildir/$domain/$mailname/Maildir/
    DEFAULT=\${MAILDIR}/
    SPAMDIR=\${MAILDIR}/.junk/
    # All mail tagged as spam (eg. with a score higher than the set threshold)
    # is moved to the designated spam folder
    :0
    * ^X-Spam-Status: Yes.*
    \${SPAMDIR}
    ";
       close(PROC);
       chmod(0600, "$file");
       `chown popuser:popuser $file`;
    }

    Then run every hour by editing your crontab.

    Code:
    crontab -e
    And add this.
    Code:
    0 */1 * * * /usr/local/sbin/psa-sa_learn.pl -n >/dev/null 2>&1
     
  2. inc595

    inc595 Guest

    0
     
    Horde Spam Handling Options

    To turn on Spam reporting options in Horde and tailor them to work with my script I modified the following files. What it does is turn on an "Empty Spam" icon. This will empty the junk folder. Then it creates a "Report as Spam" link which moves mail to the spam_learn directory. It also creates a 'Report as Innocent" link that moves mail to the ham_learn directory. This helps users in Horde to not have to understand what is going on as much.

    Code:
    /usr/share/psa-horde/imp/config/conf.php
    /usr/share/psa-horde/imp/config/prefs.php
    /usr/share/psa-horde/imp/mailbox.php
    /usr/share/psa-horde/imp/message.php
    

    Make sure to back them up before making any changes.
    Code:
    cp /usr/share/psa-horde/imp/config/conf.php /usr/share/psa-horde/imp/config/conf.php.original
    cp /usr/share/psa-horde/imp/config/prefs.php /usr/share/psa-horde/imp/config/prefs.php.original
    cp /usr/share/psa-horde/imp/mailbox.php /usr/share/psa-horde/imp/mailbox.php.original
    cp /usr/share/psa-horde/imp/message.php /usr/share/psa-horde/imp/message.php.original
    
    These diffs show the line number and what was modified or added to each respective file. Since we modified the default prefs the user doesn't need to set them for these to work. The user can still overide these settings in Horde, but that's on them.

    #/usr/share/psa-horde/imp/config/conf.php
    Code:
    *** conf.php	2008-11-07 09:05:34.000000000 -0500
    --- conf.php.original	2008-11-07 09:05:55.000000000 -0500
    ***************
    *** 35,44 ****
      $conf['fetchmail']['size_limit'] = '4000000';
      $conf['msgsettings']['filtering']['words'] = './config/filter.txt';
      $conf['msgsettings']['filtering']['replacement'] = '****';
    ! $conf['spam']['spamfolder'] = true;
    ! $conf['spam']['notspamfolder'] = true;
    ! $conf['spam']['reporting'] = true;
    ! $conf['notspam']['reporting'] = true;
      $conf['msg']['prepend_header'] = false;
      $conf['msg']['append_trailer'] = false;
      $conf['compose']['use_vfs'] = false;
    --- 35,42 ----
      $conf['fetchmail']['size_limit'] = '4000000';
      $conf['msgsettings']['filtering']['words'] = './config/filter.txt';
      $conf['msgsettings']['filtering']['replacement'] = '****';
    ! $conf['spam']['reporting'] = false;
    ! $conf['notspam']['reporting'] = false;
      $conf['msg']['prepend_header'] = false;
      $conf['msg']['append_trailer'] = false;
      $conf['compose']['use_vfs'] = false;
    
    #/usr/share/psa-horde/imp/config/prefs.php
    Code:
    *** prefs.php	2008-11-07 10:12:18.000000000 -0500
    --- prefs.php.original	2008-11-07 09:05:50.000000000 -0500
    ***************
    *** 295,301 ****
      
      // spam folder
      $_prefs['spam_folder'] = array(
    !     'value' => 'junk',
          'locked' => false,
          'shared' => false,
          'type' => 'implicit');
    --- 295,301 ----
      
      // spam folder
      $_prefs['spam_folder'] = array(
    !     'value' => 'Spam',
          'locked' => false,
          'shared' => false,
          'type' => 'implicit');
    ***************
    *** 600,613 ****
      
      // What should we do with spam messages after reporting them?
      $_prefs['delete_spam_after_report'] = array(
    !     'value' => 3,
          'locked' => false,
          'shared' => false,
          'type' => 'enum',
          'enum' => array(0 => _("Nothing"),
                          1 => _("Delete spam messages"),
    !                     2 => _("Move spam messages to spam folder and innocent messages to INBOX"),
    !                     3 => _("Move spam messages to spam_learn folder and innocent messages to ham_learn")),
          'desc' => _("What should we do with spam messages after they have been reported as spam or innocent?"),
          'help' => 'prefs-delete_spam_after_report'
      );
    --- 600,612 ----
      
      // What should we do with spam messages after reporting them?
      $_prefs['delete_spam_after_report'] = array(
    !     'value' => 0,
          'locked' => false,
          'shared' => false,
          'type' => 'enum',
          'enum' => array(0 => _("Nothing"),
                          1 => _("Delete spam messages"),
    !                     2 => _("Move spam messages to spam folder and innocent messages to INBOX")),
          'desc' => _("What should we do with spam messages after they have been reported as spam or innocent?"),
          'help' => 'prefs-delete_spam_after_report'
      );
    ***************
    *** 759,765 ****
      
      // display the 'Empty Spam' link in the menubar?
      $_prefs['empty_spam_menu'] = array(
    !     'value' => 1,
          'locked' => false,
          'shared' => false,
          'type' => 'checkbox',
    --- 758,764 ----
      
      // display the 'Empty Spam' link in the menubar?
      $_prefs['empty_spam_menu'] = array(
    !     'value' => 0,
          'locked' => false,
          'shared' => false,
          'type' => 'checkbox',
    
    #/usr/share/psa-horde/imp/mailbox.php
    Code:
    *** mailbox.php	2008-11-07 10:05:04.000000000 -0500
    --- mailbox.php.original	2008-11-07 10:07:00.000000000 -0500
    ***************
    *** 171,183 ****
              require_once IMP_BASE . '/lib/Message.php';
              $imp_message = &IMP_Message::singleton();
              $imp_message->copy($targetMbox, IMP_MESSAGE_MOVE, $indices_mbox, true);
    -     } elseif ($delete_spam == 3) {
    -         $targetMbox = ($action == 'spam') ? IMP::folderPref('spam_learn', true) : 'INBOX.ham_learn';
    -         require_once IMP_BASE . '/lib/Message.php';
    -         $imp_message = &IMP_Message::singleton();
    -         $imp_message->copy($targetMbox, IMP_MESSAGE_MOVE, $indices_mbox, true);
          }
    - 
          break;
      
      case 'message_missing':
    --- 171,177 ----
    
    #/usr/share/psa-horde/imp/message.php
    Code:
    *** message.php	2008-11-07 10:04:49.000000000 -0500
    --- message.php.original	2008-11-07 10:07:14.000000000 -0500
    ***************
    *** 162,179 ****
                      require IMP_BASE . '/mailbox.php';
                      exit;
                  }
    -     } elseif ($delete_spam == 3) {
    -         $targetMbox = ($action == 'spam') ? IMP::folderPref('spam_learn', true) : 'INBOX.ham_learn';
    -         if ($targetMbox) {
    -             require_once IMP_BASE . '/lib/Message.php';
    -             $imp_message = &IMP_Message::singleton();
    -             $imp_message->copy($targetMbox, IMP_MESSAGE_MOVE, $imp_mailbox, true);
    -             if ($prefs->getValue('mailbox_return')) {
    -                 _returnToMailbox($imp_mailbox->getMessageIndex());
    -                 require IMP_BASE . '/mailbox.php';
    -                 exit;
    -             }
    - 
              } else {
                  $notification->push(_("Could not move message to spam mailbox - no spam mailbox defined in preferences."), 'horde.error');
              }
    --- 162,167 ----
    
     
Loading...