Afin de soulager la vie de quelques usagés, on va mettre en place un système automatique pour apprendre a SpamAssassin a mieux reconnaitre les SPAMs, et a mieux reconnaitre les NON-SPAMs (les HAMs).
Pour que ça marche bien, il faut que les utilisateurs collaborent en soumettant eux-même ce qui est du “spam” ou du “ham”.
Il y a plusieurs méthodes, plus ou moins bien documentées (ou comprises !).
~~READMORE~~
la configuration Postfix sur laquelle repose ce blog-post est un peu ancienne mais est décrite par là |
D'abord, nos utilisateurs ne sont pas tous en IMAP: si c'était le cas, un simple script appliqué sur les répertoires “.Junk
” ou “.Spam
” pourrait être suffisant.
Non, quelques utilisateurs récalcitrants sont toujours en POP3 !
Sur notre mini-infrastructure, SpamAssassin
n'est pas en place sur le serveur final (mail.local.eez.fr
), mais sur des frontaux (mx0.local.eez.fr
et mx1.local.eez.fr
) .
Ainsi, tous les traitements lourds et nuisibles sont relégués loin des clients finaux.
En fait, on va créer des comptes e-mails factices uniquement dédiés à la réception , en pièce jointes , des SPAMs ou des NON-SPAMs soumis par les utilisateurs.
Régulièrement, chaque frontal récupèrera les e-mails, via “fetchmail
” , et puis entrainera SpamAssassin
a ré-considérer les messages comme du SPAM ou du HAM.
Il ne faut qu'ils soient accessibles par des vilains |
( le serveur qui livre les mails dans les comptes locaux )
Dans le fichier /etc/aliases
, on ajoute:
spam: /dev/null ham: /dev/null nospam: ham
“/dev/null
” est provisoire !
Pour l'instant, tout ce que reçoit “spam
” ou “ham
” va dans le trou noir du “/dev/null
”.
Ne pas oublier la mise à jour de la table aliases
:
# newaliases
Dans le fichier /etc/postfix/virtual
, on ajoute les adresses e-mail.
On peut préférer une variante en utilisant /etc/postfix/virtual.regexp
contenant:
/^spam@/ spam /^(ham|nospam)@/ ham
… ainsi, peut importe le domaine, ils ont tous les mêmes destinataire locaux.
Composer/modifier un fichier /etc/postfix/recipient_access.regexp
afin de limiter les accès aux boites.
# ========================================= # Limites sur le destinataire # (il faut faire de même sur tous les frontaux) # ========================================= # Limiter l'envoi a (spam|nospam|ham) /^spam(\+?.*)?@/i permit_mynetworks,reject /^nospam(\+?.*)?@/i permit_mynetworks,reject /^ham(\+?.*)?@/i permit_mynetworks,reject # --- misc ----- /^chamard@tjaouen.fr/ 550 Asshole close # ========================================= # EOF
Dans /etc/postfix/main.cf
, compléter l'instruction smtpd_recipient_restrictions
en ajoutant:
regexp:/etc/postfix/recipient_access.regexp
Ce qui donne pour moi (a titre d'informations) :
smtpd_recipient_restrictions = check_recipient_access regexp:/etc/postfix/recipient_restrictions.regexp permit_mynetworks permit_sasl_authenticated reject_unauth_destination regexp:/etc/postfix/recipient_access.regexp
(les autres options ne seront pas expliqués ici)
Et enfin:
# postfix reload
Pour les frontaux, n'ajouter que les restrictions sur les adresses e-mails. C'est à dire:
/etc/postfix/recipient_access.regexp
(voir ci-dessus)/etc/postfix/main.cf
pour l'instruction smtpd_recipient_restrictions
(voir ci-dessus)A ce stade:
Retour sur le serveur “final” (celui qui détient les comptes mails).
Il s'agit uniquement de comptes locaux: personne n’envoie directement des mails dedans |
On va donc créer les comptes locaux dédiés à la collecte des SPAMs et des HAMs soumis par les utilisateurs.
Rappel: Dans notre cas, il s'agit de comptes “PAM”, et les commandes sont surement différentes pour d'autres configuration Postfix
.
Bref: 2 frontaux, et donc 4 comptes a créé: 2 SPAMs et 2 HAMs.
1er frontal nommé “mx0” :
# adduser mx0-spam # adduser mx0-ham
2ieme frontal nommé “mx1” :
# adduser mx1-spam # adduser mx1-ham
Maintenant, on peut ajuster correctement le fichier /etc/aliases
:
spam : mx0-spam,mx1-spam ham : mx0-ham,mx1-ham nospam: ham
Recharger Postfix
avec la nouvelle configuration:
# newaliases # postfix reload
A ce stade, ce qui est destiné à “spam@xxxx.xx” ou “ham@xxxx.xx” est dupliqué respectivement dans les comptes locaux, “mx0-spam” “mx1-spam” et “mx0-ham” “mx1-ham”.
( Dans notre configuration, les mails arrivent dans /home/<compte>/Maildir/new/
)
On en a terminé sur ce serveur.
: CRON pour vérifier que les mails sont bien relevés…
Il reste a faire les choses suivantes, sur chaque frontal :
SpamAssassin
a partir de ces mails
Ce qui va suivre s'applique a chaque frontal.
On va expliquer uniquement comment faire pour le 1er, c'est à dire celui qu'on nomme “mx0”.
Chaque frontal a déjà un compte local “debian-spamd
” dédié au traitement des SPAMs avec SpamAssassin
.
(Dans un précédent blog-post, ce compte était “spamc-nobody
”)
On va utiliser ce compte déjà existant pour faire le job.
Libre a vous d'en utiliser un autre (mais éviter “root” !).
Présentons d'abord le petit script pour extraire toutes les pièces jointes…
Le script Perl qui va extraire les pièces jointes est là:
Il est inspiré de ce script: http://jmason.org/software/scripts/extract-rfc822-attachment.txt
Son fonctionnement:
$ split-rfc822-attachment.pl < message-mail /tmp/attachment
Dans cette exemple, toutes les pièces jointes du fichier “message-mail” sont alors extraites en multiples fichiers dans /tmp/attachment
.
Le but étant de récupéré les sources de chaque mail extrait, et non pas d'extraire et de reconstruire des documents.
il n'est surement pas parfait , mais il m'a semblé suffisant |
On va le mettre , par exemple, dans /usr/local/bin
… donc:
# cp split-rfc822-attachment.pl /usr/local/bin/ # chmod a+x /usr/local/bin/split-rfc822-attachment.pl
Vérifier qu'il compile sans erreur:
# perl -c /usr/local/bin/split-rfc822-attachment.pl /usr/local/bin/split-rfc822-attachment.pl syntax OK
Ensuite, il faut choisir un endroit où on va déposer les pièces jointes “spam” et “ham”.
A la racine de l'utilisateur choisit (pour nous ce sera debian-spamd
), on aura:
~/sa-retrain/spam
~/sa-retrain/ham
Créer et attribuer les “bons” droits a ces répertoires:
# su -s /bin/bash debian-spamd $ mkdir ~/sa-retrain $ mkdir ~/sa-retrain/{spam,ham}
Ceci fait, voyons la suite pour que les mails arrivent dans ces répertoires.
La manière de récupérer des mails la plus évidente est simplement le protocole POP3
!
On va utiliser la commande fetchmail
pour récuperer les mails.
Mais il y a un petit hic:
Lorsque fetchmail
récupère un mail, il le livre au Postfix
local ! Ce qui a les conséquences suivantes:
Maildir
ou mbox
selon la configuration.SpamAssassin
va tagguer le mail !!!!
Il y a plusieurs manière de corriger cela, mais ça oblige a faire, encore et encore, des modifications dans Postfix
et SpamAssassin
.
Donc, on va faire plus simple: On va dire a fetchmail
de livrer a notre propre service de livraison, notre “MDA” à nous .
Rassurez-vous: Notre “MDA” sera un simple scripte (voir section suivant).
En dehors d'être un faux (“fake”) “MDA” , il va:
split-rfc822-attachment.pl
”Le script Bash de notre “MDA” est là:
On va le mettre , par exemple, dans /usr/local/bin
… donc:
# cp sa-retrain-fake-mda /usr/local/bin/ # chmod a+x /usr/local/bin/sa-retrain-fake-mda
# aptitude update # aptitude install fetchmail
Note:
[warn] Not starting fetchmail daemon, disabled via /etc/default/fetchmail ... (warning).
On peut ignorer: Nous n'avons pas besoin d'activer le “daemon” pour que ça marche.
Retour en tant qu'utilisateur “debian-spamd
” (ou autres).
# su -s /bin/bash debian-spamd $
A la racine de la “HOME” :
$ cd ~
… on compose un fichier nommé .fetchmailrc
contenant:
# ---------------------- set postmaster root set no bouncemail #set syslog poll <HOST> protocol POP3 user mx0-spam there with password '<PASSWORD>' is debian-spamd here options ssl and wants mda "/usr/local/bin/sa-retrain-fake-mda spam %F %T" poll <HOST> protocol POP3 user mx0-ham there with password '<PASSWORD>' is debian-spamd here options ssl and wants mda "/usr/local/bin/sa-retrain-fake-mda ham %F %T" # ---------------------- # EOF
mx0-spam et mx0-ham | A adapter selon le compte e-mail associé au frontal |
<HOST> | Adresse du service “pop”. (Exemple: pop.local.eez.fr ) |
<PASSWORD> | Passe affecté au moment de la création du compte e-mail |
debian-spamd | … ou autre nom de compte (par exemple: spamc-nobody ) |
options ssl | Si on veut chiffrer les echanges. Voir configuration spécifique à SSL ici . |
Le fichier .fetchmailrec
contenant des mots de passe, il faut faire:
$ chmod 0700 .fetchmailrc
L'instruction mda “sa-retrain-fake-mda spam %F %T”
dit:
/usr/local/bin/sa-retrain-fake-mda
” (décrit plus haut) pour livrer les mails.
Comme dit plus haut, on force fetchmail
a utiliser “notre” propre “MDA”.
Maintenant, on doit avoir une chaine de transfert complète. (Reste juste une étape, voir juste après).
Pour tester:
Il suffit d'envoyer un e-mail avec un ou plusieurs e-mail en pièces jointes à l'adresse spam@…
ou ham@….
.
Par exemple, on envoi un mail avec 2 spams en pièces jointes.
Sur le serveur, on voit le mail:
Dans les logs:
Jul 18 06:05:21 mail clamsmtpd: 100174: from=<hidden>@<hidden>, to=spam@tjaouen.fr, status=CLEAN Jul 18 06:05:21 mail postfix/smtpd[25367]: disconnect from localhost[127.0.0.1] Jul 18 06:05:21 mail postfix/local[25373]: AC76454C4A: to=<mx0-spam@mail.local.eez.fr>, orig_to=<spam@tjaouen.fr>, relay=local, delay=0.26, delays=0.25/0.01/0/0.01, dsn=2.0.0, status=sent (delivered to maildir) Jul 18 06:05:21 mail postfix/local[25373]: AC76454C4A: to=<mx1-spam@mail.local.eez.fr>, orig_to=<spam@tjaouen.fr>, relay=local, delay=0.27, delays=0.25/0.01/0/0.01, dsn=2.0.0, status=sent (delivered to maildir) Jul 18 06:05:21 mail postfix/qmgr[23951]: AC76454C4A: removed
… mail qu'on retrouve dans chaque compte “spam” local:
# ls /home/mx{0,1}-spam/Maildir/new/ /home/mx0-spam/Maildir/new/: 1375020321.Vca02I408fM962049.mail /home/mx1-spam/Maildir/new/: 1375020321.Vca02I4090M967836.mail
Maintenant, on va sur l'un des frontals , et on récupère le mail en attente.
Sur le frontal:
Devenir l'utilisateur qui traite les SPAMs et les HAMs:
# su -s /bin/bash debian-spamd
Récupérer les mails en attente:
$ fetchmail 1 message pour mx0-spam dans pop.local.eez.fr (51924 octets). lecture du message mx0-spam@mail.local.eez.fr:1 parmi 1 (51924 octets) éliminé fetchmail: Aucun message pour mx0-ham dans pop.local.eez.fr
En vrai: fetchmail
râle parce que mon certificat “ssl” est auto-signé !
Voir solution ici.
On a bien récupéré le mail, mais il est où ?
Dans les logs on voit:
Jul 18 06:11:52 mx1 sa-retrain-fake-mda: spam From: <hidden>@<hidden> - OK
… le script “sa-retrain-fake-mda” a fait son boulot.
Les 2 pièces jointes sont bien extraites , et là:
$ ls ~/sa-retrain/spam/ -lart -rw------- 1 debian-spamd debian-spamd 26193 juil. 18 06:11 split-rfc822-0140259F035200DB7.2 -rw------- 1 debian-spamd debian-spamd 21896 juil. 18 06:11 split-rfc822-0140259F035200DB7.1
Reste a les faire apprendre à “sa-learn
”.
Enfin, il faut réaliser un script qui va traiter les “spam” ou les “ham” qui ont été précédement extraits des pièces jointe.
Le script Bash qui va apprendre a partir des mails est là:
Ce qu'il fait:
~/sa-retrain/{spam|ham}
SpamAssassin
que le mail est du “spam” ou du “ham”# cp sa-retrain-spamham /usr/local/bin # chmod a+x /usr/local/bin
# su -s /bin/bash debian-spamd
Et puis:
$ sa-retrain-spamham sa-retrain-spamham: spam - /var/lib/spamassassin/sa-retrain/spam/split-rfc822-0140259F035200DB7.1 Learned tokens from 1 message(s) (1 message(s) examined) sa-retrain-spamham: spam - /var/lib/spamassassin/sa-retrain/spam/split-rfc822-0140259F035200DB7.2 Learned tokens from 1 message(s) (1 message(s) examined)
Dans les logs, on peut voir aussi:
Jul 18 06:31:58 mx1 sa-retrain-spamham: sa-learn - spam:2 ham:0
Maintenant que c'est fonctionnel, il suffit de démarrer tout ça dans un CRON.
# crontab -u debian-spamd -e
Et ajouter:
MAILTO=root */10 * * * * fetchmail >/dev/null ; sleep 1 ; /usr/local/bin/sa-retrain-spamham >/dev/null
Et ainsi, toutes les 10 minutes:
sa-retrain-spamham peut être long. Un “lock” est présent pour écarter des accès concurrents |