← Retour au blogGuides

Certificat SSL expiré : que faire et comment l'éviter

Certificat SSL expiré ? Confirmez-le avec openssl, renouvelez-le, installez la chaîne complète, rechargez le serveur et automatisez les renouvellements.

Publié: · 7 min de lecture

Un certificat expiré met un site hors ligne aussi sûrement qu'un serveur en panne. Les navigateurs affichent un avertissement en pleine page (NET::ERR_CERT_DATE_INVALID dans Chrome, SEC_ERROR_EXPIRED_CERTIFICATE dans Firefox) et, si le site utilise HSTS, il n'y a même pas de lien « continuer quand même ». Clients d'API, applications mobiles, webhooks et retours de paiement échouent, tout simplement. Ce guide décrit ce qu'il faut faire dans la première demi-heure, puis comment s'assurer que cela ne se reproduise pas.

Étape 1 — Confirmez ce qui ne va pas réellement

Toute erreur de date n'est pas un certificat expiré sur votre serveur. Vérifiez depuis une machine dont l'horloge est fiable :

$ openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
    | openssl x509 -noout -subject -issuer -dates
subject=CN = example.com
issuer=C = XX, O = Example CA, CN = Example CA R3
notBefore=Jun 20 08:00:00 2026 GMT
notAfter=Sep 18 08:00:00 2026 GMT

Un notAfter dans le passé le confirme. Voici ce qui y ressemble sans l'être :

  • Une horloge fausse côté client. Un portable dont la pile est morte et qui se croit en 2019 rejette tous les certificats. Si un seul visiteur signale l'erreur, interrogez-le d'abord sur son horloge.
  • Un certificat intermédiaire expiré dans la chaîne envoyée par le serveur, alors que le certificat final est valide.
  • Un seul serveur parmi plusieurs présente encore l'ancien certificat. Derrière un répartiteur de charge ou un CDN, contrôlez chaque nœud, et contrôlez l'origine séparément de la périphérie.
  • Un autre service sous le même nom. Le port 443 a été renouvelé, mais la messagerie (:465, :993, :587 avec STARTTLS) utilise toujours l'ancien fichier :
$ openssl s_client -connect mail.example.com:587 -starttls smtp </dev/null 2>/dev/null \
    | openssl x509 -noout -enddate

L'option -servername a son importance : sans SNI, beaucoup de serveurs renvoient un certificat par défaut qui n'est pas celui que voient les navigateurs.

Étape 2 — Renouvelez, selon l'origine du certificat

ACME (Let's Encrypt et équivalents)

Le certificat aurait dû se renouveler tout seul : cherchez pourquoi il ne l'a pas fait.

$ sudo certbot certificates          # ce que certbot connaît, avec les dates d'expiration
$ sudo certbot renew --dry-run       # teste le renouvellement à blanc
$ sudo certbot renew                 # renouvelle tout ce qui arrive à échéance
$ systemctl list-timers | grep -i certbot

Les causes habituelles : le timer ou la tâche cron a disparu après une migration de serveur ; le port 80 est fermé, ou redirigé d'une manière qui casse le défi HTTP-01 ; le jeton d'API DNS utilisé pour DNS-01 a été renouvelé ; un enregistrement AAAA pointe vers une machine qui ne répond pas au défi ; un enregistrement CAA restrictif ne mentionne pas l'autorité de certification ; ou bien le domaine pointe désormais vers un tout autre serveur.

Certificat d'une autorité commerciale

  1. Générez une nouvelle clé et une nouvelle CSR. Ne réutilisez pas l'ancienne clé par habitude.
$ openssl req -new -newkey rsa:2048 -nodes \
    -keyout example.com.key -out example.com.csr \
    -subj "/CN=example.com" \
    -addext "subjectAltName=DNS:example.com,DNS:www.example.com"
  1. Soumettez la CSR, effectuez la validation du domaine (e-mail, enregistrement DNS ou fichier HTTP), puis téléchargez le certificat et la chaîne intermédiaire.
  2. Indiquez dans le champ SAN tous les noms d'hôte dont vous avez besoin. example.com ne couvre pas www.example.com, et un certificat générique *.example.com ne couvre ni le domaine nu ni a.b.example.com.

Certificat géré par un hébergeur, un CDN ou un répartiteur de charge

Regardez dans l'interface du fournisseur. Un certificat géré échoue en général à se renouveler pour une seule raison : le domaine ne passe plus la validation. L'enregistrement DNS qui pointait vers le fournisseur a été modifié, un CNAME nécessaire à la validation a été supprimé, ou un enregistrement CAA bloque l'autorité de certification du fournisseur.

Étape 3 — Installez-le avec la chaîne complète

Le serveur doit envoyer le certificat final suivi du ou des intermédiaires. La racine, elle, n'est pas envoyée. Avec certbot, il s'agit de fullchain.pem :

# nginx
ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

L'absence d'un intermédiaire est traîtresse : les navigateurs de bureau la masquent souvent en allant chercher les intermédiaires ou en les gardant en cache, tandis que curl, les applications Android et les autres serveurs échouent. Testez avec un client strict :

$ curl -sSI https://example.com >/dev/null && echo chain ok

Vérifiez que le certificat et la clé vont bien ensemble :

$ openssl x509 -noout -pubkey -in fullchain.pem | openssl sha256
$ openssl pkey -pubout -in privkey.pem | openssl sha256

Les deux empreintes doivent être identiques.

Étape 4 — Rechargez le service

Voici la cause la plus fréquente du « j'ai renouvelé et il est toujours expiré » : le serveur web garde l'ancien certificat en mémoire.

$ sudo nginx -t && sudo systemctl reload nginx
$ sudo apachectl configtest && sudo systemctl reload apache2

Avec un client ACME, intégrez le rechargement au renouvellement, par exemple certbot renew --deploy-hook "systemctl reload nginx". Faites de même pour Postfix, Dovecot, HAProxy et tout ce qui lit le fichier.

Étape 5 — Vérifiez depuis l'extérieur

Relancez la commande openssl s_client de l'étape 1 et regardez le nouveau notAfter. Contrôlez ensuite :

  • example.com et www.example.com, ainsi que tous les autres noms utilisés ;
  • IPv4 et IPv6 séparément (openssl s_client -4 / -6) si vous publiez les deux ;
  • chaque nœud derrière le répartiteur de charge ;
  • la messagerie et les autres ports TLS.

Les navigateurs peuvent garder une connexion ouverte un certain temps : testez dans une nouvelle fenêtre de navigation privée avant de conclure que cela n'a pas fonctionné.

Pourquoi cela se répète : des durées de validité toujours plus courtes

Les certificats reconnus publiquement sont limités à 398 jours depuis septembre 2020, et Let's Encrypt émet des certificats de 90 jours depuis ses débuts. En avril 2025, le CA/Browser Forum a adopté un calendrier qui réduit encore le maximum : 200 jours à partir du 15 mars 2026, 100 jours à partir du 15 mars 2027, et 47 jours à partir du 15 mars 2029. La période pendant laquelle une validation de domaine déjà effectuée peut être réutilisée diminue elle aussi.

Concrètement : le rappel dans l'agenda suivi d'un renouvellement manuel une fois par an est un procédé dont la fin est programmée. Avec des certificats de 47 jours, plus personne ne renouvelle à la main. Notez aussi que Let's Encrypt a cessé en 2025 d'envoyer ses e-mails d'avertissement avant expiration : ce filet de sécurité a disparu lui aussi.

Liste de contrôle pour éviter la récidive

  • Automatisez l'émission et le renouvellement avec ACME partout où la plateforme le permet. Beaucoup d'autorités commerciales prennent également en charge ACME.
  • Renouvelez tôt. Par défaut, les clients ACME renouvellent lorsqu'il reste environ un tiers de la durée de validité, ce qui laisse des semaines pour remarquer un échec.
  • Surveillez depuis l'extérieur, indépendamment du mécanisme de renouvellement. Le contrôle doit porter sur le certificat que le serveur présente, pas sur le fichier stocké sur le disque. Alertez à 21, 14 et 7 jours.
  • Recensez tous les points d'accès : sous-domaines, serveurs de messagerie, passerelles VPN, outils internes, origine derrière le CDN. Celui que l'on oublie est celui qui expire.
  • Testez le deploy hook. Un renouvellement sans rechargement est une panne simplement reportée.
  • Gardez la validation en état de marche : port 80 joignable pour HTTP-01, identifiants d'API DNS valides pour DNS-01, enregistrements CAA mentionnant les autorités que vous utilisez.
  • Envoyez les alertes à une adresse d'équipe, pas à la boîte d'une seule personne.

Erreurs fréquentes

  • Renouveler le certificat sans recharger le serveur.
  • Installer le certificat final sans l'intermédiaire.
  • Oublier www, ou le domaine nu, dans la liste SAN.
  • Renouveler le certificat de périphérie (CDN) pendant que celui de l'origine expire en silence ; selon le mode du CDN, cela se traduit par des erreurs 5xx renvoyées par la périphérie plutôt que par un avertissement du navigateur.
  • Dire aux utilisateurs de passer outre l'avertissement. C'est leur apprendre exactement le réflexe sur lequel comptent les attaquants.
  • Désactiver « provisoirement » la vérification des certificats dans un client d'API.
  • Conclure à un problème de certificat alors que la vraie cause est une modification DNS qui a envoyé les utilisateurs vers un autre serveur. Si le certificat présenté appartient à quelqu'un d'autre, vérifiez d'abord vers quoi pointe le nom.

Vérifiez avec OrbitProbe

Le vérificateur SSL d'OrbitProbe se connecte à votre nom d'hôte et décrit le certificat réellement présenté : émetteur, dates de validité et jours restants, noms d'hôte couverts, protocole TLS négocié, chaîne reconnue ou non, et HSTS. Lancez-le après chaque renouvellement, une fois pour le domaine nu et une fois pour www. Si la messagerie fait partie du même incident, la liste de contrôle DNS pour les e-mails qui arrivent en spam couvre le volet TLS et DNS de la remise du courrier ; et si vous prévoyez une modification DNS dans la foulée, relisez d'abord ce qu'est le TTL.