milter-regex : expressions régulières anti-spam pour Sendmail
On peut ajouter à Sendmail un anti-spam très simple, basé sur des expression régulières étendues : milter-regex ; dans http://www.pkgsrc.org, il s'agit du paquet mail/milter-regex.
Le principe est simple :
- un daemon
milter-regex
attend les connexions (sur une socket UNIX ou INET / INET6), - le MTA qui s'y connecte « parle » Milter (le protocole mis au point pour Sendmail 8.12 pour normaliser les connexions aux filtres) ⇒ il s'agit de Sendmail 8.12 ou plus (ou d'une version récente de Postfix),
- lorsque le MTA lui passe un message, le daemon le filtre suivant un fichier de configuration,
- il répond au MTA si le message est acceptable ou non.
Lors de chaque connexion du MTA, le daemon vérifie que le fichier de configuration n'a pas été modifié ; dans le cas contraire, il le relit avant de traiter le message. On n'a donc pas besoin de relancer le daemon milter-regex
à chaque modification.
Avant de l'installer, vérifier au préalable que Sendmail est bien compilé avec le support de Milter :
$ sendmail -bt -d0.4 </dev/null|grep MILTER Compiled with: FOO MILTER BAR
sans quoi il faut commencer par installer une version plus complète du MTA.
Activation
Ajouter la ligne suivante dans /etc/mail/sendmail.cf
:
Xmilter-regex, S=unix:/var/spool/milter/milter-regex.sock, T=S:30m;R:20m
et indiquer à Sendmail d'utiliser ce filtre :
O InputMailFilters=milter-regex
Pour utiliser plusieurs filtres, la variable InputMailFilters
attend les différents noms séparés par des virgules :
O InputMailFilters=milter-regex,mimedefang
Lancer le filtre puis relancer sendmail(8)
. Attention au fichier socket (emplacement et surtout droits).
Évidemment, tout cela n'est possible que si Sendmail dispose de la bibliothèque Milter… Ne pas oublier de configurer le système pour que milter-regex(8)
se lance avant le MTA. De plus, vérifier que le script de lancement supprime le fichier de socket et de PID en cas de reprise après un crash.
Utilisation
Les règles se présentent sous la forme de blocs de plusieurs lignes.
Une première ligne indiquant la réponse et commençant par l'un des mot-clefs : reject
, tempfail
, quarantine
, discard
, ou accept
; les trois premiers sont suivis d'un message de renseignement ; reject
renvoie une erreur SMTP 554
, tempfail
une erreur 471
.
Les lignes suivantes indiquent quoi chercher :
connect
ouhelo
: pour filtrer sur l'origine de la connexionenvfrom
ouenvrcpt
: pour filtrer l'enveloppeheader
oubody
: pour filtrer sur les entêtes ou le corps du messagemacro
: pour filtrer à l'aide d'une valeur d'une macro Sendmail
Quelques exemples:
reject "Banned email (bad x-mailer), see http://www.example.com/mail-filter.html" header ,X-Mailer: DOPOST 1.1 (Build Nov 4 2005), (c) www.dolist.net, ,, reject "Banned email (bad subject), see http://www.example.com/mail-filter.html" header ,Subject, ,junk email out of control,i header ,Subject, ,{subj190107}, header ,Subject, ,WINNING NOTIFICATION,i header ,Subject, ,RE: MedHelp [0-9]*,i header ,Subject, ,777, header ,Subject, ,The\ Pharmacy\ America\ Trusts,i header ,Subject, ,What\ Is\ 0EM\ Software\ And\ Why\ Do\ You\ Care\?,i header ,Subject, ,s(e|3)(x|><),ei header ,Subject, ,v(i|!|\||1)(a|4)(r|g)(g|r)(a|4),ei header ,Subject, ,s(o|0)ftware,ei reject "Banned email (no spaces, spoofing), see http://www.example.com/mail-filter.html" header ,From, ,\".*\ .*\"@example\.com,ei
Ici, les messages d'erreur indiquent tous une page web donnant des raisons potentielles de refus et un contact (en cas de faux positif).
Mieux vaut éviter les filtres sur body
, elles surchargent très vite le serveur. De plus, au delà de quelques centaines, les expressions régulières étendues (drapeau e
en fin de règle) ralentissent aussi sensiblement le serveur. Ces deux remarques sont évidemment fortement dépendantes du trafic SMTP.
Suivant la valeur de Milter.LogLevel
(renseigné dans /etc/mail/sendmail.cf
), attention à ce qui est journalisé : le niveau 17
journalise en-têtes et corps du message envoyés au(x) filtre(s) Milter. Outre un problème de déontologie évident, un souci de logique non moins évident (pourquoi stocker le message si on le journalise ? ou inversement…), les journaux deviennent très très verbeux très très vite.
On peut filtrer les messages syslog(3)
, par exemple avec Syslog-NG comme indiqué ici.