Outils personnels

Spamassassin : apprentissage et blacklist automatique

De wikiGite

Révision datée du 14 septembre 2011 à 11:16 par Frank (discussion | contributions)

L'apprentissage des spams (sa-learn) et des hams (non-spams) est très aléatoir et très long sur Spamassassin. Il faut lui donner pratiquement un nombre égal de spams et de hams à apprendre pour qu'il commence à modifier son comportement.

Rien n'empêche de le mettre en place, mais il y a plus direct et plus rapide. Ce qui suit s'applique à des mailboxes au format Maildir.

Créer un répertoire "Junk" et un répertoire "Ham" sous la boîte de réception des utilisateurs. Dans Junk, l'utilisateur pousse les mails qu'il veut voir blacklisté. Dans Ham, il pousse soit les mails que spamassassin a noté spams par erreur (faux-positifs), soit les mails qui auraient été mis dans "Junk" par erreur, et qu'il faudrait donc "dé-blacklister".

Puis dans /etc/cron.daily, créer le script :

#!/bin/bash
date >> /var/log/sa/sa-learn.log
for homedir in $(cat /etc/passwd | awk -F ":" '{ print $6 }')
do
# Directories : ~/Maildir/.INBOX.{Junk,Ham}/{cur,new}

   SADIR=$homedir/.spamassassin
   JUNKMAIL=$homedir/Maildir/.INBOX.Junk
   HAMMAIL=$homedir/Maildir/.INBOX.Ham

   if [ -d $JUNKMAIL ]
   then
      echo $homedir >> /var/log/sa/sa-learn.log
      sa-learn --showdots --no-sync --spam $JUNKMAIL/{cur,new} >> /var/log/sa/sa-learn.log 2>&1
      if [ -d $HAMMAIL ]
      then
         sa-learn --showdots --no-sync --ham $HAMMAIL/{cur,new} >> /var/log/sa/sa-learn.log 2>&1
      fi
   fi

# Blacklisting address of mails manually moved to Junk dir

   for r in cur new
   do
      for m in $(ls $JUNKMAIL/$r/* 2> /dev/null)
      do
   # Only the mails manually moved to Junk to avoid blacklisting Spamassassin false-positives
         grep "^X-Spam-Status: No" $m > /dev/null
         if [ $? -eq 0 ]
         then
            ADDR=$(grep "^From:" $m | grep -o "[\+\_\.[:alnum:]\-]*@[[:alnum:]\.\-]*" | tr "A-Z" "a-z" | sort -u)
   # address successfully decoded
            if [ "$ADDR" != "" ]
            then
   # already recorded ?
               grep $ADDR $SADIR/user_prefs > /dev/null
               if [ $? -eq 1 ]
               then
                  echo "blacklist_from $ADDR" >>  $SADIR/user_prefs
               fi
            fi
         fi
      done
   done
   # Now see if some blacklisted address need to be whitelisted again
   for r in cur new
   do
      for m in $(ls $HAMMAIL/$r/* 2> /dev/null)
      do
         ADDR=$(grep "^From:" $m | grep -o "[\+\_\.[:alnum:]\-]*@[[:alnum:]\.\-]*" | tr "A-Z" "a-z" | sort -u)
   # address successfully decoded
         if [ "$ADDR" != "" ]
         then
   # Blacklisted ?
            grep $ADDR $SADIR/user_prefs > /dev/null
            if [ $? -eq 0 ]
            then
              cat $SADIR/user_prefs | grep -v $ADDR > $SADIR/_user_prefs
              mv $SADIR/_user_prefs $SADIR/user_prefs
            fi
         fi
      done
   done

   # Cleaning
   find $HAMMAIL/{cur,new} -type f -exec rm -f {} \; > /dev/null 2>&1
   # disabled cleaning of spam directory : user must check spams for false-positives
   # find $JUNKMAIL/{cur,new} -type f -exec rm -f {} \; > /dev/null 2>&1

done