Leçon 1 sur 12 · Fondamentaux SMTP
Le voyage d'un e-mail : SMTP, submission et IMAP
Objectif
Comprendre ce qui se passe entre le clic sur « Envoyer » et l'arrivée du message dans une boîte, savoir parler SMTP à la main à un serveur et lire l'historique d'un message dans ses en-têtes.
L'essentiel
- Quatre rôles : le MUA (Thunderbird, Outlook, un téléphone) écrit ; le MSA reçoit l'envoi authentifié (port 587 ou 465) ; le MTA (Postfix) transporte de serveur à serveur (port 25) ; le MDA (Dovecot) range dans la boîte, que le client lit en IMAP (port 993).
- Pour trouver le serveur du destinataire, le MTA demande au DNS l'enregistrement MX du domaine.
- Une session SMTP tient en cinq commandes :
EHLO,MAIL FROM,RCPT TO,DATA,QUIT. - L'enveloppe (
MAIL FROM,RCPT TO) sert au transport ; les en-têtes (From:,To:,Subject:) sont ce que l'utilisateur voit. Ils peuvent être différents. - Chaque serveur traversé ajoute une ligne
Received:en haut : on lit donc l'historique de bas en haut.
1. Les acteurs et les ports
poste de l'agence de Fès Internet ml-mail-01.masterlinux.lab
┌───────────────┐ 587 (STARTTLS) ┌──────────────┐ 25 (SMTP) ┌─────────────────────────────┐
│ MUA │ ── + mot de passe ─► │ MSA/MTA │ ─────────────► │ MTA Postfix ─► MDA Dovecot │
│ Thunderbird │ │ smtp.gmail… │ (MX du domaine) │ boîte Maildir │
└───────────────┘ └──────────────┘ └──────────────┬──────────────┘
IMAP 993 (TLS) │
téléphone du support ◄┘
| Port | Nom (/etc/services) |
Rôle | Chiffrement |
|---|---|---|---|
| 25 | smtp | serveur à serveur (relais MX) | STARTTLS facultatif |
| 587 | submission | envoi par les utilisateurs, avec authentification | STARTTLS obligatoire |
| 465 | submissions | envoi par les utilisateurs, TLS dès la connexion | TLS implicite |
| 143 | imap | lecture des boîtes | STARTTLS |
| 993 | imaps | lecture des boîtes | TLS implicite |
| 110 / 995 | pop3 / pop3s | ancien protocole de relève | — |
Le port 25 sert entre serveurs. Beaucoup d'opérateurs (au Maroc comme ailleurs) bloquent le port 25 sortant des connexions domestiques : un utilisateur qui envoie doit passer par 587 ou 465, authentifié.
2. Trouver le serveur du destinataire : le MX
dig MX masterlinux.lab +short
# 10 mail.masterlinux.lab. ← priorité 10 (plus petit = préféré)
# 20 mail2.masterlinux.lab. ← secours
dig A mail.masterlinux.lab +short
# 203.0.113.25
Sans MX, l'expéditeur essaie l'enregistrement A du domaine lui-même (règle de repli de la RFC 5321). Un domaine qui ne reçoit jamais de courrier peut publier un MX nul : @ IN MX 0 ..
3. Une session SMTP à la main
Sur un vrai serveur, on teste avec swaks (paquet swaks) ou à la main avec nc ou openssl s_client :
swaks --to support@masterlinux.lab --from ops@masterlinux.lab --server 127.0.0.1 --header "Subject: Test"
openssl s_client -connect mail.masterlinux.lab:25 -starttls smtp -crlf -quiet
Le dialogue, ligne par ligne (C = client, S = serveur) :
S: 220 mail.masterlinux.lab ESMTP Postfix ← bannière
C: EHLO ml-poste-01
S: 250-mail.masterlinux.lab
S: 250-SIZE 10240000 ← taille maximale acceptée
S: 250-STARTTLS ← chiffrement possible
S: 250 8BITMIME
C: MAIL FROM:<ops@masterlinux.lab> ← enveloppe : expéditeur (adresse de retour)
S: 250 2.1.0 Ok
C: RCPT TO:<support@masterlinux.lab> ← enveloppe : destinataire
S: 250 2.1.5 Ok
C: DATA
S: 354 End data with <CR><LF>.<CR><LF>
C: From: ops@masterlinux.lab ← en-têtes (ce que l'utilisateur voit)
C: Subject: Premier envoi
C: ← ligne vide : fin des en-têtes
C: Bonjour.
C: . ← un point seul : fin du message
S: 250 2.0.0 Ok: queued as 3F2A61C0D2 ← identifiant dans la file
C: QUIT
S: 221 2.0.0 Bye
Les codes de réponse se lisent au premier chiffre : 2xx réussi, 3xx continuer, 4xx échec temporaire (l'expéditeur réessaiera), 5xx échec définitif (retour à l'expéditeur). Le code étendu (5.1.1, 4.7.1…) précise la cause : 5.1.1 = boîte inconnue, 5.7.1 = refusé par une règle de sécurité.
Dans les labs de cette formation
La machine de lab n'a pas de réseau. Elle fait tourner ml-smtpd, un serveur SMTP d'entraînement qui lit le vrai fichier /etc/postfix/main.cf et répond avec les messages de Postfix. Il écoute sur 127.0.0.1:25 et :587, livre les domaines locaux en Maildir et écrit /var/log/mail.log.
# 1. comme sendmail -bs : une session SMTP sur l'entrée standard
printf 'EHLO lab\r\nMAIL FROM:<ops@masterlinux.lab>\r\nRCPT TO:<support@masterlinux.lab>\r\nQUIT\r\n' | ml-smtpd --stdio
# 2. par le réseau local, avec Python (set_debuglevel affiche tout le dialogue)
python3 -c 'import smtplib; s=smtplib.SMTP("127.0.0.1", 25); s.set_debuglevel(1); s.noop(); s.quit()'
# 3. à la main avec bash (redirection /dev/tcp)
exec 3<>/dev/tcp/127.0.0.1/25; head -1 <&3; printf 'QUIT\r\n' >&3; cat <&3
4. Enveloppe contre en-têtes
L'enveloppe ressemble à l'adresse écrite sur une lettre postale ; les en-têtes sont l'en-tête de la lettre à l'intérieur. Le facteur ne lit que l'enveloppe.
| Enveloppe (SMTP) | En-têtes (contenu) | |
|---|---|---|
| Expéditeur | MAIL FROM:<bounces@masterlinux.lab> |
From: Support <support@masterlinux.lab> |
| Destinataire | RCPT TO:<admin@masterlinux.lab> |
To:, Cc: (et rien pour Bcc) |
| Qui l'utilise | les serveurs, SPF, les retours d'erreur | l'utilisateur, DMARC, les filtres |
| Trace à l'arrivée | Return-Path: ajouté par le serveur final |
inchangés |
C'est ce qui permet à une plateforme d'envoi de recevoir les retours d'erreur (bounces@…) tout en affichant l'adresse de la boutique. C'est aussi ce que les usurpateurs exploitent : d'où SPF, DKIM et DMARC (niveau 4).
5. Lire les lignes Received
Received: from mail-ed1-f45.google.com (mail-ed1-f45.google.com [209.85.208.45]) ← 3. reçu par NOTRE serveur
by mail.masterlinux.lab (Postfix) with ESMTPS id 4B7F21C0A2 …
Received: by mail-ed1-f45.google.com with SMTP id … ← 2. transfert interne Google
Received: from [192.168.1.23] ([41.250.88.17]) by smtp.gmail.com with ESMTPSA … ← 1. envoi du client
ESMTPS= chiffré (TLS),ESMTPA= authentifié,ESMTPSA= les deux.- Dans
from X ([IP]), le nom X est déclaré par le client (il peut mentir) ; l'IP entre crochets est vue par le serveur (fiable si ce serveur est de confiance). 192.168.1.23est l'adresse privée du poste derrière la box ;41.250.88.17est l'adresse publique vue par Gmail.
grep -n '^Received:' /root/recu.eml # les lignes de début
awk '/^Received:/,/;/' /root/recu.eml # chaque Received complet (jusqu'à la date)
Cas réel
Un lundi matin, l'équipe support de la boutique MasterLinux reçoit une réclamation « je n'ai jamais reçu votre réponse ». En relisant les en-têtes du message envoyé, l'administrateur voit que le poste du support envoyait en ESMTP (sans A) vers le port 25 d'un ancien serveur : le message partait sans authentification et Gmail le classait en spam. Passer le client de messagerie en 587 + STARTTLS + authentification a réglé le problème. Lire les Received avant de toucher à la configuration fait gagner des heures.
Pièges fréquents
- Confondre 25 et 587 : un client de messagerie configuré sur 25 marche au bureau puis échoue en 4G (port bloqué par l'opérateur).
- Croire l'en-tête From: : il est écrit par l'expéditeur, comme le nom après
fromdans Received. Seules les IP ajoutées par vos serveurs sont fiables. - Oublier
\r\nen SMTP à la main : certains serveurs refusent les fins de ligne seules (\n) — c'est même la base de l'attaque « SMTP smuggling » de 2023-2024, corrigée dans Postfix parsmtpd_forbid_bare_newline. - Lire les Received de haut en bas : le premier est le plus récent.
Lab
Sur la machine de lab, ml-smtpd joue le rôle de ml-mail-01 pour le domaine masterlinux.lab. Vous allez : envoyer un premier message par SMTP, envoyer un message dont l'enveloppe diffère de l'en-tête, provoquer un refus 550 5.1.1, retrouver l'IP d'origine d'un message réel, et récapituler les ports de la messagerie.
Quiz
- Quel enregistrement DNS indique le serveur qui reçoit le courrier d'un domaine ?
- Quelle est la différence entre
MAIL FROMet l'en-têteFrom:? - Que signifie un code de réponse qui commence par 4 ?
- Pourquoi un utilisateur envoie-t-il sur 587 et non sur 25 ?
- Dans quel ordre lit-on les lignes
Received:?
Réponses
- L'enregistrement MX (avec sa priorité ; plus petit = préféré).
MAIL FROMfait partie de l'enveloppe SMTP (adresse de retour des erreurs, utilisée par SPF) ;From:est un en-tête du contenu, affiché à l'utilisateur.- Un échec temporaire : le serveur expéditeur garde le message en file et réessaie plus tard.
- Le port 587 (submission) exige l'authentification et le chiffrement ; le port 25 est réservé aux échanges entre serveurs et souvent bloqué en sortie chez les opérateurs.
- De bas en haut : chaque serveur ajoute sa ligne au-dessus des précédentes.