Le filtrage est décrit par un fichier de configuration. Chaque ligne de ce fichier décrit une condition. L'agent de livraison lit chaque ligne, vérifie les conditions et exécute éventuellement une commande.
les lignes vides, composées uniquement d'espaces ainsi que les lignes qui commencent par un dièse « # » sont ignorées.
Les instructions de la forme
En-Tête: expression commande En-Tête: !expression commande
indiquent que la commande sera exécutée si l'en-tête existe et vérifie (ou ne vérifie pas dans le second cas) l'expression décrite.
Les noms des en-tête sont regardés indépendament de la casse,
par exemple,
date:
Date:
DATE:
DaTe:
vérifient toutes les mêmes en-têtes. Pour rechercher
sur un en-tête avec une casse bien précise, il faut
le préfixer du caractère « \
». Par exemple,
\date:
vérifie l'en-tête "date" typographié exactement de cette façon.
On peut, en une seule instruction vérifier plusieurs en-têtes à la fois. Il faut concaténer les en-têtes en questions en les séparant par « : » Par exemple:
# exécute commande si un des en-têtes parmi From, Sender # ou Return-Path contient l'adresse toto@example.com From:Sender:Return-Path: /toto@example.com/a commande
On peut vérifier une expression dans toutes les en-têtes
avec « *
» :
# exécute commande si le contenu d'un en-tête # vérifie "toto" *: /toto/ commande
header_set
.
From:Sender:Return-Path: /toto@example.com/a drop From:Sender:Return-Path: /toto@example.net/a drop From:Sender:Return-Path: /toto@example.org/a droppar
: header_set f From Sender Return-Path %f: /toto@example.com/a drop %f: /toto@example.net/a drop %f: /toto@example.org/a dropL'ensemble «
f
» est défini et contient les
en-tête « From
»,
« Sender
» et
« Return-Path
». Le
« %f
» à la place d'une en-tête reprendra tous
les en-têtes de l'ensemble.
Certains en-têtes peuvent avoir été codées pour passer sur les
serveur de courrier. C'est notement le cas lorsqu'elles doivent
contenir des caractères accentués, chinois, musicaux, et autres. Par
exemple la phrase « un filtre; » peut être codé comme
=?iso-8859-1?b?dW4gZmlsdHJl?=
et la phrase « deux
filtres; » comme
=?iso-8859-1?b?ZGV1eCBmaWx0cmVz?=
. Il y a d'autes codages
possibles.
Il est possible de recoder ces en-têtes dans un jeu de caractère universel (Unicode) Elles seront recodées en UTF-8 où chaque caractère est représenté en un ou plusieurs octets. Les caractères alphabétiques et numériques, la ponctuation sont représentés en UTF-8 en un seul octet, tout comme dans la représentation ordinaire (US-ASCII, ISO8858-1) en Europe occidentale et en Amérique.
Pour transformer les séquences encodées en UTF-8, il faut faire
préceder le nom de l'en-tête ou du groupe d'en-têtes par un tilde
« ~
; », par exemple :
~Subject: /un filtre/S'il y a plusieurs en-têtes, il faut précéder chacune par un «
~
» :
~To:~Cc: /toto/
Notez qu'il est plus approprié d'utiliser des expressions rationnelles gérant l'UTF-8 lorsque l'on considére que la séquence a des caractères complexes (accents, idéogrammes, etc.)
Il est possible de nier ces instructions (exécuter des commandes si les conditions ne sont pas vérifiées) :
!En-tête: expression commande !En-tête: !expression commandeCela permet de filtrer sur la présence ou l'absence d'un en-tête. Voici un résumé des cas d'exécution de commandes avec les possibilités de négation :
l'instruction ci dessous | exécute la commande si |
---|---|
En-tête: ER | il existe un en-tête qui vérifie l'E.R. |
!En-tête: ER | aucun en-tête ne vérifie l'E.R. |
En-tête: !ER | il y a un en-tête qui ne vérifie pas l'E.R. |
!En-tête: !ER | tous les en-têtes éventuels vérifient l'E.R. |
Il est possible d'exécuter des commandes en vue de comparer des scalaires x et y de la manière suivante :
$x=y commande $x<>y commande $x<y commande $x<=y commande $x>y commande $x>=y commande
la commande sera exécutée selon que le scalaire x est égal, différent, inférieur, inférieur ou égal, supérieur, supérieur ou égal au scalaire y On peut tester aussi si le scalaire x est non nul comme ceci
$x commandeLe scalaire vide représente le score pour tester par exemple que le score est inférieur à 10, on peut procéder comme ceci :
$<10 commande
Il est possible d'exécuter une commande en la faisant précéder de deux points « : » et d'un espace.
: commande
La commande skipto permet de passer les instructions suivantes jusqu'à rencontrer une étiquette.
:étiquette :étiquette commande
L'étiquette doit être immédiatement précédée du signe deux points « : ». La commande, si elle est présente, sera exécutée comme une exécution inconditionnelle
On peut filtrer sur le début ou la fin d'un courrier. L'agent de livraison récupère un bloc de données d'une taille paramétrable (mais limitée à 1024 octets) au début ou à la fin du corps du message.
Rechercher une expression dans les nnn premiers octets du message
+nnn expression commande
Rechercher une expression dans les nnn derniers octets du message
-nnn expression commande
Certaines commandes terminent l'analyse du filtre après leur action (deliver, drop, bounce, trash, forward, moved). Les autres (forward2, score skipto, deliver2, default, etc.) s'exécutent et le déroulement du filtre continue. Seule la commande stow peut faire s'interrompte ou pas le déroulement en fonction des circonstances.
-
» sont éventuellement
loggués mais ne font pas partie du message envoyé.
@
», la nouvelle adresse est construite
à partir de la partie locale de la boîte et et du nom de domaine
suivant l'« @
».
-
» sont
éventuellement loggués mais ne font pas partie du message envoyé, si message il y a.
@
), ces courriers
seront renvoyés à cette adresse. Sinon, l'argument est pris comme le
nom du dossier où seront déposés ses courriers. S'il n'y a pas
d'argument, ils seront déposés dans la boîte principale. Dans la
mesure du possible, les messages émis par le système de livraison
locale (comme les comptes rendus de log) suivent aussi cette
directive.
+
» et « @
»),
le courrier sera délivré dans le dossier du nom de cette extension en
miniscule si le dossier existe déjà et l'analyse du filtre s'arretera.
Si un répertoire est en argument, le dossier sera cherché dans ce
répertoire.
EnTete
avec une description de l'analyse
(le nom de l'antivirus utilisé ainsi que les éventuels virus
détectés). Précédé du signe « -
», l'en-tête
n'est ajouté que si un virus est détecté.
+
», il est ajouté ainsi que ses successeurs,
si un évènement est précédé du signe « -
», il
est supprimé du masque ainsi que ses successeurs. Si la liste ne
commence pas par « +
» ou par
« -
», le masque est défini comme ayant les
évènements de la listes.
deliver
forward
drop
bounce
error
all
, on
, yes
error
)
none
, off
, no
error
)
Un scalaire est un nombre entier éventuellement suivi d'une unité par laquelle la valeur sera multipliée.
:
», le
décompte est restreint aux en-têtes de cette listes.
http://www.rfc-ignorant.org/
Deux listes sont disponibles : DSBL (list.dsbl.org) et DSBL-M (multihop.dsbl.org) ; voir http://dsbl.org/usage
Les serveurs de listes noires sont gérés par des entités extérieures. Nous ne pouvont garantir ni leur sérieux, ni leur pertinence ni même leur bon fonctionnement.
Ils fonctionnent par des requêtes DNS, si un relai est présent
dans une liste noire, le serveur DNS renvoie une addresse IP (un
enregistrement « A
») et éventuellement un commentaire dans un
enregistrement « TXT
».
La vérification se fait avec la commande « blacklist
».
Cette commande est capable de vérifier si le courrier est passé par un
relais suspect et d'ajouter une en-tête au courrier pour le signaler.
Par exemple : : blacklist wsff,invalid* X-Blacklist: %q bloque' par %r -- %t
La commande prend comme premier argument l'énumération, avec les
éléments séparés par des virgules, de listes à vérifier (vous pouvez
les saisir en minuscules ou en majuscule). Quand un des élément se
termine par une étoile (« *
»), si l'élément
vérifie les relais (et non pas les domaines) tous les relais seront
vérifiés, sinon, seul le relais par lequel le serveur qui filtre
a reçu le courrier sera vérifié.
Les arguments suivants correspondent à un en-tête qui sera rajouté au courrier. Dans ces arguments :
%q
» l'adresse IP ou le domaine vérifié
dans la liste
%r
» le nom de la liste
%d
» le domaine utilisé pour la vérification
%p
» le rang de l'en-tête « Received
» dans le cas d'une vérification d'adresse IP
(1 pour le relai ayant envoyé un courrier au serveur de filtre, 2 pour le relais ayant envoyé un courrier au précedent, etc.)
%a
» l'adresse retournée par la liste (en « A
»)
%t
» le commentaire éventuellement retourné (en
« TXT
») par la liste
%%
» le signe « %
»
Il est possible d'ajouter l'en-tête uniquement si l'élément a
renvoyé une certaine valeur. Il suffit de le faire suivre du signe
« =
» et de la valeur à tester. Par exemple :
: blacklist ordb=127.0.0.2 X-Blacklist: relai ouvert %q
: blacklist ordb*=127.0.0.2 X-Blacklist: relai ouvert %q
Le premier n'ajoute l'en-tête que si "ordb" renvoie 127.0.0.2
dans le premier relai. Le second fait de même pour tous les relais.
L'en-tête est l'un de ceux qui peut apparaître dans le message, selon la RFC822, ce qui n'est pas nécessairement celui que votre logiciel de lecture affichera si celui-ci traduit les entêtes.
Quelques en-têtes intéressantes pour le filtrage :
/
»,
« "
» ou « '
».
Les expressions entourés par « /
» peuvent être
suivies d'une lettre d'option pour déterminer le type.
Les expressions formées par un mot commençant par « $
»
sont crées dynamiquement selon le courrier reçu ou l'état de la boîte au lettre.
Syntaxe | Type d'expression | sensible à la casse |
---|---|---|
expression
| expressions rationnelles étendues | non |
/expression/
| expressions rationnelles étendues | non |
/expression/e
| expressions rationnelles étendues | non |
/expression/E
| expressions rationnelles étendues | oui |
/expression/b
| expressions rationnelles basiques | non |
/expression/B
| expressions rationnelles basiques | oui |
/expression/p
| expressions rationnelles compatibles avec perl | non |
/expression/P
| expressions rationnelles compatibles avec perl | oui |
/expression/pu
| expressions rationnelles UTF-8 (unicode) compatibles avec perl | non |
/expression/Pu
| expressions rationnelles UTF-8 (unicode) compatibles avec perl | oui |
/expression/a
| liste d'adresses | non |
/expression/A
| liste d'adresses | oui |
/expression/f
| expressions du shell | non |
"expression"
| expressions du shell | non |
'expression'
| expressions du shell | non |
/expression/F
| expressions du shell | oui |
$return-path
| Compare avec l'adresse de l'en-tête Return-Path
ou, si elle est vide, avec la chaîne MAILER-DAEMON
| non |
$mailinglists
| Vérifie si l'entête contient une des adresses de
mailing listes définie dans les préférences du webmail | non |
Si vous voulez indiquer un caractère délimiteur à l'interieur d'une
expressions délimitée par ce caractère, il faut le faire précéder par
« \
».
Par exemple, pour vérifier l'expression rationnelle
« text/html
» :
Subject: /text\/html/ bounce
Dans le cas d'expression rationnelles POSIX indépendantes de la casse,
c'est équivalent à
Subject: text/html bounce
Les expressions //Pu et //pu, compatibles avec perl, peuvent
traiter des chaînes en UTF-8, or seuls les octets de des caractères
ASCII (lettres non accentuées, chiffres, ponctuation) sont supportés
par les filtres. Pour indiquer les autres caractères, il faut indiquer
leur position dans la liste des
caractères unicode, précédé par \x{
et terminé par
}. Les zéros initiaux de la position peuvent être
retirés et si on peut représenter cette position sur deux caractères
hexadécimaux, on peut indiquer ce caractère avec un \x
suivi de la position sur ces deux caractères hexadécimaux.
Par exemple, la lettre minuscule latin e accent grave (è) a pour
position 00E8, on peut le représenter par /\x{00E8}/pu
ou
plus simplement par /\xE8/pu
.
Les expressions //a
et //A
sont des
listes d'adresses. Elles sont composées d'une liste d'éléments (des
mailbox au sens de la RFC 2822) séparés par des virgules. Si un
élément commence par un @
, il indique toutes les adresses
du domaine suivant l'@
. Lors du passage du filtre, si
l'un de ces éléments est égal à l'un de ceux des en-têtes testés,
l'action en enclenchée.
Par exemple, le filtre suivant
To:Cc: /toto@example.com, titi@example.org/a
Est vérifié par l'entête
To: M. TOTO <TOTO@example (juste un test).com(mercial)>
Le filtre ci dessous est vérifié pour toutes les adresses du domaine
example.com
:
To: /@example.com/a
Une liste peut être composée d'une seule adresse To: /toto@example.com/a deliver
L'analyse de l'en-tête est plutôt laxiste, afin de retomber sur ses pieds en cas d'invalidité de l'en-tête.
Ces expressions ne sont utiles que dans les en-têtes qui contiennent des données au format d'adresses (entre autre To, Cc, From, Sender, Return-Path, Delivery-To, Reply-To, Mail-Copies-To, Message-ID, ... et les Resent- de ces en-têtes). Leur utilisation dans un autre contexte est indéterminée.
les expression du shell sont conçues à l'origine pour reconnaitre les fichiers dans les interprètes de commande ou les boîtes de séléction de fichiers. Elle sont beaucoup moins puissantes que les expressions rationnelles mais peuvent être plus facile à manier.
Elles n'ont, comme caractères spéciaux, que
*
» qui indique une séquence de caractères
quelconque
?
» qui indique un caractère quelconque
[d-f]
» qui indique un caractère entre
« d
» et « f
»
cassoulet
» dans le champ « Subject
»
avec une expression rationnelle ou une expression du shell :
Subject: /cassoulet/ deliver cuisine
Subject: "*cassoulet*" deliver cuisine
# la date de dernière modification s'ajoute magiquement après les deux points. # Dernière modification: # # jette le courrier venant d'une adresse contenant friend@public # ou dont le sujet contient $$$ (on met des barres obliques # inversées « \ » avant les dollars « $ » car le dollar simple # signifirait une fin de chaîne dans l'expression rationnelle. # To: /friend@public/ drop Subject: /\$\$\$/ drop # # jette un courrier qui est destiné à plus de 10 utilisateurs locaux # $r>10 drop # # délivre le courrier dont le sujet contient « urgent » # dans le dossier « important » # Subject: /urgent/ deliver important # # jette le courrier dont le sujet contient « pas urgent » # Subject: /pas urgent/ drop # # renvoit le message d'erreur « invalid content type » # pour les courriers en HTML ou les attachements. # Content-Type: /text\/html/ bounce invalid content type Content-Type: /multipart/ bounce invalid content type # # délivre un peu de courrier dans le dossier « lwa » # du répertoire « lapins » # From: /lwa@teaser\.fr/ deliver lapins.lwa # # Ajoute diverses informations dans le champ Trace des logs # : trace debut From: /titi/ trace from titi !From: /titi/ trace !from titi From: !/titi/ trace from !titi !From: !/titi/ trace !from !titi : trace fin # # Ajoute l'en-tête "From:" dans les logs sous certaines condition # From: /suspect/ trace -from quelque chose de suspect # # exemple de tri en fonction de l'heure de réception # $twd=513 bounce de'sole', je ne recois pas de mail les vendredi 13 $twh=011 deliver recu_pendant_la_messe_de_dimanche_a_11h $tcymd>20010614 skipto revenu $tcymd>20010506 vacation je suis absent du 6 mai 2001 au 14 juin 2001 :revenu # envoi une copie des courriers arrivés les jours # de semaine entre 13h30 et 23h50 $tw=0 skipto maison $tw=6 skipto maison $thn<1330 skipto maison $thn<2350 forward2 bureau@teaser.fr :maison # délivre le courrier si la chaîne "bonjour" est présente dans les 200 # premiers octets du corp du message +200 /bonjour/ deliver # rejette le courrier si le message ne contient pas "au revoir" # dans ses 300 derniers octets -300 !/au revoir/ bounce les gens polis disent au revoir