E-mail : DKIM échoue — pourquoi la signature se casse (et comment réparer rapidement)

Cet article vous a aidé ?

Vous avez envoyé le message. Les clients ne l’ont pas reçu. Ou pire : il a atterri dans les courriers indésirables avec un poli mais fatal « DKIM=fail » en évidence. L’équipe marketing pense que la « propagation DNS » est une météo et demande si vous pouvez « juste le renvoyer ».

C’est le moment d’arrêter de deviner. DKIM n’est pas capricieux. Il est strict. La signature casse parce que quelque chose a changé entre la signature et la vérification, ou parce que les vérificateurs ne peuvent pas récupérer la clé, ou parce que vous avez signé la mauvaise chose dès le départ. La bonne nouvelle : c’est généralement réparable en moins d’une heure si vous suivez un triage discipliné.

DKIM en termes simples (ce qui est réellement signé)

DKIM (DomainKeys Identified Mail) n’est pas une « chiffrement », et ce n’est pas une « preuve que l’expéditeur est digne de confiance ». C’est une somme de contrôle cryptographique sur des en-têtes sélectionnés et (généralement) le corps du message, signée avec une clé privée détenue par le domaine expéditeur. Le récepteur récupère la clé publique depuis le DNS et vérifie la signature. Si les octets signés ne correspondent pas à ce qui arrive, la vérification échoue. Si la clé publique ne peut pas être récupérée, la vérification échoue. Si le récepteur ne peut pas parser la signature, la vérification échoue.

Dans un en-tête de signature DKIM (DKIM-Signature:), vous verrez des champs comme :

  • d= le domaine signataire (le domaine « responsable » pour DKIM)
  • s= le sélecteur (utilisé pour trouver la clé dans le DNS)
  • h= quels en-têtes sont signés
  • bh= hash du corps (base64 du hash canoniquement calculé du corps)
  • b= la signature réelle sur les en-têtes + hash du corps
  • c= canonicalisation (comment l’espace blanc / le pliage de lignes est normalisé)
  • t=/x= horodatage / expiration

Voici le point opérationnel clé : DKIM valide une représentation précise du message. Si un relais, une passerelle, un injecteur de pied de page, un gestionnaire de liste, un « appliance » de sécurité ou un service cloud utile modifie les en-têtes signés ou le corps d’une manière non tolérée par la canonicalisation, la signature casse. Ce n’est pas un bug DKIM. C’est DKIM qui fait son travail.

Deux modes de canonicalisation, misère infinie

La canonicalisation contrôle la façon dont le signataire et le vérificateur normalisent le contenu avant le hachage et la vérification. Vous verrez :

  • simple : peu ou pas de normalisation. Fragile. Parfait pour les amateurs de pages d’astreinte.
  • relaxed : tolère certains changements d’espace blanc et de formatage d’en-tête. Souvent le bon choix.

Les valeurs par défaut communes et sensées sont c=relaxed/relaxed (en-têtes/corps relaxés) ou relaxed/simple dans certains systèmes. Si vous utilisez simple/simple sur un chemin de mail complexe, vous signez essentiellement un château de sable et vous l’envoyez dans une station de lavage automobile.

La promesse réelle de DKIM

DKIM répond à la question : « Un domaine qui contrôle cette clé privée DKIM a-t-il signé ce message, et les parties signées sont‑elles arrivées inchangées ? » Il ne répond pas à la question : « L’adresse From est-elle authentique ? » C’est la tâche de DMARC, qui utilise SPF et DKIM plus des règles d’alignement. DKIM est un élément d’un ensemble plus large de contrôles à la porte.

Faits intéressants et courte histoire (parce que le mail est plus vieux que votre pipeline CI)

  • Fait 1 : DKIM a été normalisé en 2007 (RFC 4871), fusionnant des idées de DomainKeys de Yahoo et d’Identified Internet Mail de Cisco.
  • Fait 2 : Les signatures DKIM sont évaluées après les changements de transport ; même une « injection » de pied de page « inoffensive » peut invalider un hash de corps.
  • Fait 3 : Les premières déploiements utilisaient largement des clés RSA 1024 bits ; de nombreux récepteurs préfèrent ou exigent maintenant des clés 2048 bits pour une sécurité renforcée.
  • Fait 4 : Les limites de taille des enregistrements TXT DNS et la fragmentation ont historiquement causé des échecs intermittents de récupération de clé, surtout avec des clés surdimensionnées ou des configurations DNS négligées.
  • Fait 5 : DKIM ne peut signer qu’un sous‑ensemble d’en‑têtes ; le choix est un compromis entre intégrité et survie à travers les relais.
  • Fait 6 : Les listes de diffusion sont célèbres pour casser DKIM : elles modifient Subject, ajoutent des en‑têtes de liste et ajoutent des pieds de page — exactement ce que DKIM a tendance à couvrir.
  • Fait 7 : ARC (Authenticated Received Chain) a été introduit plus tard pour préserver les résultats d’authentification à travers les transferts et les listes, parce que DKIM seul casse souvent en aval.
  • Fait 8 : Certains MTA réécrivaient historiquement les fins de ligne ou le « dot-stuffing » différemment ; la canonicalisation existe en partie pour survivre à ce chaos.
  • Fait 9 : Plusieurs signatures DKIM peuvent coexister ; les systèmes récepteurs acceptent typiquement le message si n’importe quelle signature valide satisfait la politique (surtout pour l’alignement DMARC).

Comment DKIM casse : les modes de défaillance qui comptent

1) Le DNS ne peut pas servir la clé (ou sert la mauvaise)

Les récepteurs vérifient DKIM en interrogeant un enregistrement DNS à :

<selector>._domainkey.<domain>

Si cet enregistrement est manquant, mal formé, mal fragmenté, trop volumineux pour votre chemin DNS, ou mis en cache dans un état obsolète pendant une rotation, vous obtenez des échecs DKIM qui semblent aléatoires — parce qu’ils le sont, selon les résolveurs.

2) Le message a été modifié après la signature

C’est le classique : le message est signé, puis un relais le modifie. Coupables courants :

  • Ajout d’un pied de page de non-responsabilité (légal, RH ou bannière « confidentiel »)
  • Réécriture des lignes Subject (préfixe « EXTERNAL »)
  • Modification des frontières MIME ou ré-encodage du contenu
  • Normalisation d’espace blanc d’une manière non couverte par la canonicalisation
  • Scanners antivirus ou passerelles DLP réassemblant des pièces jointes

3) Vous avez signé les mauvais en-têtes (ou trop)

Signer des en-têtes instables est une blessure auto-infligée. Des en‑têtes comme Received changent à chaque saut, donc les signer est inutile sauf si vous aimez l’échec. Certains systèmes ajoutent ou réécrivent aussi Message-ID, Date, ou même From d’une façon inattendue. Choisissez des en‑têtes qui représentent l’identité et le contenu mais restent stables après l’exécution du signataire.

4) Votre domaine de signature n’est pas aligné avec DMARC

Vous pouvez avoir une signature DKIM valide et quand même échouer DMARC si le d= ne s’aligne pas avec le domaine visible From: selon la politique DMARC (alignement strict ou relaxé). Cela apparaît souvent comme « DKIM=pass » mais « DMARC=fail », ce que les parties prenantes interprètent comme « Le mail est cassé ». Compréhensible.

5) Temps, expiration et protections de rejeu

Certaines signatures DKIM incluent x= (expiration). Si vos horloges dérapent ou si vos messages restent en file trop longtemps (bonjour, backpressure), les signatures peuvent expirer avant la livraison. C’est moins fréquent mais extrêmement énervant parce que tout « a l’air correct » sauf le temps.

6) Rotation de sélecteur/clé faite comme un hobby du week-end

Faire tourner les clés DKIM est normal. Les faire tourner sans chevauchement est comment vous créez un incident de deux jours. Les caches DNS, les MTA multi‑régionaux et les files longues signifient que les anciens sélecteurs peuvent encore être utilisés un moment. Supprimer l’enregistrement trop tôt et la vérification échoue pour les mails retardés.

Blague courte #1 : DKIM est comme un sceau anti‑manipulation. Si vous continuez d’ouvrir le bocal pour « l’améliorer », ne soyez pas surpris quand le sceau hurle.

Playbook de diagnostic rapide (premier/deuxième/troisième)

Voici la séquence qui identifie le goulot le plus vite dans des environnements réels. Ne commencez pas par modifier les configs. Commencez par regarder ce que les récepteurs ont vu.

Premier : confirmer ce qui a échoué (DNS vs hash du corps vs parse d’en-tête)

  1. Récupérez un vrai message échoué (sources originales telles que reçues). Pas une capture d’écran. Pas un forward. La source brute.
  2. Lisez l’en‑tête Authentication-Results du récepteur. Il indique souvent exactement ce qui a cassé : « no key », « body hash mismatch », « bad signature », « invalid header format ».
  3. Vérifiez les champs de DKIM-Signature : d=, s=, c=, h=, bh=, x=.

Deuxième : vérifier le DNS depuis plusieurs points de vue

  1. Interrogez l’enregistrement du sélecteur en utilisant un résolveur connu.
  2. Interrogez en utilisant votre résolveur système (pour attraper le split‑horizon ou les bizarreries DNS d’entreprise).
  3. Vérifiez que l’enregistrement est syntaxiquement valide et complet (pas de guillemets cassés, fragments manquants).

Troisième : isoler où le message est modifié

  1. Comparez le message au moment de la signature vs à la livraison (si vous pouvez capturer les deux).
  2. Cherchez les systèmes intermédiaires qui réécrivent le contenu : passerelles sortantes, sécurité mail, plateformes CRM, gestionnaires de listes.
  3. Envoyez un test contrôlé : même expéditeur, même destinataire, mais en contournant les composants optionnels (si possible) pour trouver le saut qui modifie.

Quatrième : réparer la plus petite chose qui restaure le pass

Résistez à l’envie de « ré-architecturer les e-mails ». Restaurez d’abord la délivrabilité, puis durcissez la chaîne. En pratique, cela signifie souvent :

  • Corriger l’enregistrement clé DNS ou l’utilisation du sélecteur
  • Basculer la canonicalisation sur relaxed
  • Arrêter la modification du corps après la signature (déplacer la signature au dernier saut)
  • Ajuster les en‑têtes signés
  • Aligner d= avec le domaine From pour DMARC

Tâches pratiques : commandes, sorties et décisions (12+)

Ce sont des tâches réelles que vous pouvez exécuter sur un hôte mail ou une machine d’investigation. Chaque tâche inclut : commande, ce que signifie la sortie, et la décision à prendre. Je suppose un environnement Linux avec des outils typiques. Ajustez les chemins pour votre distribution.

Task 1: Extract Authentication-Results and DKIM-Signature from a saved message

cr0x@server:~$ awk 'BEGIN{RS="";FS="\n"} {for(i=1;i<=NF;i++) if($i ~ /^Authentication-Results:/ || $i ~ /^DKIM-Signature:/) print $i}' failed.eml
Authentication-Results: mx.example.net; dkim=fail (body hash did not verify) header.d=example.com header.s=s2025 header.b=Qn...
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=s2025; h=from:to:subject:date:mime-version:content-type; bh=3l8...; b=Qn...

Signification : Vous avez déjà la classe d’échec : body hash mismatch. Ce n’est pas « DNS manquant », ni « mauvaise clé », ni « signature expirée ». Quelque chose a changé dans le corps après la signature.

Décision : Arrêtez de regarder le DNS. Trouvez ce qui modifie le corps (pieds de page, ré-encodage, réécriture par passerelle), ou déplacez la signature plus tard dans la chaîne.

Task 2: Check the DKIM public key record exists (dig)

cr0x@server:~$ dig +short TXT s2025._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtY..."

Signification : Un enregistrement TXT existe et renvoie une charge utile qui ressemble à du DKIM.

Décision : Si DKIM échoue encore avec « no key », suspectez la visibilité DNS (split‑horizon), des échecs DNSSEC, ou la fragmentation/formatage de l’enregistrement sur certains résolveurs.

Task 3: Check the same DKIM record via a specific resolver (catch split-horizon)

cr0x@server:~$ dig @1.1.1.1 +short TXT s2025._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtY..."

Signification : Les résolveurs publics sont d’accord. Si votre résolveur interne renvoie autre chose, vous avez du split DNS ou des caches obsolètes.

Décision : Si les résultats diffèrent, corrigez le DNS faisant autorité d’abord. Les récepteurs d’e‑mail n’utilisent pas votre vue interne de la réalité.

Task 4: Detect malformed multi-string DKIM TXT records

cr0x@server:~$ dig TXT s2025._domainkey.example.com +noall +answer
s2025._domainkey.example.com. 300 IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkq..." "G9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtY..."

Signification : Certains fournisseurs DNS scindent les longs enregistrements TXT en plusieurs chaînes. C’est correct si c’est fait proprement ; les résolveurs concatènent. Mais des erreurs de guillemets peuvent casser silencieusement les clés.

Décision : Si vous voyez une ponctuation étrange, des guillemets manquants ou des segments tronqués, régénérez et republiez l’enregistrement. Ne modifiez pas manuellement un base64 dans un navigateur à 2 h du matin.

Task 5: Verify OpenDKIM sees the key and selector mapping

cr0x@server:~$ sudo opendkim-testkey -d example.com -s s2025 -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 's2025._domainkey.example.com'
opendkim-testkey: key OK

Signification : L’enregistrement DNS de clé est joignable et correspond à ce qu’OpenDKIM attend.

Décision : Si cela échoue, corrigez d’abord le DNS/le sélecteur. S’il passe mais que les récepteurs échouent, suspectez le flux mail ou la modification du message.

Task 6: Confirm the signer is actually signing (mail logs)

cr0x@server:~$ sudo grep -E "opendkim|DKIM-Signature" /var/log/mail.log | tail -n 5
Jan 03 10:14:22 mailgw opendkim[1423]: 6F2C12A0B1: DKIM-Signature field added (s=s2025, d=example.com)
Jan 03 10:14:23 mailgw postfix/qmgr[1111]: 6F2C12A0B1: from=, size=48213, nrcpt=1 (queue active)

Signification : OpenDKIM a injecté une signature pour cet ID de message.

Décision : Si vous ne voyez pas de signature, vérifiez le câblage du milter, les permissions de socket, ou un chemin de contournement qui saute le milter.

Task 7: Confirm Postfix is wired to the DKIM milter

cr0x@server:~$ sudo postconf | egrep 'smtpd_milters|non_smtpd_milters|milter_default_action|milter_protocol'
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = inet:127.0.0.1:8891
milter_default_action = accept
milter_protocol = 6

Signification : Le courrier reçu via SMTP et le courrier généré localement passent par le milter DKIM. Si seul smtpd_milters est défini, le courrier injecté localement peut ne pas être signé.

Décision : Si non_smtpd_milters est vide et que vous générez du mail localement (cron, applications), ajoutez‑le. Le courrier non signé est fréquemment traité comme suspect une fois DMARC strict activé.

Task 8: Validate the message body wasn’t rewritten by a gateway (compare hashes via OpenDKIM tools)

cr0x@server:~$ sudo opendkim-testmsg -v < failed.eml
opendkim-testmsg: dkim_eom(): verification failed: body hash did not verify

Signification : Le message stocké (tel que reçu) ne correspond pas au hash du corps signé.

Décision : Identifiez le saut qui a modifié le corps. Si vous contrôlez une passerelle en aval qui injecte des pieds de page, déplacez la signature après elle ou empêchez‑la de toucher le courrier signé.

Task 9: Find which headers you signed (and whether you signed unstable ones)

cr0x@server:~$ grep -i '^DKIM-Signature:' -m 1 failed.eml | sed 's/; /\n/g' | egrep '^(h=|c=|d=|s=)'
c=relaxed/relaxed
d=example.com
s=s2025
h=from:to:subject:date:mime-version:content-type

Signification : Vous avez signé un ensemble d’en‑têtes assez standard. Bien. Si vous voyez h=...:received:... ou d’autres en‑têtes qui mutent au fil des sauts, vous êtes coupable.

Décision : Si des en‑têtes instables sont signées, ajustez la configuration du signataire pour signer un ensemble stable.

Task 10: Detect line-ending or MIME transformations (spot the classic “gateway rewrap”)

cr0x@server:~$ python3 - <<'PY'
import sys, email
from email import policy
msg = email.message_from_binary_file(open("failed.eml","rb"), policy=policy.default)
print("Content-Type:", msg.get_content_type())
print("Has multipart:", msg.is_multipart())
print("Transfer-Encoding:", msg.get("Content-Transfer-Encoding"))
PY
Content-Type: multipart/alternative
Has multipart: True
Transfer-Encoding: None

Signification : Un e‑mail multipart est plus susceptible d’être « utilement » réécrit par des produits de sécurité. Pas toujours, mais c’est un lieu fréquent du crime.

Décision : Si vous avez une passerelle DLP/AV, vérifiez si elle ré-encode des parties ou normalise les frontières MIME. Si oui, signez après cette étape.

Task 11: Verify DMARC alignment clues (Authentication-Results parsing)

cr0x@server:~$ grep -i '^Authentication-Results:' -m 1 failed.eml
Authentication-Results: mx.example.net; spf=pass smtp.mailfrom=bounces.vendor-mail.net; dkim=pass header.d=vendor-mail.net; dmarc=fail header.from=example.com

Signification : SPF a réussi pour le domaine fournisseur, DKIM a réussi pour le domaine fournisseur, mais DMARC a échoué parce que le From visible est example.com et ni SPF ni DKIM ne s’alignent avec ce domaine.

Décision : Forcez le fournisseur à signer avec d=example.com (votre domaine) et alignez SPF via un domaine de rebond personnalisé, ou acceptez que DMARC échouera et que la délivrabilité sera affectée sous des politiques strictes.

Task 12: Check for multiple DKIM signatures and decide which one matters

cr0x@server:~$ grep -i '^DKIM-Signature:' failed.eml | wc -l
2

Signification : Deux signatures existent. Souvent l’une est ajoutée par votre système, une autre par un service en amont. Les récepteurs peuvent valider l’une et ignorer l’autre selon l’alignement et la politique.

Décision : Assurez‑vous qu’au moins une signature valide s’aligne avec le domaine From pour DMARC. Si la signature alignée échoue, vous avez toujours un problème même si une autre passe.

Task 13: Confirm the selector in outbound mail matches your published record

cr0x@server:~$ grep -i '^DKIM-Signature:' -m 1 failed.eml | tr ';' '\n' | grep -E '^\s*s='
 s=s2025

Signification : Le message a utilisé le sélecteur s2025. Si le DNS n’a que s2024, vous avez trouvé le décalage.

Décision : Publiez soit le record s2025 immédiatement (et conservez‑le), soit revenez à la configuration du signataire pour utiliser le sélecteur publié. Ne « attendez pas la propagation » si l’enregistrement n’existe tout simplement pas.

Task 14: Check OpenDKIM key table/signing table mappings (common misroute)

cr0x@server:~$ sudo egrep -v '^\s*(#|$)' /etc/opendkim/SigningTable /etc/opendkim/KeyTable
/etc/opendkim/SigningTable:*@example.com s2025._domainkey.example.com
/etc/opendkim/KeyTable:s2025._domainkey.example.com example.com:s2025:/etc/opendkim/keys/example.com/s2025.private

Signification : SigningTable mappe les expéditeurs à un nom de clé ; KeyTable mappe ce nom à un domaine/sélecteur/chemin de clé privée.

Décision : Si le mail de noreply@sub.example.com n’est pas couvert par votre wildcard, vous ne signez peut‑être pas involontairement. Corrigez les motifs de table pour correspondre aux adresses From/expéditeur réelles.

Task 15: Validate that your private key file is readable by the signing service

cr0x@server:~$ sudo -u opendkim test -r /etc/opendkim/keys/example.com/s2025.private && echo "readable"
readable

Signification : L’utilisateur OpenDKIM peut lire la clé. Sinon, OpenDKIM peut échouer silencieusement à signer ou journaliser des erreurs confuses.

Décision : Corrigez la propriété/les permissions. Si vous « résolvez » le problème en rendant la clé lisible par tous, annulez cela et faites‑le proprement.

Task 16: Check for queue delays that can trigger signature expiry

cr0x@server:~$ mailq | head -n 20
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
6F2C12A0B1     48213 Fri Jan  3 10:14:23  noreply@example.com
                                         user@recipient.net

-- 48 Kbytes in 1 Request.

Signification : Si vous voyez des heures/jours de backlog et que vos signatures expirent (x=), la vérification peut échouer malgré une configuration correcte.

Décision : Réduisez le temps en file, évitez l’expiration DKIM sauf raison majeure, et corrigez le goulot de livraison (limites de débit, problèmes DNS, IP bloquées).

Erreurs courantes : symptôme → cause racine → fix

Cette section est volontairement directe. La plupart des problèmes DKIM sont ennuyeux. L’astuce est de reconnaître la forme rapidement.

1) « dkim=fail (no key for signature) »

  • Symptôme : Authentication-Results indique no key, ou « key not found ».
  • Cause racine : Enregistrement TXT du sélecteur manquant, mauvais sélecteur (s=) dans le mail sortant, split DNS, ou formatage TXT cassé.
  • Fix : Publiez correctement <s>._domainkey.<d> en TXT ; confirmez avec dig contre des résolveurs publics ; assurez‑vous que le signataire utilise ce sélecteur.

2) « dkim=fail (body hash did not verify) »

  • Symptôme : DKIM échoue ; souvent intermittent selon le destinataire ou le chemin.
  • Cause racine : Le corps du message a été modifié après la signature : clause de non‑responsabilité, pied de page, réécriture par filtre de contenu, ré‑encodage, changements d’enveloppements de lignes non tolérés.
  • Fix : Déplacez la signature au dernier système avant l’Internet ; désactivez les modifications post‑signature ; utilisez la canonicalisation relaxed ; évitez d’ajouter du contenu après la signature.

3) « dkim=fail (signature did not verify) » avec clé présente

  • Symptôme : La clé existe, mais la signature échoue même si le corps semble intact.
  • Cause racine : Mauvaise clé publiée pour le sélecteur (décalage de rotation), clé privée corrompue, signature avec un domaine/sélecteur différent de celui attendu, ou mismatch de canonicalisation dans certaines implémentations.
  • Fix : Validez que le signataire utilise le même sélecteur/clé que le DNS ; chevauchez les anciens/nouveaux sélecteurs pendant la rotation ; régénérez les clés si corruption suspectée.

4) DKIM passe, DMARC échoue

  • Symptôme : dkim=pass mais dmarc=fail.
  • Cause racine : DKIM a signé avec un d= qui ne s’aligne pas avec le domaine visible From, ou SPF a réussi pour un domaine différent.
  • Fix : Assurez‑vous qu’au moins une signature DKIM s’aligne avec le domaine From ; configurez les fournisseurs pour signer avec votre domaine personnalisé ; validez le mode d’alignement DMARC (relaxed vs strict).

5) DKIM échoue uniquement pour les listes de diffusion / transferts

  • Symptôme : Le mail direct passe ; le mail transféré/listé échoue.
  • Cause racine : Les listes ajoutent des pieds de page/tags sujet ; les forwarders re‑wrappent le contenu ; le rewriting du From (ou non) interagit avec DMARC. DKIM se casse en transit.
  • Fix : Préférez ARC sur les forwarders/listes ; minimisez les modifications ; envisagez un comportement compatible DMARC pour les listes ; signez au dernier saut que vous contrôlez.

6) DKIM échoue uniquement pour les gros e-mails ou certains destinataires

  • Symptôme : Les grandes newsletters échouent, les alertes petites passent.
  • Cause racine : Transformations MIME, ré-encodage par passerelle, ou problèmes DNS sur des résolveurs qui gèrent mal les TXT volumineux/fragmentés ; parfois problème MTU/EDNS.
  • Fix : Gardez les enregistrements DKIM propres ; testez le DNS via plusieurs résolveurs ; évitez les composants du chemin mail qui rewrapent le HTML ; vérifiez que votre ESP n’« optimise » pas le markup après signature.

7) DKIM échoue après un changement « inoffensif » d’infrastructure

  • Symptôme : Soudainement DKIM échoue après migration vers une nouvelle passerelle, ajout de DLP, activation d’un tag « externe », ou activation d’un connecteur cloud.
  • Cause racine : Vous avez changé les octets. DKIM l’a remarqué.
  • Fix : Déplacez la signature après le composant qui modifie, ou configurez le composant pour ne pas modifier le courrier sortant après la signature.

Trois mini-histoires d’entreprise du terrain

Mini‑histoire 1 : L’incident causé par une mauvaise hypothèse

L’entreprise A avait une pile sortante propre : des serveurs applicatifs soumettaient le mail à Postfix, Postfix le passait à un relais cloud, et le relais livrait au monde. Ils avaient DKIM « activé » et une politique DMARC pas agressive. Tout allait bien, ce qui est souvent le début du danger.

Une équipe sécurité a déployé une nouvelle bannière sortante : préfixer « [EXTERNAL] » sur le sujet pour tout mail quittant la société. Ils ont fait cela sur le relais cloud, parce que c’est là que se trouvait la case à cocher. Le changement a été approuvé rapidement ; ce n’était « qu’un préfixe de sujet ».

Trois jours plus tard, les reçus client ont commencé à atterrir en spam et certains partenaires ont commencé à rejeter le mail. Le SRE de garde a vu dkim=fail chez plusieurs récepteurs, et quelqu’un a déclaré avec assurance : « DKIM ne devrait pas se soucier du Subject, c’est juste un en‑tête. » Cette phrase leur a coûté un après‑midi.

Évidemment DKIM s’en est soucié. Leur signataire était sur la machine Postfix, en amont du relais cloud, et ils signaient l’en‑tête Subject. Le relais a modifié le Subject après la signature. Chaque message était désormais cryptographiquement « altéré ».

La réparation n’a pas été héroïque. Ils ont déplacé la signature DKIM vers le relais (le dernier saut avant l’Internet) et ont arrêté de signer les en‑têtes que les systèmes en aval réécrivent. Ils ont aussi ajouté un point de contrôle au changement : « Ce changement modifie‑t‑il les en‑têtes/corps post‑signature ? » Ça paraît bureaucratique. C’est en réalité moins coûteux que le tourisme en dossier spam du week‑end.

Mini‑histoire 2 : L’optimisation qui s’est retournée contre eux

L’entreprise B avait une installation mature et faisait des rotations de clés DKIM chaque trimestre. Quelqu’un a remarqué que leur fournisseur DNS facturait des « enregistrements avancés » et a proposé d’optimiser : consolider les sélecteurs et réutiliser la même clé DKIM sur plusieurs sous‑domaines et unités. Moins d’enregistrements, moins de tracas, moins d’éléments mobiles. Que pourrait‑il mal se passer.

Ils ont fait la consolidation, puis aussi raccourci les TTL pour accélérer les changements futurs. À la rotation suivante, ils ont mis à jour l’enregistrement DNS du sélecteur et déployé la nouvelle clé privée à la moitié de leur flotte d’envoi en premier. L’autre moitié a pris un jour de retard à cause d’une fenêtre de maintenance ratée.

La moitié de la flotte signait avec la nouvelle clé, l’autre moitié avec l’ancienne, et le DNS ne servait que la nouvelle clé publique. Tous les messages de la moitié retardataire ont échoué la vérification DKIM. Les récepteurs ne se sont pas souciés de l’explication interne du calendrier. Ils ont juste vu des signatures cassées et ont ajusté la réputation en conséquence.

L’« optimisation » a supprimé la soupape de sécurité : avoir plusieurs sélecteurs en parallèle. S’ils avaient utilisé des sélecteurs qui se chevauchent — vieux et nouveau — chaque segment de flotte aurait pu signer avec le sélecteur correspondant à sa clé déployée, et le DNS aurait pu servir les deux clés jusqu’à la fin du déploiement.

Ils ont récupéré en re‑publiant l’ancien enregistrement sélecteur, puis en planifiant les rotations avec des fenêtres de chevauchement et une règle explicite « ne pas supprimer les anciens sélecteurs tant que les files ne sont pas vidées ». Moins d’enregistrements n’a pas été la victoire qu’ils imaginaient.

Mini‑histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

L’entreprise C avait un environnement soumis à la conformité où chaque message sortant passait par une passerelle d’archivage. La passerelle était connue pour parfois réécrire la structure MIME lorsqu’elle « normalisait » les pièces jointes. Tout le monde la détestait, mais elle était non négociable.

Des années auparavant, un ingénieur avait insisté pour un design très peu sexy : la signature DKIM se fait après la passerelle d’archivage, sur le MTA final sortant. Cela signifiait que la boîte d’archivage ne voyait jamais des messages DKIM‑signés et ne pouvait donc pas casser les signatures. Les gens râlaient parce que cela compliquait la gestion des clés sur le dernier saut.

Un vendredi, l’équipe d’archivage a poussé une mise à jour qui a changé la façon dont les frontières multipart étaient générées. Cela n’a rien altéré sémantiquement, mais cela a changé les octets en transit pour certains messages. Si la signature DKIM avait été en amont, cela aurait provoqué des échecs DKIM généralisés et probablement un énorme problème DMARC le lundi.

À la place, rien ne s’est passé. Les signatures DKIM étaient ajoutées après que la passerelle ait fait son étrange travail. Les récepteurs ont validé des mails propres. L’incident a été rétrogradé à « changement interne a créé un MIME différent » et n’a jamais affecté la délivrabilité.

Blague courte #2 : La délivrabilité e‑mail est le seul sport où vous pouvez perdre parce que quelqu’un a ajouté deux espaces et un pied de page.

Listes de contrôle / plan pas-à-pas

Plan pas-à-pas : réparer un échec DKIM en moins d’une heure

  1. Capturez un message échoué brut depuis la boîte du récepteur (en‑têtes + corps bruts). Sauvegardez comme failed.eml.
  2. Lisez Authentication-Results : décidez si c’est « no key », « body hash mismatch », « signature invalid », ou « pass mais DMARC fail ».
  3. Extraire le sélecteur et le domaine depuis DKIM-Signature (s=, d=).
  4. Interrogez le DNS pour s._domainkey.d en utilisant au moins un résolveur public et votre environnement local.
  5. Validez le câblage du service de signature (config milter, logs montrant « DKIM-Signature field added »).
  6. Si mismatch du hash du corps  : cartographiez le chemin sortant et identifiez le saut qui modifie le contenu. Contournez temporairement ce saut si possible pour confirmer.
  7. Appliquez le changement correctif minimal  :
    • Corriger l’enregistrement DNS / mismatch de sélecteur
    • Déplacer la signature en aval des modificateurs
    • Empêcher les modificateurs de toucher le courrier sortant
    • Basculez sur relaxed/relaxed canonicalization
  8. Envoyez un test contrôlé à au moins deux récepteurs externes et confirmez dkim=pass.
  9. Ce n’est qu’ensuite que vous parlez de durcir la rotation des clés, d’ARC et des ajustements de politique DMARC.

Hygiène opérationnelle (choses à faire avant que ça casse)

  • Signer au dernier saut que vous contrôlez avant l’Internet ouvert.
  • Utiliser des clés 2048 bits sauf contrainte forte ; garder les enregistrements TXT propres et correctement scindés.
  • Faire tourner les sélecteurs avec chevauchement : publier le nouveau sélecteur d’abord, déployer la signature, garder l’ancien enregistrement jusqu’à ce que vous soyez sûr que les files sont vidées et les égarés livrés.
  • Choisir des en‑têtes stables à signer ; ne signez pas les en‑têtes qui mutent au saut.
  • Journaliser les événements de signature DKIM et alerter sur les baisses soudaines du volume signé.
  • Suivre chaque système qui peut réécrire le mail (DLP, AV, taggage de bannière, relais SMTP « intelligents », CRM, systèmes de ticketing).
  • Valider l’alignement DMARC pour les mails envoyés par des fournisseurs au nom de votre domaine.

Une idée de fiabilité à garder (paraphrasée)

Idée paraphrasée (John Allspaw) : La fiabilité vient du fait de rendre le comportement du système observable et d’apprendre des pannes, pas de prétendre que les pannes n’arriveront pas.

FAQ

1) Pourquoi DKIM passe parfois et échoue d’autres fois pour le même expéditeur ?

Généralement parce que le mail a suivi des routes différentes. Un chemin modifie le message (injection de pied de page, tag sujet, ré‑encapsulation MIME), un autre non. Moins fréquemment, c’est une incohérence DNS : certains résolveurs voient l’enregistrement de clé, d’autres non à cause du cache, du split DNS, ou d’une configuration faisant autorité cassée.

2) Quelle est la façon la plus rapide de dire si c’est DNS ou modification de message ?

Lisez le Authentication-Results du récepteur. « No key » crie DNS/sélecteur. « Body hash did not verify » crie modification après signature. « Signature did not verify » peut être soit une mauvaise clé/mismatch de rotation soit des changements d’en‑têtes/corps.

3) Dois‑je toujours utiliser la canonicalisation relaxed/relaxed ?

Dans les chemins e‑mail de production avec des intermédiaires du monde réel, oui la plupart du temps. simple est fragile. Si vous contrôlez tout le chemin et que vous voulez de la rigidité, d’accord, mais la plupart des organisations ne contrôlent pas réellement tout le chemin — malgré ce que le diagramme d’architecture prétend.

4) Puis‑je signer moins d’en‑têtes pour que DKIM survive mieux ?

Oui, mais ne soyez pas trop malin. Signez des en‑têtes qui ont une signification d’identité comme From, plus des métadonnées de routage/contenu qui ne changeront pas après la signature. Évitez de signer des en‑têtes connus pour changer en aval. L’objectif est la survivabilité sans rendre la signature dénuée de sens.

5) Le transfert casse‑t‑il toujours DKIM ?

Le transfert casse souvent SPF (parce que le forwarder devient l’IP expéditrice) et peut casser DKIM si le forwarder modifie le contenu. Un transfert SMTP pur sans modification peut préserver DKIM. Beaucoup de forwarders modifient (rewrap, ajout d’en‑têtes, parfois altération de contenu), c’est là qu’ARC devient précieux.

6) Qu’en est‑il des listes de diffusion ?

Les listes de diffusion sont le prédateur naturel de DKIM. Elles ajoutent couramment des pieds de page, modifient le sujet et changent des en‑têtes. Attendez‑vous à des échecs DKIM sauf si la liste est configurée pour être compatible DKIM/DMARC (ou utilise correctement ARC). Si la participation à une liste est importante, prévoyez‑le au lieu de blâmer « le mail qui est mail ».

7) Une clé DKIM 1024 bits est‑elle encore acceptable ?

Certains récepteurs l’acceptent, d’autres la pénalisent, et la marge de sécurité est plus faible. La réponse pratique : utilisez RSA 2048 bits sauf si votre fournisseur DNS ou plateforme ne peut pas le gérer proprement. Si vous ne pouvez pas, corrigez la contrainte DNS/fournisseur plutôt que de vous accrocher aux 1024 bits.

8) Nous utilisons un fournisseur pour envoyer le mail. Pourquoi avons‑nous des échecs DMARC alors que le fournisseur dit « DKIM activé » ?

Parce que le fournisseur signe probablement avec son propre domaine (d=vendor.com) et votre domaine visible From est le vôtre. DKIM peut passer, mais il ne s’aligne pas avec votre domaine, donc DMARC échoue. La correction est la signature DKIM en domaine personnalisé et un envelope sender aligné (domaine de rebond personnalisé) si nécessaire.

9) Dois‑je avoir plusieurs signatures DKIM ?

Ça peut être utile : une signature de votre infrastructure et une autre du fournisseur, ou une par identité de domaine. Mais assurez‑vous qu’au moins une signature s’aligne avec votre domaine From. Plusieurs signatures compliquent aussi le débogage ; gardez‑les intentionnelles, pas accidentelles.

10) Comment faire tourner les clés DKIM sans casser le mail ?

Utilisez un nouveau sélecteur, publiez son enregistrement DNS d’abord, déployez les signataires pour l’utiliser, et gardez l’ancien enregistrement publié pendant une fenêtre de chevauchement. Ne supprimez l’ancien enregistrement que lorsque vous êtes sûr que le mail retardé et les MTA retardataires ne l’utilisent plus.

Conclusion : prochaines étapes que vous pouvez vraiment faire aujourd’hui

Les échecs DKIM semblent mystiques jusqu’à ce que vous les traitiez comme n’importe quel autre problème d’intégrité en production : identifiez ce qui a changé, identifiez où cela a changé, et empêchez que cela change au mauvais endroit.

Faites ceci ensuite :

  1. Collectez un message brut échoué et classez l’échec via Authentication-Results.
  2. Vérifiez le sélecteur DNS depuis un résolveur public et votre environnement local. Corrigez « no key » avant de toucher quoi que ce soit d’autre.
  3. Si c’est un body hash mismatch, arrêtez les modifications post‑signature : déplacez la signature DKIM au dernier saut sortant ou désactivez les réécritures en aval.
  4. Assurez l’alignement DMARC pour vos domaines From commerciaux réels, surtout pour les mails envoyés par des fournisseurs.
  5. Institutionnalisez les parties ennuyeuses : chevauchement de rotation des clés, journalisation des événements de signature, et traitez « ajoute un pied de page » comme un changement de délivrabilité, pas un ajustement cosmétique.

Le mail est un système distribué hostile déguisé en service de commodité. DKIM est un des rares éléments qui se comporte de façon prévisible. S’il échoue, quelque chose a changé. Trouvez‑le. Réparez‑le. Puis consignez‑le pour que le Vous du futur n’ait pas à le redécouvrir à 3 h du matin.

← Précédent
GPU Docker dans les conteneurs : pourquoi ça échoue et comment le réparer
Suivant →
Blockchain partout : le battage qui s’est collé aux produits

Laisser un commentaire