Ayant de plus en plus d'utilisateurs mail sur mes machines, et certains ayant des besoins spécifiques au niveau du filtrage des spams, il semblait évident qu'il faille changer de stratégie pour spamassassin (un seul utilisateur, une seule base bayes, un seul fichier de préférences).
Je me suis donc attelé à la tâche afin de migrer tout ça en base MySQL, et comme je ne suis pas du genre radin, je vous en fais profiter :)
Le howto a été réalisé sur une Debian sid.

Je pars ici du principe que vous avez les choses suivantes déjà fonctionnelles :

  • Postfix
  • Spamassassin en configuration mono-utilisateur
  • MySQL
  • Squirrelmail

Tout d'abord, sauvegardons la base bayes de l'utilisateur qui analyse les mails, je pars du principe qu'il se nomme spamd :

# su - spamd
$ sa-learn --backup > /tmp/sa_backup.txt

Créez une base dans votre MySQL, ou réutilisez celle que vous aviez déjà pour stocker vos utilisateurs virtuels. Je suis personnellement dans le second cas ici, la base s'appelle maildb. Passons à la création des tables nécessaires :

$ wget http://blog.hacky.info/public/base_spam.sql
$ mysql -u root -p maildb < base_spam.sql
Enter password:

Vous pouvez réutiliser le même utilisateur MySQL que postfix utilise pour aller consulter ses tables de configuration, mais il est beaucoup plus sécurisé de créer un autre utilisateur n'ayant accès qu'aux tables awl, bayes_expire, bayes_global_vars, bayes_seen, bayes_token, bayes_vars et userpref.

$ mysql -u root -p
Enter password:
mysql> CREATE USER 'spamd'@'localhost' IDENTIFIED BY 'password("motdepasse")';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL ON `maildb`.`awl` TO 'spamd'@'localhost' WITH GRANT OPTION ;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL ON `maildb`.`bayes_expire` TO 'spamd'@'localhost' WITH GRANT OPTION ;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL ON `maildb`.`bayes_global_vars` TO 'spamd'@'localhost' WITH GRANT OPTION ;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL ON `maildb`.`bayes_seen` TO 'spamd'@'localhost' WITH GRANT OPTION ;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL ON `maildb`.`bayes_token` TO 'spamd'@'localhost' WITH GRANT OPTION ;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL ON `maildb`.`bayes_vars` TO 'spamd'@'localhost' WITH GRANT OPTION ;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL ON `maildb`.`userpref` TO 'spamd'@'localhost' WITH GRANT OPTION ;
Query OK, 0 rows affected (0.00 sec)

Éditons maintenant la configuration de spamassassin :
Changez la ligne OPTIONS du fichier /etc/default/spamassassin :

OPTIONS="--max-children 5 --username spamd --nouser-config --sql-config"

Commentez tout ce qui fait référence à vos anciens paramètres de configuration dans le fichier /etc/spamassassin/local.cf puis ajoutez ceci :

bayes_store_module              Mail::SpamAssassin::BayesStore::MySQL
auto_whitelist_factory          Mail::SpamAssassin::SQLBasedAddrList
user_awl_sql_table              awl
bayes_sql_override_username     root
user_scores_dsn                 DBI:mysql:maildb:localhost
user_scores_sql_username        spamd
user_scores_sql_password        motdepasse
user_awl_dsn                    DBI:mysql:maildb:localhost
user_awl_sql_username           spamd
user_awl_sql_password           motdepasse
bayes_sql_dsn                   DBI:mysql:maildb:localhost
bayes_sql_username              spamd
bayes_sql_password              motdepasse

Un petit redémarrage de spamassassin pour prendre en compte la nouvelle configuration :

# /etc/init.d/spamassassin restart

Et restaurons la sauvegarde de la base bayes :

$ sa-learn -u root --restore /tmp/sa_backup.txt

Pendant ce temps, on peut réinsérer en base les paramètres globaux qui étaient présents dans le fichier local.cf (les directives qu'on a commentées juste au dessus).

$ mysql -u spamd -p maildb
Enter password:
mysql> insert into userpref values ('@GLOBAL','required_hits','5.0','');
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> insert into userpref values ('@GLOBAL','rewrite_header Subject','*****SPAM*****','');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into userpref values ('@GLOBAL','report_safe','1','');
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> insert into userpref values ('@GLOBAL','report_contact','postmaster@hacky.info','');
Query OK, 1 row affected, 1 warning (0.00 sec)

Voila, c'est tout coté spamassassin !

Côté postfix, il faut créer un pipe aboutissant sur un script de filtrage. Ce script, nommé /usr/bin/antispam comporte ces lignes :

/usr/bin/spamc -u "$4" | /usr/lib/sendmail -i "$@"
exit $?

Pour l'appeler au moment de l'arrivée d'un mail, il faut modifier la configuration postfix dans le fichier /etc/postfix/master.cf :

Ajouter l'appel du pipe en modifiant la ligne smtp existante :

smtp      inet  n       -       n       -       -       smtpd
        -o content_filter=antispam

Et créer ou modifier le pipe antispam :

antispam  unix  -       n       n       -       -       pipe
   flags=Rq user=spamd argv=/usr/bin/antispam -f ${sender} -- ${recipient}

Il ne vous reste plus qu'à utiliser un plugin squirrelmail ou un autre panel afin d'autoriser vos utilisateurs à modifier leurs préférences : http://sourceforge.net/projects/php...

Il existe de nombreux panels d'administration pour cette base, le wiki de SpamAssassin en recense quelques uns : http://wiki.apache.org/spamassassin...