03-comment-je-travaille/vps/07-email-delivrabilite.md

Email transactionnel & délivrabilité — Postfix, DKIM, SPF, DMARC

Ce document répond à : "Comment Telaria fait-il pour envoyer des mails sans tomber en spam ?" La délivrabilité repose sur quatre dispositifs complémentaires : SPF, DKIM, DMARC et un relais SMTP de confiance (OVH).


1. Pourquoi les emails tombent en spam

Un email peut être classé spam pour deux raisons principales :

  1. Réputation IP : l'IP du VPS est inconnue des fournisseurs d'email. Un VPS OVH envoyant directement a une réputation nulle à zéro, voire négative (les plages IP des hébergeurs sont souvent pré-classées suspectes).
  2. Authentification manquante : sans SPF, DKIM ou DMARC, le serveur destinataire ne peut pas vérifier que l'email vient bien du domaine qu'il prétend représenter.

Solution adoptée par Telaria

Application Symfony
    │  smtp://localhost
    â–Ľ
Postfix (satellite — ne gère que l'envoi sortant)
    │  Signe l'email avec OpenDKIM (DKIM)
    â–Ľ
OVH SMTP (relais — sa réputation IP est établie)
    │
    â–Ľ
Serveur destinataire (vérifie SPF + DKIM + DMARC)

Telaria ne gère pas la réputation IP — il délègue l'envoi à OVH, qui a une réputation établie. Ce que Telaria gère : l'authentification cryptographique (DKIM) et les politiques DNS (SPF, DMARC).


2. SPF — autoriser les serveurs légitimes

SPF (Sender Policy Framework) liste dans le DNS quels serveurs sont autorisés à envoyer des emails au nom du domaine.

Enregistrement DNS TXT Ă  publier chez OVH :

telaria.dev  IN  TXT  "v=spf1 include:mx.ovh.com ~all"
Directive Signification
include:mx.ovh.com Les serveurs OVH sont autorisés
~all Tout autre serveur = "softfail" (suspect, pas forcément rejeté)
-all Tout autre serveur = "fail" (rejeté — utiliser seulement si on est sûr)

3. DKIM — signature cryptographique des emails

DKIM (DomainKeys Identified Mail) ajoute une signature numérique à chaque email. Le serveur destinataire vérifie la signature avec la clé publique publiée en DNS. Si la signature est valide, l'email n'a pas été altéré en transit.

OpenDKIM — installation

sudo apt install -y opendkim opendkim-tools

Configuration OpenDKIM (/etc/opendkim.conf)

Mode                    sv
Syslog                  yes
SyslogSuccess           yes
LogWhy                  yes

# Socket dans le chroot Postfix (voir §5 — piège critique)
Socket                  local:/var/spool/postfix/opendkim/opendkim.sock

UserID                  opendkim
UMask                   007

# Multi-NDD : chaque domaine a sa propre clé
KeyTable                /etc/opendkim/key.table
SigningTable            refile:/etc/opendkim/signing.table
ExternalIgnoreList      refile:/etc/opendkim/trusted.hosts
InternalHosts           refile:/etc/opendkim/trusted.hosts

Signing table — qui signe quoi

/etc/opendkim/signing.table :

*@telaria.dev       telaria._domainkey.telaria.dev
*@adoption.fr       adoption._domainkey.adoption.fr

Tout email avec From: *@telaria.dev sera signé avec la clé telaria._domainkey.telaria.dev.

Key table — clés par domaine

/etc/opendkim/key.table :

telaria._domainkey.telaria.dev    telaria.dev:telaria:/etc/opendkim/keys/telaria.dev/telaria.private
adoption._domainkey.adoption.fr   adoption.fr:adoption:/etc/opendkim/keys/adoption.fr/adoption.private

Format : sélecteur._domainkey.domaine domaine:sélecteur:chemin_clé_privée

Trusted hosts

/etc/opendkim/trusted.hosts :

127.0.0.1
localhost
::1
telaria.dev
adoption.fr

Génération des clés

# Pour chaque domaine
sudo mkdir -p /etc/opendkim/keys/telaria.dev
cd /etc/opendkim/keys/telaria.dev
sudo opendkim-genkey -s telaria -d telaria.dev -b 2048
sudo chown opendkim:opendkim telaria.private
sudo chmod 600 telaria.private

# telaria.txt contient l'enregistrement DNS Ă  publier
cat telaria.txt

Contenu de telaria.txt (Ă  copier en enregistrement DNS TXT) :

telaria._domainkey  IN  TXT  "v=DKIM1; h=sha256; k=rsa; p=MIIBIjAN..."

4. DMARC — politique d'authentification

DMARC (Domain-based Message Authentication, Reporting and Conformance) indique aux serveurs destinataires quoi faire si SPF ou DKIM échouent, et envoie des rapports de délivrabilité.

_dmarc.telaria.dev  IN  TXT  "v=DMARC1; p=quarantine; pct=100; rua=mailto:dmarc@telaria.dev"
Directive Signification
p=quarantine Email suspect → dossier spam (pas rejeté)
p=reject Email suspect → rejeté (plus strict — activer après validation)
pct=100 Appliquer Ă  100% des emails
rua= Adresse qui reçoit les rapports agrégés (journaliers)

5. Reverse DNS (PTR) — réputation IP

Le Reverse DNS (ou enregistrement PTR) est souvent oublié mais crucial pour la délivrabilité. Il associe l'IP du serveur à un nom de domaine. Les serveurs destinataires vérifient que l'IP d'envoi correspond bien au domaine déclaré.

Sans PTR : l'IP du VPS est "anonyme". Gmail, Outlook, et la majorité des FAI marquent automatiquement ces emails comme suspects.

Configuration OVH

Le PTR se configure dans l'interface OVH, pas dans le DNS du domaine :

  1. Espace Client OVH → Bare Metal Cloud → IP
  2. Cliquer sur l'IP du VPS → "Modifier le reverse"
  3. Entrer : telaria.dev (sans point final)

OVH propage le PTR en quelques minutes.

Vérification

# Remplacer 1.2.3.4 par l'IP du VPS
dig -x 1.2.3.4 +short
# Doit retourner : telaria.dev.

6. Postfix — configuration satellite

Postfix en mode satellite : il n'accepte pas d'emails entrants, il relaie uniquement les emails sortants vers OVH.

Installation

sudo apt install -y postfix libsasl2-modules
# À l'installation : choisir "Satellite system" et entrer le nom du domaine

/etc/postfix/main.cf (configuration complète)

# Identité
myhostname = telaria.dev
mydomain   = telaria.dev
myorigin   = $mydomain

# Mode satellite : aucune livraison locale
mydestination =
local_transport = error: local delivery disabled

# Relais OVH (port 465, TLS wrapper mode)
relayhost = [ssl0.ovh.net]:465

# Authentification SASL vers OVH
smtp_sasl_auth_enable       = yes
smtp_sasl_password_maps     = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options  = noanonymous

# TLS obligatoire (connexion chiffrée vers OVH)
smtp_tls_security_level  = encrypt
smtp_tls_wrappermode     = yes   # port 465 = TLS d'emblée (pas STARTTLS)
smtp_tls_CAfile          = /etc/ssl/certs/ca-certificates.crt

# Milter OpenDKIM (signature avant envoi)
milter_default_action = accept
milter_protocol       = 6
smtpd_milters         = unix:/var/spool/postfix/opendkim/opendkim.sock
non_smtpd_milters     = unix:/var/spool/postfix/opendkim/opendkim.sock

Credentials OVH (/etc/postfix/sasl_passwd)

[ssl0.ovh.net]:465  login_ovh@telaria.dev:mot_de_passe_smtp
sudo postmap /etc/postfix/sasl_passwd   # compiler en hash db
sudo chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
sudo systemctl restart postfix

6.bis ⚠️ Piège critique — socket OpenDKIM dans le chroot Postfix

C'est le piège le plus courant lors de l'installation OpenDKIM + Postfix.

Le problème : Postfix tourne dans un chroot (/var/spool/postfix/). Le socket UNIX d'OpenDKIM doit être dans ce chroot pour que Postfix puisse y accéder. Si le socket est en dehors (/var/run/opendkim/), Postfix ne peut pas s'y connecter.

Symptôme : emails envoyés sans signature DKIM (dkim=none dans les headers reçus), ou Postfix refuse de démarrer (milter connect to ... No such file or directory).

Solution :

# Créer le répertoire socket dans le chroot Postfix
sudo mkdir -p /var/spool/postfix/opendkim
sudo chown opendkim:postfix /var/spool/postfix/opendkim
sudo chmod 750 /var/spool/postfix/opendkim

# Ajouter opendkim au groupe postfix (pour que postfix lise le socket)
sudo usermod -aG postfix opendkim
# ET ajouter postfix au groupe opendkim
sudo usermod -aG opendkim postfix

sudo systemctl restart opendkim postfix

Vérifier que le socket est créé :

ls -la /var/spool/postfix/opendkim/
# srwxrwx--- 1 opendkim postfix ... opendkim.sock

7. Symfony Mailer — configuration

# .env.local
MAILER_DSN=smtp://localhost:25
# OU
MAILER_DSN=sendmail://default

L'application Symfony envoie au Postfix local (port 25, non chiffré localement — la liaison localhost ne sort pas sur le réseau). Postfix prend en charge le chiffrement vers OVH.


8. Vérification de la délivrabilité

# Envoyer un email de test
echo "Test DKIM" | mail -s "Test délivrabilité" test@example.com

# Vérifier les logs Postfix
sudo tail -f /var/log/mail.log
# Chercher : "status=sent" et "250 2.0.0 Ok: queued"

# Vérifier les headers reçus (dans le client mail)
# Authentication-Results: dkim=pass; spf=pass; dmarc=pass

Tests externes :

Outil Usage
check-auth@verifier.port25.com Envoyer un email → réponse automatique avec résultat SPF/DKIM/DMARC
mail-tester.com Score /10, détail par critère (recommandé : score 9+)
mxtoolbox.com/blacklists.aspx Vérifier si l'IP est sur une blacklist

Vérification DNS :

dig TXT telaria._domainkey.telaria.dev   # DKIM public key
dig TXT _dmarc.telaria.dev               # DMARC policy
dig TXT telaria.dev | grep spf           # SPF record
dig -x $(curl -s ifconfig.me) +short     # PTR reverse DNS

Si IP blacklistée : chaque liste a sa procédure de délistage. Consulter mxtoolbox pour identifier laquelle, puis demander le retrait via leur formulaire. En dernier recours : relais SMTP externe (Brevo, Mailjet, SendGrid).


Étape suivante : 08-application.md

Assistant documentaire

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

Loading…
Loading the web debug toolbar…
Attempt #