HOWTO Spamassassin SQL via procmail et qmail
Un article de Gentoo Linux Wiki.
Sommaire |
[modifier] Introduction
Le problème réside dans la capacité du système à différencier les « bons » mails des « mauvais ». Aucun système n’est parfait, surtout dans ce domaine où en permanence les spammeurs ajustent leurs techniques d’attaque à nos techniques de défense.
[modifier] Principe
Pour ne pas prendre le risque de vous faire perdre de « bons mails », le système suivant peut être mis en place :
- Un mail arrive sur notre serveur à destination d'une adresse email. Qmail transmet la gestion du mail au filtre procmail
- Le mail est dirigé vers le contrôle anti-spam (spamassassin)
- le contrôle anti-spam analyse le mail et lui attribue une note en fonction de multiples critères. Plus cette note est élevée, plus il y a de chances que ce soit du spam.
- Si la note dépasse un premier seuil (que nous pouvons régler), le mail est tagué par spamassassin avec une inscription du style [**SPAM**]
- A son retour d’analyse, notre système regarde le score atteint et décide de l’avenir du mail, indépendamment du fait qu'il ait été tagué ou pas.
- Note de 0 à un second seuil --> Le mail est dirigé vers votre boite de réception.
- Note comprise entre le second seuil et le troisième seuil --> Le mail est dirigé dans votre dossier Spam sur le serveur (Il y a de forte chance que ce soit du spam, mais un « bon mail » pourrait s’y trouver...)
- Note supérieur au troisième seuil --> Le mail est détruit.
[modifier] Exemple
- Note de 0 à 3 : mail transmis tel quel dans la boite de réception
- Note > 3 : Le mail est tagué [**SPAM** _HITS_] avec la note obtenue, mais est tout de même transmis dans la boite de réception.
- Note > 5 : Le mail est dirigé vers votre dossier Spam sur le serveur. Le client de messagerie POP ne le chargera pas, Mais il est possible de consulter et vider ce dossier par IMAP ou Webmail)
- Note > 15 : Le mail est détruit.
Tous ces seuils sont réglables.
[modifier] Emerger les programmes
Je suppose que vous partez d'une installation style OVH release 2 (Base Gentoo) où qmail fonctionne via vpopmail.
Si procmail et spamassassin ne sont pas installés il faut le faire avec un portage à jour.
#emerge --sync #emerge procmail #emerge spamassassin
[modifier] Configuration
[modifier] Vue d'ensemble
La complexité de la configuration réside dans la nécessité d'intervenir sur la configuration de 3 services différents (qmail, procmail et spamassassin) et sur trois niveaux différents (Configuration globale, au niveau de chaque domaine, voire au niveau de chaque adresse mail).
il y aura donc des fichiers de configuration à modifier/rédiger au niveau global, mais aussi au niveau des domains dans vpopmail.
[modifier] Configuration globale
[modifier] spamassassin
Le deamon spamassassin s'appelle spamd. Un #man spamd permet de voir tous les flags associés. nous allons d'emblée configurer spamassassin pour un fonctionnement couplé à MySQL.
Pour plus de détails, je vous engage à consulter le site de Spamassassin et notamment les pages concernant l'utilisation sous MySQL.
#vim /etc/conf.d/spamd Modifier les flags comme ceci : SPAMD_OPTS="-m 5 -H -q -D --siteconfigpath=/etc/spamassassin/" # rc-update add spamd default
Vous pouvez supprimer le -D si vous ne souhaitez pas le debuggage.
Le -q indique à Spamassassin que l'on va utiliser une base de donnée.
rc-update permet de lancer automatiquement le deamon au démarrage.
Il faut maintenant créer un base de donnée qui contiendra nos paramètres ainsi que utilisateur disposant des droits nécessaires sur cette base. Pour ma part, j'utilise PHPMyAdmin mais vous pouvez très bien le faire en ligne de commande. J'ai nommé la base de donnée spamd et créé un utilisateur du même nom (spamd). Dans cette base, j'ai créé une table avec la structure suivante :
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -- -- Base de données: `spamd` -- -- -------------------------------------------------------- -- -- Structure de la table `userpref` -- CREATE TABLE IF NOT EXISTS `userpref` ( `id` int(11) unsigned NOT NULL auto_increment, `username` varchar(255) NOT NULL default '', `preference` varchar(64) NOT NULL default '', `value` varchar(255) default NULL, `domain` varchar(255) default NULL, `obs` varchar(255) default NULL, `modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, UNIQUE KEY `id` (`id`), KEY `added_by` (`obs`), KEY `preference` (`preference`), KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Spamassassin Preferences';
Adaptez éventuellement le code MySQL suivant votre configuration (MyISAM au lieu d'InnoDB, CHARSET=latin1, ...)
Seuls les champs username, preference et value sont absolument nécessaires. Les autres sont à adapter à votre convenance.
Il est maintenant nécessaire de configurer Spamassassin.
Pour cela, nous allons éditer le fichier de configuration et inscrire le fait que les paramètres sont à rechercher dans une base MySQL
#vim /etc/mail/spamassassin/local.cnf
user_scores_dsn DBI:mysql:spamd:localhost
user_scores_sql_username spamd
user_scores_sql_password votremotdepasse
user_scores_sql_custom_query SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR username = '$GLOBAL' OR username = CONCAT('%',SUBSTRING_INDEX(_USERNAME_,'@',-1)) ORDER BY username ASC
Mettre en commentaire toutes les autres lignes en plaçant un # devant
Concernant la requête SQL dans user_scores_sql_custom_query, j'utilise la fonction SQL SUBSTRING_INDEX(_USERNAME_,'@',-1) pour extraire le nom de domaine de la variable _USERNAME_.
Au moment du transfert du mail à Spamassassin il sera nécessaire de transmettre l'adresse mail de destination (-u $EXT@$HOST dans procmail, voir plus loin) qui se retrouvera dans _USERNAME_.
Les variables de configuration seront alors chargées au niveau général ($GLOBAL), du domaine (%domaine.tld) ou d'un compte mail particulier (user@domaine.tld).
Le ORDER BY username ASC fait en sorte que si un paramètre spamassassin est défini à plusieurs niveaux, la priorité sera donnée au compte mail, puis au domaine et en dernier lieu au global.
Il faut maintenant saisir quelques paramètres dans la table de paramètres
INSERT INTO `userpref` (`username`, `preference`, `value`, `domain`, `obs`) VALUES
('$GLOBAL', 'required_hits', '6.00', NULL, NULL),
('$GLOBAL', 'subject_tag', '[SPAM-_HITS_]-', NULL, NULL),
('$GLOBAL', 'report_safe', '0', NULL, NULL),
('$GLOBAL', 'use_bayes', '0', NULL, NULL),
('$GLOBAL', 'bayes_auto_learn', '0', NULL, NULL),
('$GLOBAL', 'timelog_path', '/var/log/spamassassin', NULL, NULL),
('$GLOBAL', 'rewrite_header Subject', '[SPAM _HITS_] -', NULL, NULL),
('%domain1.tld', 'rewrite_header Subject', '[**SPAM** _HITS_]', 'domain1.tld', NULL),
('user1@domain1.tld', 'required_hits', '3', 'domain1.tld', NULL),
('%domain2.tld', 'required_hits', '5.5', 'domain2.tld', NULL),
('user1@domain2.tld', 'required_hits', '3', 'domain2.tld', NULL);
Bien évidemment, vous devez adapter à vos domaines et adresses mail. C'est justement à cet endroit que l'on personnalise le comportement de Spamassassin.
Maintenant, nous allons tester le bon fonctionnement de Spammassassin sous SQL
# /etc/init.d/spamd
# echo -e "From: user\nTo:user\nSubject: Test\n\n" | spamc -u 'user1@domain2.tld'
X-Spam-Flag: YES
X-Spam-Checker-Version: SpamAssassin 3.2.1-gr1 (2007-05-02) on
xxxxx.votredomain.tld
X-Spam-Level: *****
X-Spam-Status: Yes, score=5.1 required=3.0 tests=FH_FROMEML_NOTLD,MISSING_DATE,
MISSING_MID,NO_RECEIVED,NO_RELAYS,TO_MALFORMED,TVD_SPACE_RATIO
autolearn=disabled version=3.2.1-gr1
X-Spam-Report:
* 0.0 MISSING_MID Missing Message-Id: header
* 0.0 TO_MALFORMED To: has a malformed address
* 2.2 FH_FROMEML_NOTLD E-mail address doesn't have TLD (.com, etc.)
* 0.0 MISSING_DATE Missing Date: header
* -0.0 NO_RELAYS Informational: message was not relayed via SMTP
* 2.9 TVD_SPACE_RATIO BODY: TVD_SPACE_RATIO
* -0.0 NO_RECEIVED Informational: message has no Received headers
From: user
To:user
Subject: [SPAM 5.1] - Test
X-Spam-Prev-Subject: Test
On s'aperçoit au travers de required=3.0 que c'est bien le paramètre spécifique de user1@domain2.tld qui a été pris en compte. De ce fait, notre message a droit au statut de spam (X-Spam-Status: Yes).
Le même message sans spécifier d'utilisateur donne
# echo -e "From: user\nTo:user\nSubject: Test\n\n" | spamc
X-Spam-Checker-Version: SpamAssassin 3.2.1-gr1 (2007-05-02) on
xxxxx.votredomain.tld
X-Spam-Level: *****
X-Spam-Status: No, score=5.1 required=6.0 tests=FH_FROMEML_NOTLD,MISSING_DATE,
MISSING_MID,NO_RECEIVED,NO_RELAYS,TO_MALFORMED,TVD_SPACE_RATIO
autolearn=disabled version=3.2.1-gr1
From: user
To:user
Subject: Test
On s'aperçoit au travers de required=6.0 que c'est le paramètre global qui a été pris en compte. notre message n'a pas le statut de spam (X-Spam-Status: no).
Reste maintenant à organiser les aiguillages entre qmail et spamassassin via procmail
[modifier] qmail
Je suppose que qmail est utilisé avec vpopmail. Pour d'autres configurations, des adaptations doivent être possibles.
# locate .qmail-default en fonction de la localisation des fichiers trouvés (Dans /var, dans /home , etc ) # cd /home/vpopmail/domains/domain1.tld # vim .qmail-default Commenter la ligne existante # | /home/vpopmail/bin/vdelivermail '' bounce-no-mailbox et la remplacer par | preline /usr/bin/procmail -p -m /home/vpopmail/domains/domain1.tld/procmailrc
Il faut répéter l'opération pour chaque domaine que vous souhaitez faire contrôler par notre système.
Reste maintenant à configurer procmail pour qu'il aiguille correctement les mails.
[modifier] procmail
Procmail réagit en fonction de règles. Il existe un fichier de configuration globale (/etc/procmailrc), mais il ne nous est pas nécessaire. Dans notre cas, nous devons rédiger un fichier au niveau du domaine, ce qui nous permettra des réglages différents pour chaque domaine.
Si vous n'etes pas dans le bon répertoire : # cd /home/vpopmail/domains/domain1.tld #vim procmailrc copiez ceci : SHELL=/bin/bash VHOME=`/home/vpopmail/bin/vuserinfo -d $EXT@$HOST` VERBOSE=no LOGFILE=/var/log/procmail_log DROPPRIVS=yes # Make sure that we have a .Spam and .Virus folder to sort spam and virus into. # This will create directorys under the ~vpopmail/domains///Maildir # direcory. This directory will be created as soon as the user # recives any mail. It simply creates the .Spam and .Virus directories, # as well as subscribes them to courier-imap :0wic * ? test ! -d $VHOME/Maildir/.Spam |( /var/qmail/bin/maildirmake $VHOME/Maildir/.Spam ; /bin/echo .INBOX/Spam. >> $VHOME/Maildir/.bincimap-subscribed ) :0wic * ? test ! -d $VHOME/Maildir/.Virus |( /var/qmail/bin/maildirmake $VHOME/Maildir/.Virus ; /bin/echo .INBOX/Virus. >> $VHOME/Maildir/.bincimap-subscribed ) # Run Anti-Virus and Anit-spam tests. # :0fw # | /var/qmail/bin/scanmail.sh # :0: # * ^X-Virus-Status: INFECTED # $VHOME/Maildir/.Virus/ #SPAMASSASSIN :0fw | /usr/bin/spamc -f -u $EXT@$HOST :0: * ^X-Spam-Level: \*\*\*\*\*\*\*\*\*\*\*\*\*\*\* /dev/null # Sort anything marked as SPAM into the users Maildir/.Spam/ :0: # * ^X-Spam-Status: YES * ^X-Spam-Level: \*\*\*\*\* $VHOME/Maildir/.Spam/ # Everything else goes to the users default Maildir/ #:0: #* #$VHOME/Maildir/ :0w | /home/vpopmail/bin/vdelivermail '' bounce-no-mailbox
La création automatique des répertoires de spam et virus vient de ce site
Vérifiez bien et n'hésitez pas à adapter vos chemins et nommage (Exemple : Maildir différent de maildir différent de .maildir).
J'ai laissé en commentaire les règles concernant la gestion des virus, au cas où quelqu'un serait intéressé de prolonger le sujet.
| /usr/bin/spamc -f -u $EXT@$HOST transmet le mail avec l'adresse du destinataire qui sera récupérée par _USERNAME_ dans Spamassassin
Au retour de spamassassin, les header du mail ont été modifiés. Un nouvelle règle s'applique :
- 0:
- ^X-Spam-Level: \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
/dev/null
Si le niveau de spam dépasse 15, le mail est directement détruit, un log est inscrit dans /home/vpopmail/domains/idigitale.fr/procmail-log et procmail s'arrête.
Sinon on passe à la règle suivante :
- 0:
- * ^X-Spam-Status: YES
- ^X-Spam-Level: \*\*\*\*\*
$VHOME/Maildir/.Spam/
Si le niveau de spam dépasse 5, le mail est orienté vers le dossier Spam sur le serveur. L'utilisateur ne le chargera pas lors d'un envoyer/recevoir sous pop3, mais pourra retourner dans sa boite mail via un service webmail ou IMAP pour contrôler s'il n'y a pas eu de faux classement. Voici un nouveau réglage à votre disposition.
Si la règle s'applique, le processus s'arrête. Sinon il passe à la dernière règle :
- 0w
| /home/vpopmail/bin/vdelivermail bounce-no-mailbox
On retrouve la ligne d'origine dans .qmail-default : le mail est transmis à l'utilisateur.
Remarque 1 : Il se peut que le mail soit transmis tagué s'il a obtenu une note supérieure au 'required_hits' de spamassassin et une note inférieur à la règle 2 de procmail.
Pour surveiller le travail de procmail, vous pouvez scruter les logs dans le répertoire /home/vpopmail/domains/domain1.tld (A condition d'avoir reçu au moins un mail depuis l'installation):
# tail -n 100 -f procmail-log
Remarque 2 : Faudrait gérer un peu mieux les logs pour limiter l'inflation. Avis aux amateurs.
Remarque 3 : Une tâche cron permettant de supprimer les spam ayant un certain âge dans les dossier .Spam de toutes les adresses emails serait à développer. Avis aux amateurs. Sinon cette configuration peut très bien servir uniquement pendant la phase de mise en route pour déterminer un "level" à partir duquel on va jeter les mails et transmettre tout le reste.
Bon travail
--Stéphane 8 avril 2008 à 08:06 (UTC)
---
