On ne va pas se mentir. La plupart des pannes « incompréhensibles » sur un site ou une API, celles qui arrivent un mardi à 07h58 juste avant une démo, finissent par être… un certificat TLS expiré.
Et le pire, c’est que l’incident est souvent évitable. Pas avec une grosse refonte, pas avec un audit à 20 000 €, mais avec une discipline simple : visibilité, automatisation, et une ou deux ceintures de sécurité.
Dans cet article, je te donne une méthode concrète pour éviter le scénario classique : certificat expiré, navigateur en alerte rouge, clients qui te pingent, SEO qui prend une claque, et toi qui te demandes pourquoi « ça n’a pas renouvelé tout seul ».
Objectif : que l’expiration d’un certificat soit un non événement. Un log, une alerte, un renouvellement, et basta.
Comprendre ce qui expire, exactement
Quand on dit « TLS expiré », on parle presque toujours du certificat X.509 présenté par ton serveur (Nginx, Apache, un load balancer, un ingress Kubernetes, un CDN, etc.).
Ce certificat a :
- une date de début (notBefore)
- une date de fin (notAfter)
- un nom (CN/SAN : tes domaines)
- une chaîne de confiance (intermédiaires)
- une clé, un algorithme, des usages
Si la date de fin est dépassée, les clients modernes réagissent fort. Et ils ont raison.
Mais attention, dans la vraie vie, « TLS expiré » peut aussi cacher des variantes :
- chaîne intermédiaire manquante (ça casse sur certains clients)
- horloge serveur fausse (NTP mort, VM reprise, dérive)
- mauvais certificat déployé (le bon est renouvelé, mais pas reload)
- SNI mal configuré (tu sers le cert du mauvais vhost)
- certificat du CDN / proxy expiré (et toi tu regardes sur le serveur d’origine…)
Bref. Avant d’« agir », il faut savoir où est le point de terminaison TLS. C’est lui qui compte.
Pourquoi c’est si violent quand ça arrive
Un certificat expiré, ce n’est pas juste un warning.
- Conversion en chute libre : l’utilisateur voit un écran rouge. Il fuit.
- API cassée : les clients mobiles refusent souvent la connexion.
- Automatisations HS : webhooks, intégrations, partenaires B2B.
- SEO et confiance : Google n’aime pas les sites qui font peur.
- Support qui brûle : tickets, messages, Slack, appels.
Et le plus frustrant : tu peux être excellent en infra, avoir des backups, du monitoring CPU, des dashboards Grafana… et te faire avoir par une date.
Les causes les plus fréquentes (et très humaines)
1) « Let’s Encrypt renouvelle tout seul », sauf quand non
Let’s Encrypt renouvelle bien… si :
- le cron tourne
- le challenge passe (HTTP-01 ou DNS-01)
- le port 80/443 est accessible comme attendu
- le DNS pointe au bon endroit
- le rate limit n’est pas atteint
- le serveur redémarre ou reload après renouvellement
Il suffit d’un petit changement réseau, d’un WAF plus strict, d’un redirect mal placé, d’un port 80 fermé « temporairement », et le renouvellement échoue silencieusement.
2) Le certificat est renouvelé, mais le service ne recharge pas
Classique : certbot a renouvelé, les fichiers sur disque sont OK, mais Nginx tourne toujours avec l’ancien certificat chargé en mémoire.
Résultat : tu testes le fichier, tout est bon. Tu testes le site, tout est mauvais.
3) Des environnements oubliés
Tu surveilles prod. Mais le domaine staging, ou le sous domaine admin, ou l’ancienne landing page, ou un vieux endpoint API est encore utilisé par un client.
Et lui, il tombe en panne. Surprise.
4) Certificats multipliés partout
Un peu sur le serveur, un peu sur Cloudflare, un peu sur un load balancer, un peu sur un ingress. Chaque couche peut avoir son propre certificat, sa propre date, son propre mode de renouvellement.
Si tu n’as pas une cartographie, tu joues à cache cache.
Le plan anti incident : une stratégie en 3 couches
Je te propose une approche très simple, mais solide :
- inventaire de tous les endpoints TLS
- monitoring des dates d’expiration avec alertes
- automatisation du renouvellement et du reload
Et en bonus : un runbook court, parce que quand ça pète, tu n’as pas envie de réfléchir.
Couche 1 : inventaire, sinon tu surveilles le mauvais truc
Tu dois lister tout ce qui présente du TLS :
- domaines principaux
- sous domaines
- API
- endpoints partenaires
- load balancers
- ingress
- CDN (si terminaison TLS au CDN)
- services internes (oui, aussi)
Astuce rapide : si tu as une zone DNS, exporte les enregistrements et commence par là. Même si ça ne donne pas tous les endpoints, ça te donne un terrain.
Commandes utiles pour vérifier un certificat
Sur une machine quelconque :
bash echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates -issuer -subject
Juste la date de fin :
bash echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null
| openssl x509 -noout -enddate
Tu peux même automatiser une extraction propre :
bash DOMAIN="example.com" ENDDATE=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null
| openssl x509 -noout -enddate | cut -d= -f2) echo "$DOMAIN -> $ENDDATE"
Oui, c’est old school. Mais c’est fiable, et ça te donne la vérité côté client.
Couche 2 : monitoring et alertes (ne pas attendre J-0)
Tu veux des alertes à :
- J-30
- J-14
- J-7
- J-3
- J-1
Pourquoi autant ? Parce que les problèmes de renouvellement ne se règlent pas toujours en 5 minutes. Surtout si tu dois toucher au DNS, à un firewall, à un provider.
Option A : Uptime Kuma, simple et efficace
Uptime Kuma sait surveiller l’expiration TLS. Tu ajoutes un monitor HTTPS, et tu actives l’alerte certificat. Très pratique pour petites équipes, freelances, side projects.
Option B : Prometheus + blackbox exporter (setup plus pro)
Le blackbox exporter peut mesurer l’expiration et exposer une métrique. Tu alertes ensuite via Alertmanager.
Tu surveilles aussi la chaîne, le handshake, etc. C’est propre.
Option C : un script cron + envoi e mail / Slack
Parfois, tu veux juste un truc qui marche en 20 minutes.
Pseudo logique :
- récupérer la date de fin avec openssl
- calculer le nombre de jours restants
- si inférieur à un seuil, envoyer une alerte
Ça fait le job. Et franchement, c’est déjà mieux que 80 % des systèmes « pas encore mis en place ».
Couche 3 : renouvellement automatisé + reload automatique
C’est là que la plupart des gens se plantent. Ils automatisent le renouvellement, mais pas le reload.
Let’s Encrypt avec certbot (Nginx)
Généralement :
bash sudo certbot renew
Mais le vrai point, c’est le hook de déploiement :
bash sudo certbot renew --deploy-hook "systemctl reload nginx"
Ou mieux, tu mets ça dans un fichier de hook. Comme ça, à chaque renouvellement réussi, Nginx recharge.
Vérifie aussi les timers systemd :
bash systemctl list-timers | grep certbot
Et les logs :
bash journalctl -u certbot --since "7 days ago"
Attention au port 80 et aux redirects
HTTP-01 passe par /.well-known/acme-challenge/.
Si tu forces tout en HTTPS, c’est OK si c’est bien géré, mais certains setups cassent le challenge. Ne suppose pas. Teste.
DNS-01 si tu es derrière un proxy ou un CDN
Si ton trafic passe par Cloudflare et que tu veux éviter les soucis, DNS-01 est souvent plus stable. Mais il faut gérer l’API DNS (token, permissions minimales, rotation).
Pour les environnements sérieux, DNS-01 est souvent le meilleur choix, surtout si ton infra bouge.
Les erreurs qui font mal, et comment les éviter
Erreur : se baser sur le fichier au lieu du endpoint
Tu regardes /etc/letsencrypt/live/.../fullchain.pem et tu vois une date OK. Mais le navigateur voit autre chose.
Toujours vérifier le endpoint, comme un client externe.
Erreur : oublier le certificat intermédiaire
Certains navigateurs récupèrent l'intermédiaire via AIA. D'autres non. Certains clients Java sont plus stricts.
Assure-toi de servir fullchain.pem et pas juste cert.pem.
Sur Nginx :
nginx ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
Erreur : pas d'horloge fiable
Un serveur avec une horloge fausse peut te faire croire qu'un certificat est « pas encore valide » ou « expiré ».
Active NTP, vérifie timedatectl.
Erreur : aucun runbook
Quand ça arrive, tu perds du temps à te souvenir « où c'est », « qui gère », « comment on renew ».
Fais un runbook court, même une page Markdown.
Un runbook minimal (à copier coller)
Quand alerte « certificat bientôt expiré » ou incident en cours :
- Identifier l'endpoint touché (domaine exact, port, SNI).
- Vérifier la date vue par le client :
bash DOMAIN="example.com" echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN:443" 2>/dev/null | openssl x509 -noout -dates - Déterminer où se fait la terminaison TLS : CDN, LB, ingress ou serveur.
Si Let's Encrypt sur serveur
- Lancer
certbot renew --dry-runet vérifier les erreurs. - Renouveler puis recharger le service.
- Re-vérifier le endpoint.
- Noter la cause (port 80 fermé, DNS, hook absent, etc.) et corriger définitivement.
C'est basique. Mais dans le feu, le basique sauve.
Cas particulier : Kubernetes et ingress
Si tu es sur Kubernetes, tu as souvent cert-manager.
Ce qui peut mal tourner :
- ClusterIssuer mal configuré
- solver HTTP-01 cassé par une ingress rule
- secret TLS non mis à jour
- rate limits
À surveiller :
bash kubectl get certificates -A kubectl describe certificate -n kubectl get challenges -A kubectl get orders -A
Et surtout, surveille l’expiration des secrets TLS exposés, pas seulement l’objet Certificate. Parce que parfois, la ressource est là… mais le secret n’a pas été mis à jour comme tu crois.
Checklist prévention (celle que tu veux avoir en place)
- liste des domaines et sous domaines en service
- surveillance expiration TLS sur chaque endpoint public
- alertes J-30, J-14, J-7, J-3, J-1
- renouvellement automatisé testé (
--dry-run) - hook de reload après renouvellement
- runbook incident TLS en 1 page
- audit trimestriel des domaines oubliés
- NTP actif sur serveurs impliqués
- documentation « où se termine TLS » (CDN, LB, serveur)
Ça, c’est la base. Après tu peux raffiner.
Deux trois habitudes qui changent tout (vraiment)
1) Tester le renouvellement comme un exercice
Une fois par mois, lance un --dry-run. Pas pour faire joli. Pour détecter les changements qui ont cassé le challenge.
2) Avoir une vue unique, même si ton infra est dispersée
Même un simple tableau Notion ou un fichier tls-endpoints.md dans un repo privé. Tu mets :
- domaine
- où est le TLS
- méthode de renouvellement
- owner
- lien dashboard monitoring
C’est idiot, mais ça évite les « je croyais que c’était toi ».
3) Ne pas dépendre d’une seule alerte
Tu peux avoir :
- une alerte externe (Uptime Kuma, StatusCake, etc.)
- une alerte interne (Prometheus, script cron)
Double ceinture. Parce que si ton monitoring interne tombe, il ne t’alerte plus. Logique.
Et si tu gères des sites pour des clients (freelance, agence)…
C’est encore plus important.
Parce que l’expiration TLS, côté client, est perçue comme un manque de sérieux immédiat. Même si toi tu sais que « c’est juste un cert ».
Si tu fais du freelancing, du growth, du SEO, ou que tu gères des tunnels de vente, tu sais déjà le coût d’une page qui ne charge pas.
D’ailleurs, sur Le Blog Tech Pro de Samyn-Antoy ABASSE ( https://monblog-sa-abasse.blogspot.com ), je partage souvent ce genre de checklist très terrain, mélange sysadmin et business. Parce que c’est ça la réalité quand tu bosses en ligne. La technique impacte le chiffre, direct.
Si tu veux, tu peux enregistrer le blog dans tes favoris ou t’abonner, ça évite de perdre l’article au moment où tu en as besoin.
Conclusion : rendre l’expiration impossible à « surprendre »
Un TLS expiré, ce n’est pas une fatalité. C’est un défaut de visibilité, ou un automatisme incomplet.
Tu veux juste :
- savoir quels endpoints existent
- être alerté suffisamment tôt
- automatiser le renouvellement, et le reload
- documenter le minimum
Et après, tu passes à autre chose. A des choses plus intéressantes, franchement.
Si tu veux, dis moi ton contexte (Nginx ? Cloudflare ? Kubernetes ? plusieurs domaines clients ?) et je peux te proposer une stack de monitoring et une checklist adaptée, sans usine à gaz.
Questions fréquemment posées
Qu'est-ce qu'un certificat TLS expiré et pourquoi cause-t-il des pannes sur un site ou une API ?
Un certificat TLS expiré est un certificat X.509 dont la date de fin (notAfter) est dépassée. Lorsqu'un certificat expire, les navigateurs modernes affichent une alerte rouge, ce qui fait fuir les utilisateurs, casse les API, impacte le SEO et génère beaucoup de support. C'est souvent la cause principale des pannes 'incompréhensibles' sur les sites web et API.
Quels sont les problèmes courants liés aux certificats TLS au-delà de l'expiration ?
Outre l'expiration, on peut rencontrer : une chaîne intermédiaire manquante, une horloge serveur fausse (problème NTP), un mauvais certificat déployé sans rechargement du service, une mauvaise configuration SNI, ou un certificat expiré sur un CDN ou proxy. Tous ces cas peuvent provoquer des erreurs TLS.
Pourquoi le renouvellement automatique avec Let's Encrypt peut-il échouer ?
Le renouvellement automatique via Let's Encrypt dépend que plusieurs conditions soient réunies : que le cron tourne, que le challenge HTTP-01 ou DNS-01 passe, que les ports 80/443 soient accessibles, que le DNS pointe correctement, et que les limites de taux ne soient pas atteintes. Un changement réseau, un WAF strict ou un port fermé peuvent faire échouer silencieusement le renouvellement.
Comment éviter que le certificat renouvelé ne soit pas pris en compte par le serveur ?
Il faut s'assurer qu'après le renouvellement du certificat (par exemple via certbot), le service web (Nginx, Apache) soit rechargé pour prendre en compte le nouveau certificat en mémoire. Sans ce rechargement, même si les fichiers sont à jour sur disque, le serveur continue d'utiliser l'ancien certificat expiré.
Quels sont les risques liés à la gestion de plusieurs environnements et certificats ?
Oublier de surveiller des environnements comme staging, sous-domaines admin ou anciens endpoints peut entraîner des pannes inattendues pour certains clients. De plus, avoir des certificats dispersés sur différents serveurs, CDN, load balancers ou ingress sans cartographie claire complique la gestion et augmente le risque d'expiration non détectée.
Quelle stratégie adopter pour prévenir efficacement les incidents liés aux certificats TLS expirés ?
Adopter une discipline basée sur la visibilité (logs et alertes claires), l'automatisation du renouvellement et du rechargement des services, ainsi qu'une ou deux ceintures de sécurité (surveillance multi-couches). Cette méthode permet de transformer l'expiration d'un certificat en un non-événement géré automatiquement sans impact utilisateur.
0 Commentaires