E-mail : renouvellement du certificat TLS — empêcher la panne SMTP/IMAP le jour du renouvellement

Cet article vous a aidé ?

Le jour du renouvellement d’un certificat transforme souvent le « rien n’a changé » en incendie général.
Le courrier électronique est spécial de ce point de vue : le reste de votre pile peut tolérer un bref incident,
mais les tentatives SMTP se multiplient, les clients IMAP hurlent, et les cadres redécouvrent ce que signifie « boîte d’envoi ».

La bonne nouvelle : maintenir SMTP/IMAP stable pendant le renouvellement d’un certificat TLS relève principalement de la mécanique ennuyeuse.
La mauvaise nouvelle : cela ne marche que si vous faites volontairement les parties ennuyeuses, et si vous testez exactement les choses qui cassent.

Modèle mental de production : ce qui peut casser, où et pourquoi

Renouveler un certificat TLS ressemble à un simple échange de fichier : remplacer un fichier, redémarrer un démon, terminé.
Les serveurs de mail punissent cet optimisme car il existe plusieurs contextes TLS et plusieurs clients,
et ils ne se comportent pas tous de la même façon.

SMTP n’est pas un protocole unique, ce sont trois modes de déploiement

La plupart des opérateurs mail exécutent tous ceux-ci en même temps :

  • SMTP avec STARTTLS (port 25) pour la livraison serveur-à-serveur. TLS opportuniste, mais dépendant des politiques, il reste pointilleux sur les chaînes et les noms d’hôte.
  • Submission avec STARTTLS (port 587) pour les utilisateurs/clients. Validation généralement stricte, surtout sur les clients mobiles/desktop modernes.
  • SMTPS (port 465) TLS implicite. Toujours répandu ; les clients attendent une poignée de main propre immédiatement.

Vous pouvez renouveler un cert et « tester le port 25 » et tout de même casser la moitié de vos utilisateurs sur le port 587.
Ou l’inverse. Demandez‑moi comment je le sais. En fait, ne demandez pas ; c’est formateur, et vous avez probablement déjà assez de caractère.

IMAP/POP sont le royaume des connexions « longue durée »

Dovecot (ou votre démon IMAP/POP préféré) garde souvent de nombreuses sessions TLS ouvertes.
Un échange de certificat ne force pas automatiquement une renégociation. Certains clients continueront à fonctionner jusqu’à leur reconnexion ; d’autres se reconnecteront agressivement et commenceront à échouer par rafales. Cela donne l’impression de « problèmes réseau intermittents » tant que vous ne corrélez pas avec l’événement de renouvellement.

Le changement de fichier n’est pas le déploiement

C’est le bug conceptuel le plus courant : « certbot a renouvelé, donc on a fini. »
Certbot (ou tout client ACME) écrit des fichiers. Vos démons ne les relisent pas magiquement sauf si vous rechargez/redémarrez,
et même dans ce cas seulement si votre configuration pointe vers les bons chemins. Ajoutez des symlinks et des montages de conteneur et vous obtenez le classique :
« Le certificat sur le disque est nouveau mais le service sert toujours l’ancien. »

À quoi ressemble réellement une « rupture »

Vous verrez une des choses suivantes :

  • Échecs de poignée de main (clé incorrecte, chaîne cassée, protocole/chiffrement non supporté, ou mauvaises permissions).
  • Inadéquation de nom d’hôte (CN/SAN incorrect, mappage de vhost erroné, SNI incorrect, ou clients ciblant un nom différent de celui que vous avez testé).
  • Échecs de conformité (MTA-STS appliqué, DANE non concordant, certificats épinglés côté client, proxies d’entreprise faisant de l’« inspection »).
  • Échecs opérationnels (reload non effectué, dérive de configuration, mauvaise propriété de fichier, SELinux/AppArmor bloquant l’accès).

Un cadrage utile (légèrement paranoïaque) : traitez un renouvellement TLS comme un petit déploiement de configuration qui affecte chaque connexion entrante et sortante.
Vous ne « renouvelez pas un certificat ». Vous « déployez un nouvel artefact de confiance dans un système distribué ».

Une citation qui tient toujours en exploitation : L’espérance n’est pas une stratégie. — Gene Kranz

Faits intéressants et contexte historique (oui, ça compte)

Le comportement TLS du courrier est le résultat de décennies de rétrofits. Un peu d’histoire clarifie pourquoi votre changement « simple » peut déclencher
20 comportements client différents.

  1. STARTTLS a été ajouté plus tard. SMTP précède TLS ; STARTTLS est une extension greffée sur un protocole ancien, d’où un esprit « opportuniste » par défaut.
  2. Le port 465 a été « déprécié », puis est revenu. SMTPS était autrefois non officiel, puis la submission sur 587 est devenue préférable, et maintenant 465 est à nouveau largement recommandé pour TLS implicite.
  3. Les chaînes de certificats se sont raccourcies avec le temps. Beaucoup d’environnements sont passés de longues chaînes cross-signées à des racines/intermédiaires plus propres ; d’anciens clients exigent parfois l’intermédiaire « correct ».
  4. Let’s Encrypt a accéléré les cycles de renouvellement. Les certificats à courte durée de vie ont normalisé l’automatisation, mais aussi l’oubli du hook de reload.
  5. IDLE IMAP rend les échecs aléatoires. Les connexions longue durée font que les problèmes de certificat apparaissent lors d’ouragans de reconnexions, pas forcément au moment exact du renouvellement.
  6. La suppression de TLS 1.0/1.1 a été une rupture. Resserrement des versions de protocole = meilleure sécurité, mais les clients mail hérités (et appliances) ont mal réagi.
  7. MTA-STS et TLS-RPT ont changé les incitations. Le TLS serveur-à-serveur est passé de « sympa à avoir » à « certains domaines vous refuseront » si vous ne respectez pas la politique.
  8. DANE existe et est sous-utilisé. Il peut imposer TLS au niveau SMTP via DNSSEC, mais rend aussi les erreurs de renouvellement immédiatement visibles pour les pairs stricts.

Blague n°1 : le renouvellement TLS, c’est comme changer un pneu pendant que la voiture roule—sauf que la voiture livre aussi des e-mails aux cadres et vous juge en silence.

Playbook de diagnostic rapide (premières/deuxièmes/troisièmes vérifications)

Quand « TLS mail est cassé », vous avez besoin d’un chemin rapide vers le goulot d’étranglement. Ne commencez pas par redéployer tout.
Isolez d’abord quel service, quel port, quel nom, quel certificat.

Première étape : identifier la surface en échec

  • Quel protocole ? SMTP entrant (25), submission (587), SMTPS (465), IMAPS (993), POP3S (995).
  • Quel nom d’hôte ? mail.example.com vs smtp.example.com vs apex du domaine.
  • Quel type de client ? Serveurs Gmail, Outlook desktop, iOS Mail, une imprimante, une appliance SIEM.

Décision : si un seul port casse, vous avez un problème de mapping/configuration/reload. Si tous les ports cassent, suspectez les permissions de fichier,
une incompatibilité de clé, ou une corruption de chaîne.

Deuxième étape : récupérer le certificat servi depuis le réseau

Ne faites pas confiance à ce qui est sur le disque pour l’instant. Faites confiance à ce qui est réellement servi.

Décision : si le certificat servi est ancien, votre reload ne s’est pas appliqué. S’il est nouveau mais invalide, c’est la chaîne/le nom/la clé.

Troisième étape : confirmer localement l’appariement chaîne/clé

Si la poignée de main réseau échoue, confirmez que la clé privée correspond au certificat, et que la chaîne complète est correcte.

Décision : un désappariement signifie des fichiers mal câblés ; les problèmes de chaîne signifient que vous devez fournir le bon fichier d’intermédiaire/fullchain dans la config.

Quatrième étape : lire les logs du démon avec un but

Postfix et Dovecot vous disent généralement exactement ce qu’ils ne peuvent pas charger. Les gens ne lisent tout simplement pas les lignes qui comptent.
Trouvez « cannot load », « no start line », « permission denied », « key values mismatch ».

Cinquième étape : vérifier la couche politique (MTA-STS/DANE) si seuls certains domaines échouent

Si la plupart des livraisons réussissent mais que certains domaines rebondissent avec « TLS required », vous n’êtes pas face à un « TLS en panne »,
vous êtes face à une « non-conformité TLS ». Problème différent, correction différente.

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

Ci‑dessous des tâches opérationnelles réelles. Chacune inclut : la commande, un extrait réaliste de sortie,
ce que signifie la sortie, et ce que vous devez décider ensuite.

Task 1: Confirm certificate expiry and SANs on disk

cr0x@server:~$ openssl x509 -in /etc/letsencrypt/live/mail.example.com/fullchain.pem -noout -dates -subject -ext subjectAltName
notBefore=Jan  1 00:12:03 2026 GMT
notAfter=Apr  1 00:12:02 2026 GMT
subject=CN = mail.example.com
X509v3 Subject Alternative Name:
    DNS:mail.example.com, DNS:smtp.example.com, DNS:imap.example.com

Signification : Ce certificat est actuellement valide et couvre plusieurs noms d’hôte.

Décision : Si le nom en échec n’est pas dans les SANs, arrêtez. Émettez le certificat correct (ou ajoutez le nom),
n’essayez pas de « contournements » comme désactiver la vérification de nom d’hôte.

Task 2: Verify the private key matches the certificate (modulus check)

cr0x@server:~$ openssl x509 -noout -modulus -in /etc/letsencrypt/live/mail.example.com/cert.pem | openssl md5
MD5(stdin)= 9c0a0c7d5d0f4f1d0c1b1c1f3b7a2a7e
cr0x@server:~$ openssl rsa -noout -modulus -in /etc/letsencrypt/live/mail.example.com/privkey.pem | openssl md5
MD5(stdin)= 9c0a0c7d5d0f4f1d0c1b1c1f3b7a2a7e

Signification : Le certificat et la clé correspondent.

Décision : Si les hachages diffèrent, vous servez un certificat avec la mauvaise clé. Corrigez le câblage et redéployez ; ne redémarrez pas les services en boucle en espérant que ça résout le problème.

Task 3: Check what Postfix thinks its TLS files are

cr0x@server:~$ postconf -n | egrep 'smtpd_tls_cert_file|smtpd_tls_key_file|smtpd_tls_CAfile|smtpd_tls_chain_files|smtp_tls_security_level'
smtp_tls_security_level = may
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.example.com/privkey.pem

Signification : Postfix est configuré pour présenter fullchain.pem.

Décision : Si ces chemins ne pointent pas là où vous pensez, corrigez la config d’abord, puis rechargez. Si vous utilisez un chroot, assurez-vous que Postfix peut voir ces chemins depuis l’intérieur.

Task 4: Check Dovecot TLS config paths

cr0x@server:~$ doveconf -n | egrep 'ssl =|ssl_cert|ssl_key|ssl_min_protocol|ssl_cipher_list'
ssl = required
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
ssl_min_protocol = TLSv1.2

Signification : Dovecot lit la chaîne complète et exige TLS.

Décision : Si Dovecot pointe sur cert.pem au lieu de fullchain.pem, vous casserez souvent des clients qui ne récupèrent pas les intermédiaires. Utilisez la chaîne complète sauf raison testée contraire.

Task 5: Test STARTTLS on port 25 from a client perspective

cr0x@server:~$ openssl s_client -starttls smtp -connect mail.example.com:25 -servername mail.example.com -showcerts -verify_return_error </dev/null
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = mail.example.com
verify return:1
250 SMTPUTF8

Signification : TLS se vérifie proprement, et les capacités SMTP sont annoncées après STARTTLS.

Décision : Si la vérification échoue, lisez la première ligne « verify error ». Si c’est « unable to get local issuer », votre chaîne est incorrecte. Si c’est « hostname mismatch », vos SANs sont erronés ou le SNI est mal routé.

Task 6: Test submission port 587 with STARTTLS and AUTH advertisement

cr0x@server:~$ openssl s_client -starttls smtp -connect mail.example.com:587 -servername mail.example.com -crlf -quiet </dev/null | head -n 12
depth=0 CN = mail.example.com
verify return:1
250-mail.example.com
250-PIPELINING
250-SIZE 52428800
250-STARTTLS
250-AUTH PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250 8BITMIME

Signification : Le certificat se vérifie et le serveur annonce AUTH (typique pour la submission).

Décision : Si le port 25 fonctionne mais le 587 échoue, vous avez probablement un écouteur séparé, une configuration de certificat différente, ou un processus/conteneur distinct servant le 587.

Task 7: Test implicit TLS on port 465

cr0x@server:~$ openssl s_client -connect mail.example.com:465 -servername mail.example.com -verify_return_error </dev/null | egrep 'subject=|issuer=|Verify return code'
subject=CN = mail.example.com
issuer=C = US, O = Let's Encrypt, CN = R3
Verify return code: 0 (ok)

Signification : La poignée de main SMTPS est propre.

Décision : Si le 465 échoue mais le 587 fonctionne, suspectez une pile TLS différente (par ex. définition de service séparée, configuration legacy, ou un LB terminant TLS uniquement pour 465).

Task 8: Test IMAPS (993) and verify the presented certificate

cr0x@server:~$ openssl s_client -connect mail.example.com:993 -servername mail.example.com -verify_return_error </dev/null | egrep 'subject=|issuer=|Verify return code'
subject=CN = mail.example.com
issuer=C = US, O = Let's Encrypt, CN = R3
Verify return code: 0 (ok)

Signification : IMAPS présente le certificat et la chaîne attendus.

Décision : Si IMAPS échoue mais SMTP fonctionne, concentrez-vous sur Dovecot : permissions de fichiers, reload, ou un chemin ssl_cert séparé.

Task 9: Confirm which certificate Postfix actually loaded (log-driven)

cr0x@server:~$ sudo journalctl -u postfix -n 200 --no-pager | egrep -i 'tls|certificate|key|error' | tail -n 12
Jan 04 10:21:18 mail postfix/smtpd[21456]: warning: TLS library problem: error:0A00018F:SSL routines::ee key too small
Jan 04 10:21:18 mail postfix/smtpd[21456]: fatal: TLS library initialization failed
Jan 04 10:21:19 mail postfix/master[1023]: warning: process /usr/lib/postfix/sbin/smtpd pid 21456 exit status 1
Jan 04 10:21:19 mail postfix/master[1023]: warning: /usr/lib/postfix/sbin/smtpd: bad command startup -- throttling

Signification : La bibliothèque TLS a rejeté la taille de clé (commun après durcissement de sécurité ou quand quelqu’un a installé la mauvaise clé).

Décision : Réémettez une paire cert/clé qui respecte la politique OpenSSL (typiquement RSA 2048+ ou ECDSA). Ne relâchez pas les niveaux de sécurité OpenSSL juste pour « faire fonctionner » le service.

Task 10: Confirm Dovecot can read the files (permissions and SELinux-ish reality)

cr0x@server:~$ sudo -u dovecot test -r /etc/letsencrypt/live/mail.example.com/privkey.pem && echo OK || echo NO
OK
cr0x@server:~$ sudo -u dovecot test -r /etc/letsencrypt/live/mail.example.com/fullchain.pem && echo OK || echo NO
OK

Signification : L’utilisateur dovecot peut lire les deux fichiers.

Décision : Si vous obtenez NO, corrigez les permissions/propriétés de fichiers ou utilisez une étape de copie de déploiement vers un répertoire détenu par le service. Pensez aussi aux systèmes MAC (SELinux/AppArmor) : « lisible » au niveau des permissions Unix n’implique pas forcément autorisé.

Task 11: Reload daemons safely and verify they stayed up

cr0x@server:~$ sudo systemctl reload postfix
cr0x@server:~$ sudo systemctl reload dovecot
cr0x@server:~$ systemctl is-active postfix dovecot
active
active

Signification : Les deux services ont accepté le reload et sont restés actifs.

Décision : Si le reload échoue ou que le service devient inactif, arrêtez et revenez aux fichiers certs connus bons. Un déploiement de certificat qui fait tomber le démon est pire qu’un certificat expiré de loin.

Task 12: Verify from inside the host network namespace (container/LB gotcha)

cr0x@server:~$ openssl s_client -starttls smtp -connect 127.0.0.1:587 -servername mail.example.com -verify_return_error </dev/null | egrep 'subject=|Verify return code'
subject=CN = mail.example.com
Verify return code: 0 (ok)

Signification : Localement, le service est correct. Si les tests externes échouent, suspectez des load balancers, proxies, NAT, ou un nœud différent servant le trafic.

Décision : Comparez les empreintes locales et externes ; si elles diffèrent, vous avez un split‑brain entre instances.

Task 13: Confirm the served certificate fingerprint (good for comparing nodes)

cr0x@server:~$ echo | openssl s_client -connect mail.example.com:993 -servername mail.example.com 2>/dev/null | openssl x509 -noout -fingerprint -sha256
sha256 Fingerprint=6B:12:8E:3B:40:65:8D:29:42:0E:AD:AF:47:3F:9A:5C:0C:52:6A:0F:84:62:26:25:13:73:4C:CA:19:1C:0E:8A

Signification : C’est le certificat réellement servi sur cet endpoint maintenant.

Décision : Lancez la même commande contre chaque nœud ou cible VIP. Si les empreintes diffèrent, corrigez votre pipeline de déploiement ou l’appartenance au pool LB avant toute autre opération.

Task 14: Validate the chain file is structurally sane

cr0x@server:~$ awk 'BEGIN{c=0} /BEGIN CERTIFICATE/{c++} END{print c}' /etc/letsencrypt/live/mail.example.com/fullchain.pem
2

Signification : fullchain.pem contient deux certificats (leaf + intermédiaire), ce qui est courant.

Décision : Si cela renvoie 1, vous servez peut‑être seulement le certificat feuille. Si le compte est surprenant, quelqu’un a concaténé des certificats supplémentaires et a confondu des clients pointilleux.

Task 15: Check for upcoming expiry across all served names (cheap insurance)

cr0x@server:~$ for host in mail.example.com smtp.example.com imap.example.com; do
> echo -n "$host 587: "
> echo | openssl s_client -starttls smtp -connect $host:587 -servername $host 2>/dev/null \
> | openssl x509 -noout -enddate
> done
mail.example.com 587: notAfter=Apr  1 00:12:02 2026 GMT
smtp.example.com 587: notAfter=Apr  1 00:12:02 2026 GMT
imap.example.com 587: notAfter=Apr  1 00:12:02 2026 GMT

Signification : Tous les noms servent un certificat cohérent avec la même date d’expiration.

Décision : Si un nom affiche une date différente, vous avez une divergence de routage/vhost ou un nœud obsolète.

Trois mini‑histoires d’entreprise (anonymisées, douloureusement plausibles)

Mini‑histoire 1 : La panne causée par une mauvaise hypothèse (le mythe « fullchain est optionnel »)

Une entreprise SaaS de taille moyenne exécutait Postfix + Dovecot sur une paire de VM derrière un load balancer TCP.
Ils ont renouvelé via ACME, et dans un commit de nettoyage, un ingénieur a « simplifié » la config en pointant Postfix et Dovecot vers cert.pem
au lieu de fullchain.pem. L’hypothèse était raisonnable : « les clients peuvent récupérer les intermédiaires. »

Le premier signe n’était pas une panne totale. Ce furent des tickets support : « Outlook dit que le certificat est non fiable. »
Puis un commercial n’a pas pu se connecter depuis le Wi‑Fi d’un hôtel. Puis la passerelle mail on‑prem d’un partenaire a refusé les livraisons
avec une erreur de validation TLS. La plupart des autres clients continuaient de fonctionner, car les piles modernes reconstituent parfois les intermédiaires depuis leur cache.

Ops a passé des heures à chasser une « instabilité réseau » parce que les symptômes variaient selon les clients et les lieux. Les checks LB étaient verts (ils ne vérifiaient que le TCP). Les queues mail ont lentement grossi, puis ont explosé quand les retries se sont accumulés. Personne n’a corrélé ça au renouvellement parce que « le certificat est valide » et la date d’expiration était dans le futur.

La correction fut une ligne : servir fullchain.pem. Mais la leçon est restée : on ne met pas d’hypothèses sur le comportement des clients en production mail. La chaîne que vous envoyez est la chaîne dont vous êtes responsable.

Mini‑histoire 2 : L’optimisation qui s’est retournée contre eux (éviter les reloads comme « tactique de stabilité »)

Une équipe IT d’entreprise avait une culture de contrôle des changements stricte, et ils avaient été brûlés par des redémarrages.
Ils ont donc déclaré une nouvelle norme : renouveler les certificats automatiquement, mais ne jamais recharger les démons mail automatiquement.
« On le fera pendant la fenêtre mensuelle », disaient‑ils, et ça sonnait mûr.

Pendant des semaines, tout avait l’air correct. Les certificats se renvoyaient sur le disque. Les tableaux de bord étaient verts parce qu’ils surveillaient
les dates d’expiration en lisant des fichiers locaux. Puis un jour un certificat a réellement expiré parce que la fenêtre mensuelle a été déplacée
pour un événement business, et personne n’a rechargé.

Les démons continuaient de servir l’ancien certificat, maintenant expiré. Certains clients l’ont ignoré temporairement ; d’autres ont refusé tout net.
Les échecs de soumission ont touché d’abord (587/465). Les utilisateurs pouvaient recevoir du courrier (les sessions IMAP restaient actives), mais ne pouvaient pas envoyer.
C’est exactement le type de panne qui provoque des escalades : « Je ne peux pas envoyer de mail au conseil. »

Le postmortem fut gênant : l’« optimisation » visant à éviter une indisponibilité avait créé une panne différée, plus difficile à repérer. Leur supervision vérifiait la mauvaise chose : le système de fichiers, pas le réseau.
Ils ont changé la politique : renouvellement automatique et reload automatique, validés par un test canari de poignée de main.

Mini‑histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise (staging, canaris et empreintes)

Une entreprise de paiements traitait le mail comme un « mal nécessaire » mais le gérait comme de la production. Ils avaient trois habitudes :
(1) toujours tester ce qui est servi depuis l’extérieur, (2) déployer les certificats via une copie contrôlée vers un répertoire détenu par le service,
et (3) recharger pendant les heures ouvrables avec un check canari, parce que c’est là que les humains sont réveillés.

Lors d’un cycle de renouvellement, leur client ACME a produit un certificat valide, mais la chaîne intermédiaire a changé (toujours valide, juste différente).
Un petit ensemble de scanners anciens dans un entrepôt a rejeté la nouvelle chaîne. Personne ne se souciait des scanners—jusqu’à ce qu’ils commencent à envoyer des exceptions d’expédition par mail.

Le canari l’a détecté. Leur suite de tests incluait un profil client « legacy connu‑mauvais » encore présent en production.
Le canari n’a pas bloqué définitivement le déploiement ; il a déclenché une décision : garder la chaîne moderne pour les endpoints publics,
et exécuter un nom d’hôte interne dédié avec une chaîne de compatibilité pour le segment entrepôt.

La pratique ennuyeuse gagne encore. Ils n’ont pas eu de panne ; ils ont eu une correction de compatibilité contrôlée. C’est la différence entre « le jour du renouvellement » et « un mardi ».

Listes de contrôle / plan étape par étape pour le jour du renouvellement

Principes (la partie opinionnée)

  • Ne déployez jamais un certificat que vous n’avez pas validé depuis le réseau. Les vérifications sur disque sont nécessaires mais pas suffisantes.
  • Servez une chaîne complète. Utilisez fullchain.pem sauf si vous faites quelque chose d’intentionnellement inhabituel.
  • Automatisez les reloads, mais gatez‑les. Un hook de reload qui exécute un test de poignée de main avant et après n’est pas une « automation dangereuse », c’est plus sûr que les humains.
  • Ne « corrigez » pas les problèmes de certificat en affaiblissant TLS. Vous ne dépannez pas, vous créez un incident futur.
  • Supposez que vous avez un split‑brain jusqu’à preuve du contraire. Mail multi‑nœud + load balancers + renouvellements = incohérence par défaut.

Plan étape par étape : pipeline de renouvellement sûr (nœud unique)

  1. Renouvelez dans un emplacement de staging.
    Gardez le répertoire live du service stable jusqu’à ce que vous ayez vérifié l’appariement clé/SAN.
  2. Validez l’appariement cert/clé localement (Task 2). Si mismatch, arrêtez.
  3. Validez la structure de la chaîne (Task 14). Si feuille seule, arrêtez.
  4. Copiez les fichiers dans un répertoire détenu par le service avec des permissions stables.
    Évitez de pointer les démons directement vers les répertoires ACME si votre modèle de sécurité rend cela fragile.
  5. Rechargez Dovecot et Postfix (Task 11).
  6. Exécutez des tests de poignée de main externes pour 25/587/465/993 (Tasks 5–8). Confirmez les SANs et les codes de vérification.
  7. Confirmez les empreintes pour l’auditabilité (Task 13). Enregistrez‑les dans la note de changement.
  8. Surveillez les logs et les queues pendant 15–30 minutes. Le mail casse parfois lentement.

Plan étape par étape : multi‑nœud avec un load balancer

  1. Choisissez un nœud canari. Vidangez‑le du LB (ou réduisez son poids) mais gardez‑le accessible pour les tests.
  2. Déployez le certificat sur le nœud canari (copie en staging), rechargez les services.
  3. Testez le canari directement par IP/DNS du nœud en utilisant le SNI et le nom d’hôte attendu (Tasks 5–8 plus Task 13).
  4. Réintégrez le canari au LB et surveillez les taux d’erreur et les logs. Si tout est propre, avancez nœud par nœud.
  5. Après le rollout, testez le VIP du LB et aussi chaque backend pour s’assurer que les empreintes correspondent (Task 13).

Exemple de hook de renouvellement : valider avant reload, valider après

Ce n’est pas un « tutoriel de script », c’est un modèle : l’événement de renouvellement déclenche des tests, puis un reload, puis des re‑tests.
Les tests doivent renvoyer un code non‑zéro si la vérification échoue.

cr0x@server:~$ sudo bash -lc 'cat >/usr/local/sbin/mail-tls-postrenew.sh <<'"'"'EOF'"'"'
#!/usr/bin/env bash
set -euo pipefail

HOST="mail.example.com"

precheck() {
  echo | openssl s_client -starttls smtp -connect 127.0.0.1:587 -servername "$HOST" 2>/dev/null \
    | openssl x509 -noout -enddate >/dev/null
}

postcheck() {
  echo | openssl s_client -starttls smtp -connect "$HOST:587" -servername "$HOST" -verify_return_error 2>/dev/null \
    | openssl x509 -noout -enddate
  echo | openssl s_client -connect "$HOST:993" -servername "$HOST" -verify_return_error 2>/dev/null \
    | openssl x509 -noout -enddate
}

precheck
systemctl reload postfix
systemctl reload dovecot
postcheck
EOF
chmod 0755 /usr/local/sbin/mail-tls-postrenew.sh
/usr/local/sbin/mail-tls-postrenew.sh'
notAfter=Apr  1 00:12:02 2026 GMT
notAfter=Apr  1 00:12:02 2026 GMT

Signification : Les vérifications avant et après ont réussi ; le reload n’a pas cassé la vérification externe.

Décision : Si ce script échoue, traitez‑le comme un déploiement raté : revenez en arrière ou stoppez le rollout. Ne relancez pas les reloads en boucle.

Erreurs courantes : symptômes → cause racine → correction

Ce ne sont pas des théories. Ce sont celles qui apparaissent à 02:00 avec un on‑call bien réveillé.

1) « Il a été renouvelé, mais les clients voient encore l’ancien certificat »

Symptômes : Sur le disque le certificat est nouveau ; à l’extérieur l’empreinte du certificat est inchangée.
Les clients continuent d’afficher des avertissements d’expiration ou de confiance.

Cause racine : Le service n’a pas été rechargé, ou le service pointe vers des chemins de fichiers différents de ceux que vous avez mis à jour.
En clusters, un nœud n’a pas reçu la mise à jour.

Correction : Vérifiez le certificat servi avec le Task 13. Rechargez les démons (Task 11). Confirmez les chemins de config (Tasks 3–4).
Pour multi‑nœud : vérifiez l’empreinte de chaque nœud et corrigez l’incohérence de déploiement.

2) « Échec de poignée de main : key values mismatch / mauvaise clé »

Symptômes : Les logs Postfix/Dovecot montrent un mismatch de clé ; TLS n’initialise pas ; le service peut refuser d’établir TLS.

Cause racine : Le certificat et la clé privée ne correspondent pas, généralement dû à une copie partielle des fichiers, mélange ECDSA/RSA,
ou pointeur vers le mauvais privkey.pem.

Correction : Exécutez le check modulus (Task 2). Corrigez les chemins de fichiers et déployez la paire correcte.
Si vous faites une rotation de clés, faites‑la de manière atomique pour les deux fichiers.

3) « Certains clients fonctionnent, d’autres non (surtout Outlook ou appareils embarqués) »

Symptômes : Les clients modernes se connectent bien ; les appareils anciens échouent avec « non fiable » ou « impossible à vérifier ».

Cause racine : Vous servez seulement le certificat feuille (pas d’intermédiaire) ou une chaîne que ces clients ne peuvent pas reconstituer.

Correction : Servez fullchain.pem (Tasks 3–4, 14). Si vous avez vraiment des dépendances legacy,
vous devrez peut‑être concevoir une stratégie de chaîne de compatibilité (mais ne faites pas de cargo‑cult : testez avec les appareils réels).

4) « Inadéquation de nom d’hôte après le renouvellement »

Symptômes : Erreur du type « certificate subject name does not match target host name. »
Se produit sur certains ports/noms d’hôte mais pas sur d’autres.

Cause racine : SAN manquants, nom d’hôte incorrect utilisé par les clients, ou configuration vhost différente par port.
Parfois le routage SNI est erroné (le LB envoie le mauvais certificat pour le nom).

Correction : Inspectez les SANs (Task 1). Validez avec SNI en utilisant -servername (Tasks 5–8).
Ajustez l’émission du certificat pour inclure tous les noms utilisés, et alignez le DNS/clients si vous avez de la dérive.

5) « Seuls certains domaines externes renvoient le mail en échec avec TLS required »

Symptômes : La plupart des domaines reçoivent le mail. Certains renvoient des rebonds comme « TLS required but handshake failed. »

Cause racine : Application de politiques via MTA-STS ou DANE chez le destinataire ; votre offre TLS ou validation casse sous règles strictes.

Correction : Reproduisez avec une vérification stricte (Task 5 avec -verify_return_error).
Assurez‑vous d’une chaîne correcte, du bon nom d’hôte, et de versions de protocole sensées. Ne désactivez pas TLS ; corrigez la conformité.

6) « Le reload a marché, puis des heures plus tard des plaintes IMAP ont commencé »

Symptômes : Échecs lents et progressifs, surtout en IMAP ; pas liés au moment du reload.

Cause racine : Les tempêtes de reconnexion client révèlent des problèmes de certificat ou de chaîne graduellement ; certains clients avaient des intermédiaires en cache et les perdent plus tard.

Correction : Validez IMAPS depuis l’extérieur (Task 8) et confirmez la chaîne complète.
Surveillez les logs pour des alertes TLS après le renouvellement. Envisagez de forcer une fenêtre de reconnexion contrôlée si vous devez purger des sessions obsolètes.

Supervision et alertes qui détectent ça avant les utilisateurs

L’erreur de surveillance habituelle est de vérifier la date d’expiration sur le système de fichiers. Cela vous indique ce qui est disponible,
pas ce qui est servi. Surveillez depuis le réseau, par port, par nom d’hôte, depuis au moins deux emplacements.

Ce qu’il faut surveiller (minimum viable)

  • Date d’expiration du certificat servi sur 25 (STARTTLS), 587 (STARTTLS), 465 (implicite), 993 (implicite), et tout port POP exposé.
  • Taux de réussite des poignées de main (binaire). Soit vous établissez TLS et vérifiez la chaîne, soit non.
  • Dérive d’empreinte de certificat entre nœuds et le VIP (optionnel, mais précieux pour diagnostiquer un split‑brain).
  • Profondeur de la file et taux de defer pour Postfix. Les échecs de certificat se traduisent souvent par des déferrals et des retries.
  • Taux d’erreurs TLS dans les logs pour Postfix et Dovecot.

Exemple : vérification rapide d’expiration depuis le réseau (compatible cron)

cr0x@server:~$ bash -lc 'host=mail.example.com
for p in 465 993; do
  echo -n "$host:$p "
  echo | openssl s_client -connect $host:$p -servername $host 2>/dev/null | openssl x509 -noout -enddate
done'
mail.example.com:465 notAfter=Apr  1 00:12:02 2026 GMT
mail.example.com:993 notAfter=Apr  1 00:12:02 2026 GMT

Signification : La date d’expiration du certificat servi est visible et cohérente sur les ports TLS implicites.

Décision : Générez une alerte si l’expiration est dans votre seuil (ex. 14 jours) ou si la commande échoue (aucune sortie signifie généralement échec de poignée de main).

Signal basé sur les logs : trouver rapidement les échecs TLS

cr0x@server:~$ sudo journalctl -u postfix -S "1 hour ago" --no-pager | egrep -i 'tls|handshake|SSL|certificate|verify|alert' | tail -n 20
Jan 04 11:02:07 mail postfix/smtpd[22911]: warning: TLS library problem: error:0A000086:SSL routines::certificate verify failed
Jan 04 11:02:07 mail postfix/smtpd[22911]: warning: TLS library problem: error:0A000418:SSL routines::tlsv1 alert unknown ca

Signification : Il y a des erreurs TLS actives. « unknown ca » indique souvent un problème de chaîne ou de confiance côté client.

Décision : Si cela augmente après un renouvellement, traitez‑le comme une régression ; confirmez que vous servez la chaîne complète et pas un certificat inattendu.

Blague n°2 : La seule chose qui se renouvelle plus vite qu’un cert Let’s Encrypt, c’est la rumeur d’une panne mail dans un chat d’entreprise.

Renforcement : chaînes, chiffrements, SNI, DANE, MTA-STS et réalité

Utilisez fullchain par défaut, mais comprenez ce que c’est

fullchain.pem est votre certificat feuille plus l’intermédiaire (ou les intermédiaires) nécessaires pour remonter jusqu’à une racine de confiance.
La plupart des clients ne veulent pas partir à la chasse aux intermédiaires pendant la poignée de main.

Votre démon mail doit généralement présenter :

  • Le certificat feuille (pour mail.example.com)
  • Le(s) certificat(s) intermédiaire(s)
  • Pas le certificat racine CA (les clients possèdent déjà les racines ; l’inclure peut perturber certaines piles)

SNI : le piège silencieux dans les configurations multi‑domaines

Si vous servez plusieurs domaines/certificats sur une même IP, les clients utilisant SNI demanderont le nom correct.
Certains clients SMTP le font, d’autres non, et quelques proxies le suppriment.
Les load balancers peuvent terminer TLS et ré‑chiffrer, changeant ce que le client voit.

Conseils opérationnels :

  • Testez toujours avec -servername (Tasks 5–8). Cela se rapproche du comportement réel des clients.
  • Testez aussi parfois sans SNI. Si votre certificat « par défaut » est incorrect, les clients legacy peuvent l’obtenir.

Versions de protocole et suites de chiffrement : soyez stricts, mais pas dans l’excès

Pour le mail, TLS 1.2 minimum est une base saine. TLS 1.3 est excellent, mais vous n’avez pas besoin d’en faire un étendard.
Le piège plus important est de durcir trop vite sans inventorier les clients legacy.

Si vous voulez savoir ce que vous proposez, testez directement :

cr0x@server:~$ openssl s_client -connect mail.example.com:993 -servername mail.example.com -tls1_2 </dev/null | egrep 'Protocol|Cipher|Verify return code'
Protocol  : TLSv1.2
Cipher    : ECDHE-RSA-AES256-GCM-SHA384
Verify return code: 0 (ok)

Signification : TLS 1.2 fonctionne et la vérification passe.

Décision : Si TLS 1.2 échoue mais TLS 1.3 fonctionne, vous avez peut‑être rendu le serveur trop strict pour certains clients. Décidez si ceci est acceptable ; sinon, élargissez volontairement la compatibilité.

DANE : puissant, mais il vous force à être exact

DANE pour SMTP utilise des enregistrements TLSA signés DNSSEC pour indiquer aux expéditeurs quel certificat/clé attendre.
C’est excellent pour la sécurité et terrible pour les renouvellements bâclés.

Si vous utilisez DANE, tout changement de clé nécessite une mise à jour TLSA. Si vous épinglez le SPKI feuille et que vous faites une rotation de clés sans mettre à jour le DNS,
les expéditeurs stricts vous traiteront comme hostile.

MTA-STS : la politique rend votre « ça marche à peu près » inacceptable

MTA-STS n’améliore pas TLS magiquement, mais rend l’échec actionnable : si vous annoncez une politique « enforce »,
les récepteurs exigeront une poignée de main valide au bon nom d’hôte.

Cela signifie que les erreurs de renouvellement passent de « certains clients avertissent » à « mail qui rebondit ».
Si vous activez MTA-STS, vous vous engagez implicitement à être discipliné sur les certificats.
C’est bien. Ne le faites juste pas à moitié.

Atomicité : déployez en unité, pas fichier par fichier

Le certificat, la clé et la chaîne constituent une unité. Ne les copiez pas un par un pendant qu’un service se recharge.
Si vous devez copier, copiez dans un nouveau répertoire et échangez un symlink de façon atomique, puis rechargez.

C’est particulièrement important sur les serveurs chargés où un reload peut survenir en plein copie, produisant des échecs intermittents qui
disparaissent quand vous « réessayez ». Ce sont les pires incidents : ceux qui gaslightent l’on‑call.

FAQ

1) Dois‑je redémarrer Postfix/Dovecot pour prendre en compte un certificat renouvelé ?

En général un systemctl reload suffit, mais seulement si le démon relit réellement le certificat lors du reload.
Confirmez en vérifiant l’empreinte servie (Task 13). Si elle n’a pas changé, vous avez besoin d’un restart ou votre reload n’est pas câblé.

2) Dois‑je pointer les configs vers cert.pem ou fullchain.pem ?

Utilisez fullchain.pem pour les services mail sauf si vous avez une raison testée de faire autrement. Le feuille‑seule casse souvent des clients plus vieux ou plus stricts.

3) Pourquoi le port 25 fonctionne mais le 587 échoue (ou inversement) ?

Écouteurs différents, blocs de config différents, processus différents, ou points de terminaison différents (LB/proxy).
Traitez chaque port comme son propre produit et testez‑le explicitement (Tasks 5–7).

4) Comment savoir quel certificat les clients voient réellement ?

Utilisez openssl s_client depuis l’extérieur de votre réseau et enregistrez l’empreinte (Task 13). Ne vous fiez pas aux fichiers locaux.

5) Quelle est la façon la plus rapide de détecter un split‑brain entre nœuds mail ?

Comparez les empreintes par nœud et sur le VIP. Si deux nœuds présentent des certificats différents, votre déploiement n’est pas cohérent.
Les empreintes rendent ça évident en quelques secondes.

6) Puis‑je éviter les reloads en comptant sur le hot‑reloading des fichiers de certificat ?

Certains logiciels peuvent surveiller les fichiers ; beaucoup de piles mail ne le font pas de façon fiable, et le comportement varie selon versions et distributions.
Supposez que vous avez besoin d’un reload explicite et concevez l’automatisation en conséquence.

7) Les certificats ECDSA sont‑ils sûrs pour les clients mail ?

Souvent oui, mais pas universellement. Certains clients legacy et appliances ont un support ECDSA incomplet.
Si votre base d’utilisateurs inclut des appareils anciens, envisagez des certificats doubles ou testez avant de changer d’algorithme.

8) Et si j’utilise un load balancer qui termine TLS ?

Alors le renouvellement est d’abord un problème de LB : mettez à jour le magasin de certificats du LB et validez sur le VIP.
Assurez‑vous aussi que le TLS backend (si vous l’utilisez) est correct, mais souvenez‑vous que le client voit le certificat du LB.

9) Pourquoi les problèmes IMAP apparaissent‑ils plus tard que SMTP ?

Les clients IMAP gardent souvent des sessions TLS longue durée (surtout avec IDLE). Les clients de submission se reconnectent fréquemment.
Donc la submission casse fort et vite ; IMAP peut casser lentement au fil du churn des sessions.

10) Est‑il acceptable de désactiver temporairement la vérification de certificat pour « faire circuler le mail » ?

Pour les applications clientes, non. Pour serveur‑à‑serveur, affaiblir la vérification peut ne pas aider car les pairs appliquent des politiques.
Vous entraînez aussi votre organisation à accepter des solutions non sécurisées. Corrigez le certificat et la chaîne correctement.

Prochaines étapes (pratiques)

Si vous voulez que le jour du renouvellement ressemble à un non‑événement, faites ceci :

  1. Ajoutez des vérifications réseau de certificats pour 25/587/465/993, par nom d’hôte, et alertez sur l’expiration et l’échec de poignée de main.
  2. Standardisez le déploiement de la chaîne complète et vérifiez la couverture SAN avant le reload.
  3. Implémentez un hook post‑renew gated qui exécute des tests de poignée de main, recharge les services, puis re‑teste (modèle montré ci‑dessus).
  4. Rendez le rollout atomique et cohérent à travers les nœuds : copie en staging, swap de symlink, puis reload, puis vérification d’empreinte.
  5. Consignez vos étapes de « diagnostic rapide » dans votre runbook on‑call et incluez les commandes exactes que vous lancerez à 02:00.

L’objectif n’est pas de rendre les renouvellements TLS excitants. L’objectif est de les rendre ennuyeux — et l’ennui est le plus grand compliment qu’un système de production puisse recevoir.

← Précédent
Debian 13 : fuites mémoire dans les services — détecter avec un minimum de perturbations (cas n°43)
Suivant →
DNS inversé (PTR) : pourquoi vos e-mails souffrent et comment corriger correctement le rDNS

Laisser un commentaire