## Introduction

L'expiration et la mauvaise configuration des certificats comptent parmi les causes les plus courantes de pannes évitables. Un certificat qui expire à 3 h du matin peut entraîner l'indisponibilité d'une API de production, d'un flux de paiement ou d'un portail client entier. Surveiller les certificats TLS et alerter sur leur état n'est pas optionnel pour les équipes qui accordent de l'importance à la disponibilité.

Ce guide s'adresse aux développeurs, ingénieurs DevOps, SRE et fondateurs techniques qui ont besoin d'une méthode pratique pour surveiller les certificats, configurer des alertes pertinentes et répondre aux incidents sans sur-ingénierie. Nous verrons comment inspecter les certificats avec OpenSSL, quelles métriques suivre, comment construire un tableau de bord simple et quoi faire en cas de problème.

Chaque commande de cet article peut être exécutée sans risque sur vos propres systèmes, et nous mettrons l'accent sur les vérifications en lecture seule, les changements minimaux et les chemins de récupération. À la fin, vous disposerez d'une liste de contrôle claire pour mettre en œuvre ou améliorer la surveillance TLS dans votre environnement.

## Inventaire des versions et de l'environnement

Avant de dépanner ou de surveiller, vous devez savoir à quoi vous avez affaire. Cela implique de capturer l'état actuel de vos certificats, les versions des logiciels et les points de terminaison concernés. Une erreur courante consiste à exécuter une commande qui suppose une version particulière d'OpenSSL ou un format de certificat. Vérifiez toujours les bases en premier.

### Vérifier la version d'OpenSSL

OpenSSL est l'outil de facto pour inspecter les certificats TLS, et son comportement change selon les versions. Exécutez :

openssl version 
 La sortie attendue ressemble à :

OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022) 
 Si vous êtes sur un système avec OpenSSL 1.1.1, certaines options comme -brief peuvent ne pas être disponibles. Vérifiez toujours la version avant de scripter.

### Lister les certificats sur un serveur

Sur un serveur Linux typique, les certificats sont souvent stockés sous /etc/ssl ou /etc/pki . Vous pouvez les lister avec :

find /etc/ssl -name "*.pem" -o -name "*.crt" 2>/dev/null 
 Cela vous aide à localiser les fichiers de certificats que vous devez inspecter. Notez les chemins ; vous les utiliserez dans les commandes suivantes.

### Identifier le sujet et l'expiration d'un certificat

Pour inspecter un fichier de certificat sans le modifier, utilisez :

openssl x509 -in /etc/ssl/certs/example.com.pem -noout -subject -issuer -dates -fingerprint -sha256 
 Exemple de sortie :

subject=CN = example.com
issuer=C = US, O = Let's Encrypt, CN = R3
notBefore=Jun 1 00:00:00 2024 GMT
notAfter=Aug 30 00:00:00 2024 GMT
SHA256 Fingerprint=3A:4B:5C:... (empreinte complète) 
 Enregistrez ces valeurs. Elles deviennent votre référence pour comparaison après tout changement.

### Tester un point de terminaison distant

Pour un serveur en ligne, utilisez openssl s_client :

echo | openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null | openssl x509 -noout -dates -subject 
 Sortie attendue :

subject=CN = example.com
notBefore=Jun 1 00:00:00 2024 GMT
notAfter=Aug 30 00:00:00 2024 GMT 
 Si la connexion échoue, vérifiez les règles de pare-feu ou si le service écoute sur le port 443.

## Chemin de configuration sécurisé

La surveillance ne doit jamais risquer de casser la production. Le chemin sécurisé implique :

- Observation en lecture seule : commandes qui ne modifient pas l'état.

- Validation non destructive : tester une configuration sans l'appliquer.

- Changements limités : appliquer uniquement ce qui est nécessaire, avec des options de retour en arrière.

- Vérification après changement : confirmer le résultat attendu avec une vérification.

### Valider une chaîne de certificats hors ligne

Avant de déployer un nouveau certificat, validez la chaîne avec :

openssl verify -CAfile /etc/ssl/certs/ca-certificates.crt -untrusted /etc/ssl/certs/intermediate.pem /etc/ssl/certs/example.com.pem 
 Sortie attendue en cas de succès :

/etc/ssl/certs/example.com.pem: OK 
 Si la chaîne est incomplète, vous verrez une erreur comme error 20 at 0 depth lookup: unable to get local issuer certificate . Corrigez la chaîne avant de l'appliquer.

### Tester une configuration de serveur web sans redémarrage

Si vous utilisez Nginx, vérifiez la configuration avec :

nginx -t 
 Sortie attendue :

nginx: configuration file /etc/nginx/nginx.conf test is successful 
 Seulement après que cela passe, rechargez :

systemctl reload nginx 
 Puis vérifiez que le certificat est servi :

echo | openssl s_client -connect localhost:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates 

### Automatiser le renouvellement en toute sécurité

 Si vous utilisez Let's Encrypt avec Certbot, effectuez d'abord un essai à blanc :

certbot renew --dry-run 
 Cela teste le renouvellement sans émettre réellement de certificats. Planifiez ensuite le renouvellement réel avec cron ou un timer systemd.

## Vérification et diagnostics

Une fois qu'un certificat est en place ou lorsque vous soupçonnez un problème, exécutez un ensemble systématique de vérifications.

### Vérifier la date d'expiration à distance

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate 
 Sortie attendue :

notAfter=Aug 30 00:00:00 2024 GMT 
 Calculez les jours restants avec un script simple :

expiry_date=$(echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
expiry_epoch=$(date -d "$expiry_date" +%s)
current_epoch=$(date +%s)
days_left=$(( (expiry_epoch - current_epoch) / 86400 ))
echo "$days_left jours restants" 
 Si le nombre est inférieur à 30, vous devriez déclencher une alerte.

### Vérifier la correspondance du nom d'hôte

Un certificat n'est valide que si son sujet ou SAN correspond au nom d'hôte demandé. Vérifiez avec :

echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -text | grep -A1 "Subject Alternative Name" 
 Sortie attendue :

X509v3 Subject Alternative Name:
 DNS:example.com, DNS:www.example.com 
 Si le nom d'hôte auquel vous vous connectez n'est pas listé, les clients obtiendront une erreur de certificat.

### Vérifier la chaîne de certificats présentée par le serveur

Assurez-vous que le serveur envoie la chaîne complète (feuille + intermédiaire) :

echo | openssl s_client -connect example.com:443 -showcerts 2>/dev/null | grep "s:" 
 Vous devriez voir au moins deux certificats : le certificat du serveur et l'intermédiaire. Les intermédiaires manquants provoquent des erreurs de confiance sur certains clients.

### Tester le protocole TLS et la suite de chiffrement

Confirmez que le serveur prend en charge TLS 1.2 ou 1.3 et des suites de chiffrement fortes :

echo | openssl s_client -connect example.com:443 -tls1_2 2>/dev/null | grep "Protocol\|Cipher" 
 Pour TLS 1.3 :

echo | openssl s_client -connect example.com:443 -tls1_3 2>/dev/null | grep "Protocol\|Cipher" 
 Si TLS 1.2 échoue mais que 1.3 fonctionne, vous pourriez avoir un problème de compatibilité pour les clients plus anciens.

## Modes de défaillance et récupération

Les certificats échouent de manière prévisible. Comprendre ces modes vous aide à répondre rapidement.

### Certificat expiré

Symptômes : Les navigateurs affichent « Votre connexion n'est pas privée », les API renvoient des erreurs SSL, les alertes de surveillance se déclenchent.

Diagnostic : Vérifiez la date d'expiration comme indiqué ci-dessus. Si notAfter est dans le passé, le certificat est expiré.

Récupération :

- Obtenez un nouveau certificat auprès de votre autorité de certification.

- Remplacez le fichier de certificat sur le serveur.

- Rechargez le serveur web :

systemctl reload nginx 

- Vérifiez avec openssl s_client que la nouvelle date d'expiration est dans le futur.

 Prévention : Configurez des alertes à 30, 14 et 7 jours avant l'expiration. Automatisez le renouvellement lorsque c'est possible.

### Non-correspondance du nom d'hôte

Symptômes : Le certificat est valide mais le navigateur se plaint d'une non-correspondance de nom.

Diagnostic : Comparez le nom d'hôte demandé avec la liste SAN du certificat.

Récupération :

- Si vous utilisez un certificat générique, assurez-vous que le caractère générique couvre le sous-domaine (par exemple, *.example.com couvre api.example.com ).

- Si le certificat est pour le mauvais domaine, émettez-en un nouveau avec les bons SAN.

- Mettez à jour la configuration du serveur pour utiliser le bon certificat.

### Chaîne incomplète

Symptômes : Certains clients (en particulier mobiles) échouent à vérifier, tandis que les navigateurs de bureau peuvent fonctionner car ils mettent en cache les intermédiaires.

Diagnostic : Utilisez openssl s_client -showcerts et vérifiez que l'intermédiaire est présent. Alternativement, utilisez un vérificateur SSL en ligne comme SSL Labs.

Récupération :

- Concaténez les certificats feuille et intermédiaire dans le bon ordre (feuille d'abord, puis intermédiaire).

- Pour Nginx, définissez ssl_certificate sur le fichier de chaîne complète.

- Rechargez et vérifiez.

### Certificat révoqué

Symptômes : Le certificat est dans sa période de validité mais rejeté par les clients.

Diagnostic : Vérifiez le statut de révocation avec OCSP :

openssl ocsp -issuer intermediate.pem -cert example.com.pem -url http://ocsp.example.com -text 
 Cherchez Cert Status: revoked ou good .

Récupération : S'il est révoqué, remplacez immédiatement le certificat. Enquêtez sur la raison de la révocation (clé compromise, mauvaise émission).

### Non-correspondance de la clé privée

Symptômes : Le serveur web ne démarre pas ou la poignée de main TLS échoue.

Diagnostic : Comparez le module du certificat et de la clé privée :

openssl x509 -noout -modulus -in example.com.pem | openssl md5
openssl rsa -noout -modulus -in example.com.key | openssl md5 
 Si les empreintes MD5 diffèrent, ils ne correspondent pas.

Récupération : Obtenez la bonne clé ou générez une nouvelle paire clé et certificat.

## Liste de contrôle opérationnelle

Voici une liste de contrôle concrète pour les opérations continues de certificats TLS. Attribuez un seul responsable pour chaque élément et révisez trimestriellement ou plus fréquemment.

<div class="my-stack-md overflow-x-auto">
<table class="min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">#</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Tâche</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Commande / Outil</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Fréquence</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Responsable</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Résultat attendu</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">1</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Vérifier l&#39;expiration de tous les certificats publics</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">echo | openssl s_client -connect &lt;hôte&gt;:443 2&gt;/dev/null | openssl x509 -noout -enddate</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Quotidienne (automatisée)</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Priya Shah, ingénieure DevOps</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">&gt; 30 jours restants</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">2</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Vérifier que le SAN correspond aux noms d&#39;hôte</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">openssl x509 -in cert.pem -noout -text | grep -A1 SAN</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Au déploiement</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Marcus Lee, responsable backend</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Tous les noms d&#39;hôte listés</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">3</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Tester la complétude de la chaîne de certificats</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">openssl s_client -showcerts</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Hebdomadaire</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Priya Shah</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Au moins feuille + intermédiaire</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">4</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Vérifier le statut de révocation OCSP</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">openssl ocsp -issuer intermediate.pem -cert leaf.pem -url http://ocsp.example.com</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Mensuelle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Priya Shah</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Statut : bon</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">5</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Valider que la clé privée correspond au certificat</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">openssl x509 -noout -modulus -in cert.pem | openssl md5</code> et <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">openssl rsa -noout -modulus -in key.pem | openssl md5</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Lors de la rotation des clés</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Marcus Lee</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Les empreintes MD5 correspondent</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">6</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Tester le processus de renouvellement (essai à blanc)</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">certbot renew --dry-run</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Mensuelle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Priya Shah</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Aucune erreur</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">7</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Surveiller la version du protocole TLS</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">openssl s_client -tls1_2 -connect hôte:443</code> et <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">-tls1_3</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Trimestrielle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Équipe sécurité</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">TLS 1.2 et 1.3 activés</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">8</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Revoir la configuration des alertes de surveillance</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Vérifier les règles d&#39;alerte dans Prometheus/Alertmanager</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Trimestrielle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Priya Shah</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Alertes déclenchées lors du test</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">9</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Mettre à jour l&#39;inventaire des certificats et des responsables</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Tenir à jour un tableur ou une CMDB</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Mensuelle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Marcus Lee</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Tous les certificats documentés</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">10</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Effectuer un exercice de réponse aux incidents pour l&#39;expiration d&#39;un certificat</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Simuler un certificat expiré dans l&#39;environnement de préproduction</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Annuelle</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Priya Shah</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Récupération en moins de 30 min</td></tr></tbody>
</table>
</div>

### Pièges courants et comment les éviter

- Ne pas configurer d'alertes : Les équipes comptent souvent sur des vérifications manuelles ou la mémoire. L'expiration à des heures indues passe inaperçue. Comment éviter : Mettez en place des vérifications automatisées avec Prometheus Blackbox Exporter ou un simple cron qui envoie une notification.

- Tester uniquement en production : Apporter des modifications directement en production sans tester en préproduction entraîne des temps d'arrêt. Comment éviter : Reproduisez votre configuration TLS dans un environnement de préproduction et testez-y d'abord.

- Coder en dur les chemins des certificats dans les scripts : Les chemins varient entre les serveurs et les environnements. Comment éviter : Utilisez des variables ou la gestion de configuration (Ansible, Puppet) pour gérer les chemins.

- Ignorer les certificats intermédiaires : Les nouveaux développeurs peuvent téléverser uniquement le certificat feuille, cassant la validation de la chaîne. Comment éviter : Incluez le fichier de chaîne complète fourni par votre autorité de certification et vérifiez avec openssl verify .

- Ne pas surveiller la révocation : Un certificat peut être valide mais révoqué. Comment éviter : Vérifiez périodiquement le statut OCSP et configurez l'agrafage OCSP sur votre serveur.

- Supposer que tous les clients prennent en charge la dernière version de TLS : Désactiver TLS 1.0/1.1 peut casser les clients hérités. Comment éviter : Analysez les journaux des clients avant de désactiver les anciens protocoles, et proposez un plan de dépréciation progressif.

- Ne pas tester le processus de renouvellement : Le renouvellement automatisé peut échouer silencieusement en raison de changements DNS ou de règles de pare-feu. Comment éviter : Exécutez certbot renew --dry-run mensuellement et surveillez les journaux de renouvellement réels.

- Stocker les clés privées dans le contrôle de version : Les clés dans les dépôts git sont un risque de sécurité. Comment éviter : Utilisez des outils de gestion des secrets comme HashiCorp Vault ou des variables d'environnement.

## Conclusion

La surveillance et les alertes des certificats TLS sont une pratique opérationnelle essentielle. En suivant les étapes de ce guide, vous pouvez :

- Identifier l'état actuel des certificats et des points de terminaison.

- Inspecter et valider les certificats en toute sécurité sans provoquer de perturbations.

- Diagnostiquer les modes de défaillance courants et récupérer rapidement.

- Établir une liste de contrôle de routine avec des responsables et des fréquences claires.

Commencez par une vérification à faible risque : exécutez la vérification de l'expiration sur votre point de terminaison le plus important, configurez une tâche cron pour vous alerter à 30 jours, et documentez les étapes de récupération. Étendez à partir de là. L'objectif est de rendre les défaillances de certificats visibles avant qu'elles ne deviennent des incidents.

N'oubliez pas qu'un flux de travail de surveillance TLS fiable protège vos utilisateurs, votre réputation et votre sommeil.