guide/email-authentifie-spf-dkim-dmarc.md

Mettre en place l'envoi d'email authentifié (SPF + DKIM + DMARC)

Objectif : vos notifications applicatives (emails transactionnels émis par votre serveur) arrivent en boîte de réception plutôt qu'en spam — ou pire, silencieusement rejetées.

Ce guide suppose que vous savez déjà administrer un serveur Linux et éditer une zone DNS. Il vous donne la recette d'une chaîne d'envoi direct (le serveur remet lui-même au destinataire, sans relais SMTP tiers), authentifiée par les trois piliers DKIM, SPF et DMARC.

Pour le pourquoi de ces trois piliers et de leur articulation, voir SPF, DKIM, DMARC : pourquoi la délivrabilité email est difficile.


Le principe en une image

Application
    │  (Mailer → remise locale : sendmail ou smtp://localhost)
    â–Ľ
Signeur DKIM (milter — signe chaque mail sortant, au niveau OS)
    │
    â–Ľ
Serveur SMTP (« Internet Site » — remise DIRECTE au MX destinataire)
    │
    â–Ľ
MX du destinataire  →  vérifie DKIM / SPF / DMARC

Trois choses portent la délivrabilité d'un mail émis directement par un serveur :

  • DKIM — une signature cryptographique posĂ©e par le serveur d'envoi, vĂ©rifiable via une clĂ© publique publiĂ©e en DNS. C'est le pilier principal quand l'IP Ă©mettrice n'est couverte par aucun SPF rĂ©putĂ©.
  • PTR (reverse DNS) — l'IP Ă©mettrice rĂ©sout vers un nom cohĂ©rent. Sans PTR propre, beaucoup de MX rejettent d'emblĂ©e.
  • SPF et DMARC — publiĂ©s en DNS, ils dĂ©clarent qui a le droit d'Ă©mettre pour votre domaine et quoi faire en cas d'Ă©chec.

Choix d'architecture — envoi direct, pas de relais. Faire remettre le serveur directement au MX destinataire évite de dépendre d'une boîte mail relais tierce, mais impose de bâtir soi-même la réputation d'envoi (d'où l'importance de DKIM + PTR). Vérifiez que la sortie SMTP (port 25 sortant) n'est pas bloquée par votre hébergeur avant de vous engager dans cette voie.


1. Configurer le serveur SMTP en envoi direct

Configurez votre MTA (ici Postfix) en mode « Internet Site » : il livre directement, n'écoute pas le réseau, et ne relaie que ce que l'application locale lui remet.

# /etc/postfix/main.cf (extrait)
myhostname   = <VOTRE_HOSTNAME>
mydomain     = <VOTRE_DOMAINE>
myorigin     = $mydomain
mydestination = localhost
inet_interfaces = loopback-only          # n'écoute que le loopback : pas de relais ouvert

# ── Envoi DIRECT : aucun relayhost, aucun credential SMTP tiers ──

# Brancher le signeur DKIM comme milter (signature avant remise)
milter_default_action = accept
smtpd_milters     = local:/run/opendkim/opendkim.sock
non_smtpd_milters = local:/run/opendkim/opendkim.sock

Points de sécurité :

  • inet_interfaces = loopback-only — le serveur n'accepte de mail que depuis la machine locale. Vous n'exposez pas un relais ouvert.
  • Pas de relayhost ni de sasl_passwd — aucun secret d'authentification SMTP tiers Ă  stocker, donc rien Ă  fuiter.

Piège fréquent — IPv6 blocklistée. Si l'IPv6 de votre serveur est mal réputée (courant sur les IP mutualisées), les MX destinataires renvoient des bounces 550. Forcez la préférence IPv4 (smtp_address_preference = ipv4) tant que vous n'avez pas une IPv6 avec PTR et réputation propres.


2. Signer en DKIM (au niveau OS, multi-domaines)

La signature se fait au niveau du système (via un milter comme OpenDKIM), pas dans l'application. Un signeur OS signe uniformément tout ce qui sort, gère plusieurs domaines avec des clés distinctes, et évite qu'une signature applicative codée en dur ne casse le multi-domaines.

2.1 Choisir un sélecteur

Un sélecteur est une étiquette (ex. votre_selecteur) qui relie une signature à un enregistrement DNS précis. La signature s=votre_selecteur n'est validée que si l'enregistrement DNS existe sous votre_selecteur._domainkey.<VOTRE_DOMAINE>.

Conseil : datez ou versionnez votre sélecteur (ex. mailAAAA) pour pouvoir faire tourner les clés sans casser l'existant.

2.2 Générer une paire de clés par domaine

# Génère clé privée + enregistrement TXT public pour un domaine
opendkim-genkey -b 2048 -s votre_selecteur -d <VOTRE_DOMAINE> -D /etc/opendkim/keys/<VOTRE_DOMAINE>

Protégez les clés privées : lecture réservée à l'utilisateur du signeur (chown opendkim:, chmod 600). Ne les commitez jamais en clair ; si vous les stockez dans de l'IaC, chiffrez-les (coffre / vault).

2.3 Déclarer qui signe quoi

Le signeur a besoin de deux tables — une ligne par domaine servi.

# signing.table : quel motif d'expéditeur → quelle identité de signature
*@<VOTRE_DOMAINE>   votre_selecteur._domainkey.<VOTRE_DOMAINE>

# key.table : quelle identité → quel sélecteur + quelle clé privée
votre_selecteur._domainkey.<VOTRE_DOMAINE>   <VOTRE_DOMAINE>:votre_selecteur:/etc/opendkim/keys/<VOTRE_DOMAINE>/votre_selecteur.private

Réglages de fond du démon : mode signature+vérification, canonicalisation relaxed/simple, socket local partagé avec le MTA, et un TrustedHosts limité au loopback.

2.4 Publier la clé publique en DNS

Un enregistrement TXT par domaine, sous le sélecteur :

votre_selecteur._domainkey.<VOTRE_DOMAINE>   TXT   "v=DKIM1; h=sha256; k=rsa; p=<VOTRE_CLE_PUBLIQUE>"

Prérequis absolu : tant que cet enregistrement n'est pas publié et propagé, la vérification renvoie dkim=fail. Publiez le DNS avant de mettre le signeur en production.


3. Publier SPF

Le SPF déclare quels serveurs ont le droit d'émettre pour votre domaine. Il dépend de l'hébergeur mail du domaine, pas du serveur d'envoi direct.

# Domaine dont la messagerie est hébergée par un fournisseur : incluez son mécanisme SPF
<VOTRE_DOMAINE>   TXT   "v=spf1 include:<spf.votre_fournisseur> -all"

Important : pour les mails émis directement par votre serveur (notifications applicatives), l'IP du serveur n'est généralement pas dans le SPF du domaine. C'est normal — dans ce cas la délivrabilité repose sur DKIM + PTR + DMARC, pas sur SPF. Ajouter l'IP au SPF est une option, mais élargit la surface et complique la rotation d'IP.

Terminaison : -all (rejet strict) une fois sûr de votre inventaire d'émetteurs ; ~all (softfail) pendant la phase de rodage.


4. Publier DMARC

DMARC dit aux MX destinataires quoi faire quand DKIM et SPF échouent, et où vous envoyer les rapports.

_dmarc.<VOTRE_DOMAINE>   TXT   "v=DMARC1; p=quarantine; rua=mailto:dmarc@<VOTRE_DOMAINE>; pct=100"

Déploiement progressif recommandé :

  1. p=none — mode observation : vous recevez les rapports sans impact sur la remise.
  2. p=quarantine — les mails non authentifiés partent en spam.
  3. p=reject — rejet pur, une fois DKIM/SPF stabilisés et les rapports propres.

5. Piège classique — le socket entre MTA et signeur

Le milter DKIM communique avec le MTA via un socket local. Le MTA doit pouvoir le lire, sinon les mails partent non signés (dkim=none) ou le MTA refuse de démarrer (milter: can't connect).

# Répertoire du socket : propriétaire = signeur, groupe = MTA
sudo install -d -o opendkim -g postfix -m 750 /run/opendkim

# Autoriser l'utilisateur du MTA Ă  lire le socket du signeur
sudo adduser postfix opendkim

6. Vérifier

# 1. La clé publique est-elle bien publiée et propagée ?
dig +short TXT votre_selecteur._domainkey.<VOTRE_DOMAINE>

# 2. SPF et DMARC publiés ?
dig +short TXT <VOTRE_DOMAINE>
dig +short TXT _dmarc.<VOTRE_DOMAINE>

# 3. Envoi de test : inspectez les headers reçus
echo "Test" | mail -s "test auth" vous@exemple.test

Dans le mail reçu, cherchez l'en-tête Authentication-Results. Vous visez :

Authentication-Results: ...; dkim=pass; spf=pass; dmarc=pass
  • dkim=none → le milter n'a pas signĂ© : revoyez le socket (§5) et les tables (§2.3).
  • dkim=fail → clĂ© DNS absente, mauvaise ou non propagĂ©e (§2.4).
  • dmarc=fail avec p=reject → le mail sera rejetĂ© ; repassez en p=none le temps de corriger.

Un service de test « mail-tester » externe ou l'inspection manuelle des headers suffisent à valider la chaîne bout en bout.


Côté application

Pointez simplement le Mailer sur la remise locale — aucune signature DKIM applicative (elle est faite par l'OS) :

MAILER_DSN=sendmail://default
# ou
MAILER_DSN=smtp://localhost:25

Checklist de mise en production

  • Sortie SMTP (port 25) non bloquĂ©e par l'hĂ©bergeur, PTR de l'IP cohĂ©rent
  • MTA en « Internet Site », inet_interfaces = loopback-only, pas de relayhost
  • Une paire de clĂ©s DKIM par domaine, clĂ©s privĂ©es en 600 et non commitĂ©es en clair
  • Enregistrements DKIM, SPF, DMARC publiĂ©s et propagĂ©s
  • Socket MTA ↔ signeur lisible (test : dkim=pass sur un mail rĂ©el)
  • DMARC dĂ©marrĂ© en p=none, durci vers quarantine/reject après observation

Assistant documentaire

Posez une question sur la documentation. Les réponses citent leurs sources — un clic ouvre le document à gauche.