5b3dec0fa7
une règle).
465 lines
15 KiB
XML
465 lines
15 KiB
XML
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||
<!DOCTYPE html
|
||
PUBLIC "-//ENS/Tuteurs//DTD TML 1//EN"
|
||
"tuteurs://DTD/tml.dtd">
|
||
<html>
|
||
<head>
|
||
<title>Procmail</title>
|
||
</head>
|
||
<body>
|
||
|
||
<h1>Filtrer son courrier électronique avec procmail</h1>
|
||
|
||
<h2>À quoi sert procmail ?</h2>
|
||
|
||
<p> Procmail est un programme qui sert à filtrer les courriers
|
||
électroniques. Grâce à lui, vous pouvez rediriger votre mail, le trier
|
||
ou vous protéger contre le spam. Vous pouvez configurer votre mail
|
||
avec un <code>.procmailrc</code>.</p>
|
||
|
||
<h2>Ce que doit contenir un <code>.procmailrc</code></h2>
|
||
|
||
<p>Un <code>.procmailrc</code> commence par les lignes
|
||
suivantes :</p>
|
||
|
||
<pre>
|
||
PATH=/bin:/usr/bin
|
||
MAILDIR=$HOME/Mail
|
||
LOGFILE=$MAILDIR/procmail.log
|
||
</pre>
|
||
|
||
<dl>
|
||
<dt><code>PATH=/bin:/usr/bin</code></dt>
|
||
<dd>On indique à procmail le chemin des programmes qu'il va
|
||
utiliser.</dd>
|
||
<dt><code>MAILDIR=$HOME/Mail</code></dt>
|
||
<dd>On indique à procmail où se trouve votre répertoire de mail.</dd>
|
||
<dt><code>LOGFILE=$MAILDIR/procmail.log</code></dt>
|
||
<dd>On indique à procmail le nom d'un fichier où il mettra tous ses
|
||
rapports d'activité et ses messages d'erreur (les <em>logs</em>). Les
|
||
logs sont précieux pour faire des tests.</dd>
|
||
</dl>
|
||
|
||
<h2>Comment ça marche ?</h2>
|
||
|
||
<h3>Les recettes</h3>
|
||
|
||
<p> Les « recettes » (<em lang="en">recipes</em>) sont les éléments de
|
||
base du <code>.procmailrc</code>. Leur principe est le suivant :
|
||
on commence par spécifier des conditions (une condition dit à procmail
|
||
ce qu'il doit regarder dans le courrier, par exemple l'adresse de
|
||
l'expéditeur, ou encore le champ « Sujet ») puis on indique l'action à
|
||
accomplir si les conditions sont remplies (par exemple, rediriger le
|
||
courrier, ou l'envoyer à la poubelle).</p>
|
||
|
||
<p>
|
||
Une recette a toujours le format suivant (le # introduit un
|
||
commentaire pour expliquer le code, vous n'avez pas à recopier la
|
||
partie après le #) :</p>
|
||
|
||
<pre>
|
||
:0 [<a href="#flag">drapeau(x)</a>] [: [<a href="#lock">fichier verrou</a>] ]
|
||
# Les conditions commencent chacune par *
|
||
* condition(s)
|
||
action à accomplir
|
||
</pre>
|
||
|
||
<h3>Expressions régulières</h3>
|
||
|
||
<p> Pour spécifier les conditions, on se sert d'expressions
|
||
régulières. Une expression régulière est une notation permettant de
|
||
définir des schémas de recherche. Pour cela, on se sert de
|
||
métacaractères, aussi appelés jokers.</p>
|
||
|
||
<table cellspacing="5" cellpadding="5" border="5">
|
||
<tr>
|
||
<th>Joker</th>
|
||
<th>Signification</th>
|
||
</tr><tr>
|
||
<td>^</td>
|
||
<td>Début de ligne</td>
|
||
</tr><tr>
|
||
<td>$</td>
|
||
<td>Fin de ligne</td>
|
||
</tr><tr>
|
||
<td>.</td>
|
||
<td>Un caractère quelconque</td>
|
||
</tr><tr>
|
||
<td>[xy]</td>
|
||
<td>N'importe quel caractère dans l'ensemble spécifié</td>
|
||
</tr><tr>
|
||
<td>[^xy]</td>
|
||
<td>N'importe quel caractère hors de l'ensemble spécifié</td>
|
||
</tr><tr>
|
||
<td>foo|bar</td>
|
||
<td>foo ou bar</td>
|
||
</tr><tr>
|
||
<td>c*</td>
|
||
<td>Un nombre quelconque (même 0) de répétitions du caractère c</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<p>
|
||
Quelques exemples :</p>
|
||
|
||
<ul>
|
||
<li><code>^From:</code> : cette condition vise toutes les chaînes
|
||
de caractère <code>From:</code> au début d'une ligne. On dirait une
|
||
en-tête de courrier électronique, non ? :-)</li>
|
||
<li><code>^From:.*choupi.*</code> : cette condition vise toutes
|
||
les chaînes de caractère <code>From:</code> au début d'une ligne,
|
||
suivies d'un ou plusieurs caractères, puis de choupi, puis d'un ou
|
||
plusieurs autres caractères. Cette fois, on a défini l'ensemble des
|
||
mails provenant d'une adresse contenant l'expression choupi : de
|
||
cette façon, on vise tous les mails provenant de Choupi, votre
|
||
meilleur ami.</li>
|
||
<li><code>^(From|Cc|To).*choupi.*</code> cette fois, on vise
|
||
tous les mails qui viennent de Choupi, ceux où Choupi est en Cc:, et
|
||
ceux adressés à Choupi.</li>
|
||
</ul>
|
||
|
||
<h3>Rediriger certains mails vers une autre adresse électronique</h3>
|
||
|
||
<h4>Redirection de base</h4>
|
||
|
||
<p>
|
||
Pour rediriger votre courrier électronique vers une autre adresse,
|
||
c'est simple :</p>
|
||
|
||
<pre>:0
|
||
# il n'y a pas de condition : tous les courriers sont concernés
|
||
# le "!" demande le forward vers l'adresse spécifiée
|
||
! toto@northpole.foo
|
||
</pre>
|
||
|
||
<h4>Redirection avec conditions</h4>
|
||
|
||
<p> Toujours plus fort, maintenant . Imaginons que vous soyiez un
|
||
fan de Scoubidou. Votre page web porte sur Scoubidou. Choupi (votre
|
||
meilleur ami, souvenez-vous), vous a aidé à le réaliser. Vous
|
||
souhaitez relayer les courriers qui vous arrivent et qui parlent de
|
||
Scoubidou à Choupi. Avec procmail, vous pouvez le faire.</p>
|
||
|
||
<pre>:0
|
||
# Concernés : tous les mails dont le sujet contient « Scoubidou »
|
||
* ^Subject:.*Scoubidou.*
|
||
# On forwarde à Choupi
|
||
! choupi@scoubidou-fan.com
|
||
</pre>
|
||
|
||
<p> Comme vous pourrez le constater, les conditions peuvent porter sur
|
||
tous les champs d'un courrier électronique : From, To, CC, Bcc,
|
||
etc.</p>
|
||
|
||
<p> Ajoutons que dans cet exemple, vous souhaiteriez sans doute vous
|
||
aussi lire les courriers « Scoubidou. » Avec la recette ci-dessus, ces
|
||
courriers sont simplement reexpédiés vers Choupi, et vous ne les avez
|
||
jamais dans votre boîte aux lettres. Nous allors utiliser un <a
|
||
name="flag">drapeau</a> (<em lang="en">flag</em>) qui est une sorte
|
||
d'option, qui modifie le comportement standard de procmail. Il suffit
|
||
d'ajouter c après le :0, ce qui demande à procmail de copier dans le
|
||
répertoire de mail les courriers qui arrivent. L'exemple complet est
|
||
donc le suivant :</p>
|
||
|
||
<pre>
|
||
:0 c
|
||
# Concernés : tous les mails dont le sujet contient « Scoubidou »
|
||
* ^Subject:.*Scoubidou.*
|
||
# On forwarde à Choupi
|
||
! choupi@scoubidou-fan.com
|
||
</pre>
|
||
|
||
<h3>Filtrer le spam</h3>
|
||
|
||
<h4>Filtrer suivant le sujet</h4>
|
||
|
||
<p> La plupart des spams sont des mails provenant d'expéditeurs bidons
|
||
et différents à chaque fois, et qui ont pour point commun de vous
|
||
promettre de l'argent, de vous proposer du Viagra, des diplômes par
|
||
cher, et autres joyeusetés. Procmail vous permet d'identifier plus ou
|
||
moins ces mails en fonction de leur sujet, et de les envoyer
|
||
directement à la poubelle. De même, le filtrage par sujet permet de
|
||
filtrer les mails pyramidaux (chaînes de l'amitié, fausses alertes de
|
||
virus, etc.), que vous pouvez être amené à recevoir plusieurs fois.
|
||
</p>
|
||
|
||
<p>
|
||
Dans l'exemple suivant, vous allez filtrer tous les mails dont le
|
||
sujet contient le mot « Viagra » en les envoyant vers
|
||
<code>/dev/null</code>, la poubelle (attention, contrairement à
|
||
Windows ou MacOS, vous ne pouvez pas récupérer des données de
|
||
<code>/dev/null</code>, c'est un aller simple pour le grand vide).
|
||
</p>
|
||
|
||
<pre>
|
||
:0
|
||
* ^Subject: .*Viagra.*
|
||
/dev/null
|
||
</pre>
|
||
|
||
<div class="attention">La présence d'un <code>/dev/null</code> dans
|
||
votre <code>.procmailrc</code> est dangeurese : la moindre erreur
|
||
de syntaxe, la moindre coquille est susceptible d'envoyer tout votre
|
||
mail dans <code>/dev/null</code>, soit le vide intersidéral d'où vous
|
||
ne pouvez récupérer aucun courrier. En cas d'accident, vous pouvez
|
||
vous adresser au SPI, mais faites particulièrement attention en
|
||
éditant votre <code>.procmailrc</code>.</div>
|
||
|
||
<p>
|
||
Vous pouvez également utiliser la syntaxe suivante :
|
||
</p>
|
||
|
||
<pre>
|
||
:0
|
||
* ^Subject: .*Viagra.*
|
||
{
|
||
EXITCODE=67 HOST
|
||
}
|
||
</pre>
|
||
|
||
<p> Pourquoi cet EXITCODE et pas /dev/null (la poubelle) ? Ce
|
||
code renvoie une « address unknown » à l'expéditeur du courrier
|
||
électronique (pour avoir la liste de tous ces codes, lire
|
||
<code>/usr/include/sysexits.h</code>). </p>
|
||
|
||
<p>Attention, utiliser un <code>exitcode</code> n'est pas toujours une
|
||
bonne idée. Certes, il vous procure la satisfaction de renvoyer au
|
||
spammeur ses spams. Mais cela ne sert pas à grand chose : bien
|
||
souvent, le spammeur filtre les messages d'erreur qui lui sont
|
||
renvoyés. Que vous fassiez le mort (en reroutant les spams vers
|
||
<code>/dev/null</code>) ou que vous lui renvoyez 150 messages d'erreur
|
||
ne l'empêchera pas de continuer à vous spammer s'il y tient. D'autre
|
||
part, mettre des exitcodes dans son <code>.procmailrc</code> peut être
|
||
gênant pour vous si vous faites partie d'une mailing-list : le
|
||
message d'erreur risque d'être répercuté à toute la liste.</p>
|
||
|
||
<p>
|
||
Vous est-il déjà arrivé de recevoir, après avoir envoyé un mail à un
|
||
camarade de l'Ecole, un courrier avec le sujet <code>"Returned mail:
|
||
Can't create output"</code>, et contenant le message cryptique
|
||
suivant ?</p>
|
||
|
||
<pre>
|
||
----- The following address had permanent fatal errors -----
|
||
<pikachu@clipper.ens.fr>
|
||
</pre>
|
||
|
||
<p>
|
||
Cela est certainement dû à un exitcode dans un
|
||
<code>.procmailrc</code>...</p>
|
||
|
||
|
||
<h4>Filtrer suivant l'expéditeur</h4>
|
||
|
||
<p> Dans d'autres cas, vous pouvez très bien connaître l'adresse
|
||
électronique de ceux qui vous spamment. Ce peut être une liste de
|
||
diffusion à laquelle vous avez été abonné, volontairement ou non, et à
|
||
laquelle les administrateurs de la liste ne vous désabonnent pas. La
|
||
recette qu'il vous faut est la suivante : tous les courriers
|
||
provenant de l'adresse spam@foo.bar seront impitoyablement envoyés à
|
||
la poubelle (dans /dev/null, en fait).</p>
|
||
|
||
<pre>
|
||
:0
|
||
* ^From.*spam@foo.bar
|
||
/dev/null
|
||
</pre>
|
||
|
||
<h4>Filtrer suivant l'encodage</h4>
|
||
|
||
<p>Vous recevez beaucoup de mails en provenance de Corée, qui sont un
|
||
charabia illisible. Vous voudriez les filtrer. On rappelle que
|
||
procmail peut filtrer sur n'importe quel en-tête de message. Si vous
|
||
regardez les en-têtes d'un spam coréen (appuyez sur <code>H</code>,
|
||
que vous utilisiez mutt ou pine, pour y avoir accès), vous verrez un
|
||
champ appelé <code>Content-type</code>. Dans ce champ est déclaré
|
||
<code>charset="ks_c_5601-1987"</code>. Il vous suffit de filtrer cet
|
||
encodagespour être débarrassé de la plupart des spams
|
||
coréens :</p>
|
||
|
||
<pre>
|
||
:0
|
||
* ^Content-Type: .*charset="ks_c_5601-1987"*
|
||
/dev/null
|
||
</pre>
|
||
|
||
<p>De manière plus perverse, certains spams coréens ne déclarent pas
|
||
leur encodage au bon endroit, pour éviter justement ce genre de
|
||
filtres. L'encodage est alors annoncé dans le sujet. Pour y remédier,
|
||
ajoutez simplement :</p>
|
||
|
||
<pre>
|
||
:0
|
||
* ^Subject: .*EUC-KR.*
|
||
/dev/null
|
||
|
||
:0
|
||
* ^Subject: .*ks_c_5601-1987.*
|
||
/dev/null
|
||
</pre>
|
||
|
||
<h4>Trop de filtres nuit</h4>
|
||
|
||
<div class="attention">Attention en installant des filtres
|
||
anti-spam : vous prenez le risque d'écarter des courriers qui en
|
||
fait n'en sont pas, mais qui répondent tout de même à vos
|
||
règles.</div>
|
||
|
||
<p>Ce sera le cas d'un prof coréen qui vous écrit si vous filtrez les
|
||
encodages coréens, d'un courrier parlant de FreeBSD si vous filtrez le
|
||
mot « free », etc. Plus vos règles sont strictes, moins vous
|
||
recevrez de spam, mais plus vous aurez de chances de perdre du
|
||
courrier.</p>
|
||
|
||
<p>Pour cette raison, il vaut parfois mieux envoyer les courriers
|
||
suspects dans un dossier spécial, appelé « spam », par
|
||
exemple. Voir ci-dessous comment faire.</p>
|
||
|
||
<h3>Envoyer directement certains mails dans un dossier
|
||
particulier</h3>
|
||
|
||
<p> Cette recette est particulièrement utile pour les listes de
|
||
diffusion (<em lang="en">mailing-lists</em>) : vous pouvez envoyer
|
||
tous les courriers provenant de la liste directement dans un dossier
|
||
spécial, qui contiendra seulement les courriers de ce genre.</p>
|
||
|
||
<p> Admettons que vous apparteniez à la liste des amis de
|
||
Scoubidou. Cette liste a pour adresse
|
||
<code>scoubidou@zoinx.foo</code>, et tous les courriers de la liste
|
||
ont pour champ expéditeur :</p>
|
||
|
||
<pre>
|
||
To: Les Amis de Scoubidou <scoubidou@zoinx.foo>
|
||
</pre>
|
||
|
||
<p>Vous voulez regrouper les courriers de la liste dans un dossier
|
||
appelé « scoubidou. » La recette qu'il vous faut est la
|
||
suivant :</p>
|
||
|
||
<pre>
|
||
# Le dernier ":" demande l'utilisation d'un fichier verrou
|
||
:0:
|
||
# La condition : tous les fichiers contenant 'scoubidou@zoinx.foo'
|
||
# dans le champ 'To: '
|
||
* ^To.*scoubidou@zoinx.foo
|
||
# Action : placer tous ces mails dans le dossier
|
||
# « Scoubidou »
|
||
$HOME/Mail/scoubidou
|
||
</pre>
|
||
|
||
<p>À quoi sert le <a name="lock">fichier verrou</a> ? Imaginons
|
||
que deux courriers de la liste arrivent en même temps : deux
|
||
procmails essaieront d'envoyer les deux messages dans le dossier en
|
||
même temps. Si vous utilisez un fichier verrou, le premier procmail
|
||
verrouillera le dossier pendant qu'il écrira son message dans le
|
||
dossier, empêchant ainsi le second message d'y accéder. Une fois que
|
||
le premier procmail aura fait son travail, le second prendra le relais
|
||
en toute sécurité. </p>
|
||
|
||
<div class="attention">Attention ! Si vous classez ainsi vos
|
||
mails, vous perdrez les avertissements « You have new
|
||
mail. » Pour remédier à ce problème, il va falloir
|
||
bidouiller...</div>
|
||
|
||
<p> Il faut tout d'abord ajouter dans votre .zshrc les lignes
|
||
suivantes :</p>
|
||
|
||
<pre>
|
||
MAILPATH="$MAIL:$HOME/mail/Scoubidou?You have new mail in Scoubidou."
|
||
export MAILPATH
|
||
</pre>
|
||
|
||
<p>Ensuite, dans votre <code>.procmailrc</code>,</p>
|
||
|
||
<pre>
|
||
:0
|
||
* ^(To:|Cc:).*scoubidou@zoinx.foo.*
|
||
{
|
||
:0c
|
||
| touch $HOME/mail/Scoubidou
|
||
|
||
:0
|
||
mail/Scoubidou
|
||
}
|
||
</pre>
|
||
|
||
<p>Cette recette se substitue bien évidemment à la précédente.</p>
|
||
|
||
<h4>Un dossier spécial spam</h4>
|
||
|
||
<p>Une application intéressante de classement concerne le spam Pour
|
||
dea raisons évoquées plus haut, il n'est parfois pas prudent d'envoyer
|
||
le courrier suspect directement vers <code>/dev/null/</code> :
|
||
vous risquez de perdre du vrai courrier. Il vaut mieux parfois
|
||
rerouter le courrier vers un dossier spécial que vous consulterez
|
||
seulement de temps à autres.</p>
|
||
|
||
<p>Prenons un exemple. Beaucoup de spams ont un
|
||
<code>Content-type</code> en <code>text/html</code>, c'est-à-dire du
|
||
HTML seulement sans copie texte. Inversement, il n'y a guère que les
|
||
spams pour être en <code>text/html</code> : les gens normaux avec
|
||
un logiciel mal configuré n'envoient guère que du HTML+ texte (donc un
|
||
<code>Content-type</code> en <code>multipart/alternative</code>). Vous
|
||
voulez donc filtrer le <code>text/html</code>. Mais l'expérience
|
||
prouve que certains logiciels particulièrement malfaisants envoient
|
||
des courriers parfaitement normaux en
|
||
<code>text/html</code>. Solution : envoyer tous ces mails dans un
|
||
dossier spécial.</p>
|
||
|
||
<p>Application :</p>
|
||
|
||
<pre>
|
||
:0
|
||
* ^Content-Type: text/html.*
|
||
$HOME/Mail/spam
|
||
</pre>
|
||
|
||
<h4>Recettes imbriquées</h4>
|
||
|
||
<p>
|
||
Un dernier exemple pour la route ! Encore plus fort,
|
||
maintenant ! Nous allons reprendre l'exemple du courrier à
|
||
relayer à votre ami Choupi. Dans l'état où nous vous avions laissé,
|
||
vous saviez lui relayer le courrier contenant « Scoubidou » dans le
|
||
sujet et en garder une copie chez vous. Maintenant nous allons vous
|
||
montrer comment faire ceci, mais en envoyant vos copies à vous dans le
|
||
dossier « Scoubi. » Il s'agit donc d'une recette constituée de deux
|
||
recettes imbriquées (chaque recette commence par un :0,
|
||
souvenez-vous) :</p>
|
||
|
||
<pre>
|
||
:0:
|
||
# Cf. ci-dessus
|
||
* ^Subject:.*Scoubidou.*
|
||
{
|
||
:0 c
|
||
# On fait suivre vers Choupi
|
||
! choupi@scoubidou-fan.com
|
||
# et en plus de ça...
|
||
:0
|
||
# ... on dépose la copie dans le dossier « Scoubi »
|
||
$HOME/Mail/scoubi
|
||
}
|
||
</pre>
|
||
|
||
<h2>Conclusion</h2>
|
||
|
||
<p> Ceci ne montre qu'une partie des possibilités de procmail. Vous
|
||
pouvez faire beaucoup de choses plus compliquées mais tout aussi
|
||
utiles : ajouter systématiquement un champ (Reply-To, par
|
||
exemple), éviter les boucles... Pour davantage de renseignements,
|
||
consultez les pages de man. <code>man procmail</code> est une
|
||
description de procmail lui-même. Vous y trouverez les options de
|
||
procmail, <code>man procmailrc</code> est très complet mais
|
||
indubitablement compliqué. <code>man procmailsc</code> est à réserver
|
||
aux experts de procmail. <code>man procmailex</code> propose des
|
||
exemples prêts à utilisation. C'est sans doute la page de man la plus
|
||
utile pour celui qui veut se familiariser davantage avec procmail.
|
||
</p>
|
||
|
||
<div class="metainformation">
|
||
Auteur Marie-Lan Nguyen. Dernière modification :
|
||
2003-03-31</div>
|
||
|
||
</body>
|
||
</html>
|