Le courrier électronique Vincent Defert - 21 Déc. 1998

Introduction

Le présent document a pour objet d'expliquer dans ses grandes lignes comment fonctionne le courrier électronique sur l'Internet et comment mettre en place un serveur simple.

Un peu de terminologie

SMTP

Abbréviation de Simple Mail Transfer Protocol, protocole de transmission de ourrier électronique en usage sur l'Internet.

MTA

Abbréviation de Mail Transport Agent, terme officiel désignant un serveur prennant en charge les messages envoyés.

MDA

Abbréviation de Mail Delivery Agent, programme prenant en charge la distribution du courrier reçu par le MTA du destinataire. C'est ce programme qui place les messages dans les bonnes boîtes aux lettres.

MUA

Abbréviation de Mail User Agent, désigne le programme que vous utilisez pour envoyer et recevoir vos messages (outil de messagerie).

POP3, IMAP4

Protocoles permettant d'accéder au courrier reçu. POP3 ne vous permet de voir qu'une seule boîte aux lettres dont vous transférez le contenu dans votre machine régulièrement, alors qu'IMAP4 permet de créer des dossiers sur le serveur afin d'y classer le courrier. Ainsi, un fournisseur d'accès Internet n'offrira à ses clients que des boîtes POP3 afin d'éviter l'encombrement du serveur alors qu'une société choisira plutôt IMAP4 pour faciliter la communication avec le personnel itinérant.

Relais

Lorsque la machine normalement responsable du traitement du courrier d'une zone n'est pas disponible (ex. arrêt pour maintenance), d'autres machines peuvent "prendre le relais", soit pour mettre les messages en attente le temps que la machine ad hoc soit à nouveau fonctionnelle, soit parce que ces machines savent aussi comment traiter le courrier.

Spam

Ce terme anglais désigne l'équivalent électronique des prospectus papier. Comme leur version papier, ils encombrent votre boîte aux lettres électronique, vous font perdre du temps et consomment inutilement vos ressources. Les MTA modernes offrent des moyens de défense contre cette calamité.

Autopsie d'un message

Le petit message suivant a tout d'un grand, ce qui va nous permettre de passer en revue les principales informations trouvées dans un message. Vous pouvez faire le même exercice avec n'importe quel courrier reçu en le sélectionnant et en cliquant sur l'option "Page Source" du menu "View" (si vous utilisez un autre outil de messagerie que Netscape, reportez-vous à sa documentation).

Return-Path: 
Received: (from vincent@localhost)
	by mynett.fr (8.9.1/8.9.1) id NAA00279
	for sophie; Mon, 21 Dec 1998 13:38:52 +0100
Date: Mon, 21 Dec 1998 13:38:52 +0100
From: Vincent Defert 
Message-Id: <199812211238.NAA00279@mynett.fr>
To: sophie@mynett.fr
Subject: Message de test

Bonjour,

Ceci est un message de test.

Vincent

Un message comporte 2 parties : l'entête (adressage et autres informations à caractère administratif) et le corps (contenu "utile"). L'entête est composé de champs.

Return-Path:

Return-Path signifie "Chemin de retour". On trouve ici l'adresse électronique de l'expéditeur.

Received: (from vincent@localhost)
by mynett.fr (8.9.1/8.9.1) id NAA00279
for sophie; Mon, 21 Dec 1998 13:38:52 +0100

Chaque machine par laquelle le message a transité ajoute un champ Received: afin de permettre de retracer son parcours. Comme il faut y mettre le plus d'informations possible et qu'on cherche au maximum à éviter les lignes longues (plus de 76 caractères) pour préserver l'intégrité du message, le champ Received peut être réparti sur plusieurs lignes (ici, 3). La 2ème et les suivantes commencent par une tabulation pour indiquer qu'il s'agit de lignes de continuation. Ceci est vrai pour tous les champs.

Date: Mon, 21 Dec 1998 13:38:52 +0100

Ce champ indique la date d'expédition (temps local) et le décalage par rapport au temps GMT (+0100).

From: Vincent Defert

Le champ From: indique l'adresse électronique de l'expéditeur.

Message-Id: <199812211238.NAA00279@mynett.fr>

Ce champ indique un identificateur unique attribué au message. Il permet en particulier de retrouver le fil d'une série de messages pour les classer (quand on répond, cet identificateur est copié dans un champ In-Reply-To:).

To: sophie@mynett.fr

Le champ To: indique la ou les adresses des destinataires pour action. Les destinataires pour information apparaissent dans un champ Cc: (pour "Carbon Copy", c'est à dire duplicata).

Subject: Message de test

Ce champ indique le sujet du message.

Une ligne vide

Cette ligne vide est indispensable : elle sert à marquer la fin de l'entête. Le corps du message commence dès la ligne suivante.

Il s'agit bien sûr d'un message minimal. Le format et la composition de l'entête sont décrits par le RFC 822. Une convention sur le format du contenu du message connue sous le nom de MIME (Multipart Internet Mail Extension), décrite par une série de RFC, autorise également l'envoi de pièces jointes.

Principe de fonctionnement

Lorsque vous envoyez un message, votre MUA se connecte au MTA indiqué dans sa configuration et lui soumet les données. Si on se réfère à l'exemple précédent où le destinataire est sophie@mynett.fr, le MTA extrait le domaine de l'adresse du destinataire (ici, mynett.fr), puis il demande à son DNS de lui indiquer les enregistrements MX associés à cette zone, par exemple :

mail.mynett.fr, poids 0
monrelais.autredomaine.fr, poids 10

Le poids des MX établit un ordre préférentiel. Ainsi, on tentera d'abord d'utiliser la machine de poids 0, puis celle de poids 1, etc. Dans notre cas, le MTA d'origine établira une connexion avec mail.mynett.fr et lui transmettra le message. mail.mynett.fr ajoutera un champ Received: et passera le message au MDA qui l'enregistrera dans la bonne boîte aux lettres.

Pour illustrer le dialogue entre votre MUA et le MTA d'origine, vous pouvez reproduire la manipulation suivante en remplaçant les adresses indiquées par la vôtre. Ce que vous devez taper est en italique.

nenette:~$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mynett.fr ESMTP Sendmail 8.9.1/8.9.1; Mon, 21 Dec 1998 14:36:29 +0100
HELO localhost
250 mynett.fr Hello vincent@localhost [127.0.0.1], pleased to meet you
MAIL FROM: 
250 ... Sender ok
RCPT TO: 
250 ... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
From: Moi 
To: Moi aussi 
Subject: Message de test

Voici le corps du message.

Ciao.
.
250 OAA00340 Message accepted for delivery
QUIT
221 mynett.fr closing connection
Connection closed by foreign host.
You have mail in /var/spool/mail/vincent

Cet exemple est intéressant car il permet de distinguer enveloppe et entête : comme avec un courrier papier, on peut faire figurer sur l'enveloppe des mentions différentes de celles portées sur le courrier (dont la première page est en principe sur papier à entête).

Ici, l'enveloppe est donc décrite par les commandes MAIL FROM et RCPT TO. Il s'agit des instructions données au MTA pour l'acheminement du courrier. L'entête contient les indications utiles au destinataire. C'est cette distinction qui permet d'envoyer des copies confidentielles (Bcc, Blind Carbon Copies) : il suffit de désigner un destinataire avec une commande RCPT TO et de ne pas le faire figurer dans le champ To: ou Cc: de l'entête. Ainsi, il recevra le message, mais saura qu'il s'agit d'une copie confidentielle puisqu'il ne se verra pas dans l'entête.

Pour boucler la boucle, voyons comment le MUA du destinataire procède pour récupérer le message (cas d'un serveur POP3) :

nenette:~$ telnet localhost 110
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
+OK nenette POP3 Server (Version 1.0051) ready at 
USER vincent
+OK please send PASS command
PASS motdepasse
+OK 1 messages ready for vincent in /var/spool/mail/vincent
RETR 1
+OK message 1 (388 octets):
X-POP3-Rcpt: vincent@nenette
Return-Path: 
Received: from localhost (vincent@localhost [127.0.0.1])
	by mynett.fr (8.9.1/8.9.1) with SMTP id OAA00340
	for ; Mon, 21 Dec 1998 14:41:02 +0100
Date: Mon, 21 Dec 1998 14:41:02 +0100
From: Vincent Defert 
Message-Id: <199812211341.OAA00340@mynett.fr>
Subject: Test

Test

.
DELE 1
+OK message 1 marked for deletion
QUIT
+OK nenette POP3 Server (Version 1.0051) shutdown.
Connection closed by foreign host.

Cet exemple permet de voir que la récupération d'un message se fait en 2 temps, lecture puis suppression, ce qui explique comment procèdent les outils de messagerie qui proposent de laisser les messages sur le serveur (il suffit de ne pas faire la suppression) et pourquoi il arrive parfois dans ce cas que l'on retrouve des messages en double (perte du point de repère permettant de savoir quels messages sont nouveaux).

Mise en place d'un serveur

Maintenant que nous avons vu ce qui se passait au niveau des clients, il nous reste à aborder l'installation et l'administration d'un serveur simple. La référence en matière de MTA, Sendmail, étant fourni avec toutes les distributions de Linux, c'est avec lui que nous illustrerons notre propos.

Son installation étant probablement déjà faite, ou au pire ne demandant que l'utilisation du gestionnaire de packages de votre distribution, nous passerons directement à la configuration. Pour ce faire, placez-vous dans le répertoire /usr/src/sendmail/cf. S'il n'existe pas, installez le package intitulé "Fichiers de configuration de Sendmail" ou smailcfg.tgz ou quelque chose de similaire.

La machine sur laquelle nous travaillons est supposée gérer le courrier électronique d'un domaine réel. Elle est donc reliée en permanence à l'Internet, est correctement configurée, et c'est vers elle que pointe le MX record de poids le plus faible du domaine considéré. Il n'y a aucun inconvénient à ce qu'elle gère le courrier de plusieurs domaines.

Ceci étant précisé, vous allez maintenant créer le fichier sendmail.mc dans le répertoire /usr/src/sendmail/cf :

include(`m4/cf.m4')
OSTYPE(`linux')
define(`ALIAS_FILE', `/etc/mail/aliases')
define(`STATUS_FILE', `/etc/mail/sendmail.st')
define(`confCW_FILE', `/etc/mail/sendmail.cw')
FEATURE(`use_cw_file')
LOCAL_CONFIG
`Fm'confCW_FILE
FEATURE(`relay_entire_domain')
FEATURE(`redirect')
FEATURE(`virtusertable', `hash -o /etc/mail/virtuser')
FEATURE(`access_db', `hash -o /etc/mail/access')
FEATURE(`blacklist_recipients')
FEATURE(`rbl')
define(`confDEF_CHAR_SET', `ISO-8859-1')
define(`confMIME_FORMAT_ERRORS', `True')
MAILER(`procmail')
MAILER(`smtp')

Voici la signification du contenu de ce fichier:

include(`m4/cf.m4')

Charge les définitions de base.

OSTYPE(`linux')

Charge les définitions de base propres à Linux.

define(`ALIAS_FILE', `/etc/mail/aliases')
define(`STATUS_FILE', `/etc/mail/sendmail.st')
define(`confCW_FILE', `/etc/mail/sendmail.cw')

Définit l'emplacement de quelques fichiers. Par défaut, ceux-ci sont dans /etc, mais la migration de tous les fichiers de Sendmail dans /etc/mail est prévue, donc autant anticiper. De plus, ça limite la prolifération des fichiers dans /etc. Le fichier /etc/mail/aliases contient la liste des alias locaux. Il peut servir à créer des listes de diffusion internes.

FEATURE(`use_cw_file')

Indique à Sendmail que la liste des domaines locaux est contenue dans le fichier /etc/mail/sendmail.cw. En clair, cela signifie que toute adresse dont la partie droite figure dans cette liste doit correspondre à un compte de cette machine (si ce n'est pas le cas, Sendmail renvoie un message d'erreur à l'expéditeur).

LOCAL_CONFIG
`Fm'confCW_FILE
FEATURE(`relay_entire_domain')

Signifie que toutes les machines appartenant à un domaine local peuvent utiliser ce serveur pour envoyer leurs messages quels que soient le ou les destinataires. Toute machine n'appartenant pas à un domaine local ne peut utiliser ce serveur que pour envoyer un message à une ou des adresses locales.

FEATURE(`redirect')

Lorsqu'on supprime un compte mais qu'on connait la nouvelle adresse de son titulaire, on peut créer un alias de la forme "ancien_nom: nouvelle_adresse.REDIRECT" dans /etc/mail/aliases. Toute tentative d'envoi d'un message à l'ancienne adresse provoquera une erreur "551 User not local; please try <nouvelle_adresse>".

FEATURE(`virtusertable', `hash -o /etc/mail/virtuser')

Active une puissante fonction de redirection (voir description sur site de Sendmail). Permet par exemple de renvoyer le courrier adressé à un compte supprimé à une autre adresse.

FEATURE(`access_db', `hash -o /etc/mail/accessdb')
FEATURE(`blacklist_recipients')

Active l'utilisation de la base de données de contrôle d'accès (voir description sur site de Sendmail). Cette puissante fonctionnalité permet en particulier de lutter contre le spam.

FEATURE(`rbl')

Active l'utilisation de la Realtime Blackhole List, une liste de spammers notoires gérée sur un serveur Internet et mise à jour en permanence. Facilite énormément la mise en place de mesures anti-spam : il suffit de mettre dans /etc/mail/accessdb les règles permettant de bloquer ce qui ne l'est pas encore par la RBL.

define(`confDEF_CHAR_SET', `ISO-8859-1')

Lorsque le message des caractères dont le code est supérieur à 127 sans indiquer l'encodage utilisé, Sendmail considérera qu'il s'agit du code ISO 8859-1.

define(`confMIME_FORMAT_ERRORS', `True')

Quand Sendmail retournera à l'expéditeur un message d'erreur, il joindra le message d'origine sous forme de pièce jointe.

MAILER(`procmail')

Indique à Sendmail d'utiliser procmail pour délivrer les messages adressés à des utilisateurs locaux. Procmail est le MDA le plus apprécié. Il est inclu dans toutes les distributions de Linux.

MAILER(`smtp')

Définit les règles à appliquer aux messages adressés à des utilisateurs gérés sur d'autres machines.

Pour transformer ces options intelligibles en fichier de configuration adapté à sendmail, exécutez maintenant la commande "m4 sendmail.mc > /etc/sendmail.cf". Si vous êtes curieux, vous ne résisterez pas à la tentation de jeter un oeil au fichier /etc/sendmail.cf ...

Créez maintenant le répertoire /etc/mail et rendez-le courant. Vous pouvez à présent y créer le fichier des domaines locaux, sendmail.cw. Exemple :

mynett.fr
lesamis2linux.fr

En cas de prise en charge d'un nouveau domaine, il suffira d'ajouter son nom à ce fichier, en supposant bien sûr que le MX de poids le plus faible de cette zone pointe sur ce serveur.

Créez également le fichier aliases, contenant par exemple les lignes suivantes :

MAILER-DAEMON: postmaster
postmaster: root
halt: root
operator: root
shutdown: root
sync: root
bin: root
ftp: root
daemon: root
adm: root
lp: root
mail: root
news: root
uucp: root
man: root
games: root
guest: root
nobody: root
decode: root

Les 2 premiers alias sont obligatoires. Les suivants empêchent l'envoi de messages aux comptes spéciaux du système. Pour créer une liste de diffusion, vous pouvez également ajouter une définition comme celle-ci :

liste1: 
	sophie, 
	benoit, 
	carole, 
	nausicaa,
	vincent, 
	yves, 
	loic, 
	brieuc, 
	hermione, 
	timandra

Tout aurait pu être mis sur la même ligne, mais on installe rarement un serveur pour 2 utilisateurs, d'où le choix de préseanter la liste sous cette forme : il suffit de mettre à la fin le compte le moins succeptible d'être supprimé et la maintenance de la liste est assez simple. Toutes les lignes sauf la première sont des lignes de continuation et commencent donc par une tabulation.

Petite précision : si vous envoyez un message à une liste dont vous êtes membre, vous ne recevrez par défaut pas de copie de ce message. Pour changer ceci, il suffit d'ajouter au fichier sendmail.mc la ligne :

define(`confME_TOO', `True')

Ensuite, vous pouvez créer le fichier virtuser. Exemple :

vincent.defert@mynett.fr vincent@mynett.fr
compte.supprime@mynett.fr postmaster@mynett.fr
@lesamis2linux.fr vincent@mynett.fr

Ensuite, exécutez les commandes suivantes:

newaliases
makemap hash virtuser < virtuser
killall -HUP sendmail

Afin d'optimiser les recherches dans les tables, Sendmail utilise des versions "pré-traitées" des fichiers que vous venez de saisir. La commande newaliases remet à jour le fichier réellement utilisé par Sendmail à partir du fichier /etc/mail/aliases. La commande makemap fait de même pour le fichier virtuser. Toute modification de l'un ou l'autre de ces fichiers devra donc s'accompagner de la commande de mise à jour correspondante.

Enfin, le killall provoque la réinitialisation de Sendmail (relecture de /etc/sendmail.cf). Cette opération n'est nécessaire qu'en cas de modification de sendmail.cf. La modification d'un des autres fichiers est prise en compte immédiatement.

Références

Les HOWTOs peuvent être consultés au format HTML et en français sur Freenix. Les RFC peuvent être récupérés sur un grand nombre de serveurs FTP dont ftp.inria.fr et ftp.lip6.fr.