Un certificat SSL/TLS expiré coupe l'accès à votre site ou à votre API en quelques secondes : les navigateurs affichent une erreur bloquante, et vos clients ne voient plus rien. Sur un VPS Linux ou un serveur dédié, la commande openssl s_client permet aux administrateurs de diagnostiquer l'état d'un certificat SSL sans navigateur et sans accès à une interface d'administration. Ce tutoriel explique comment lire la date d'expiration, vérifier le nom de domaine couvert, tester la chaîne de confiance et intégrer ces contrôles dans des scripts de supervision automatique.
Pourquoi vérifier un certificat SSL en ligne de commande
Les interfaces d'administration de Let's Encrypt, de Certbot ou de votre hébergeur montrent la date d'expiration d'un certificat SSL, mais elles ne reproduisent pas ce qu'un client réel voit au moment de la connexion. openssl s_client se comporte comme un vrai client TLS : il ouvre la connexion réseau, reçoit le certificat envoyé par le serveur et vérifie la chaîne de certification. En tant qu'administrateur système, vous pouvez ainsi détecter :
- un certificat SSL expiré ou dont l'expiration est proche ;
- un certificat renouvelé mais dont les fichiers de configuration du serveur web n'ont pas encore été rechargés (
sudo systemctl reload nginx) ; - un nom de domaine absent du champ Subject Alternative Name (SAN) du certificat ;
- une chaîne de certification incomplète (le serveur n'envoie pas les certificats intermédiaires) ;
- une adresse IP qui sert un certificat SSL différent de celui attendu après une migration.
L'outil est disponible sur toutes les distributions Linux modernes dans le paquet openssl. Sur Ubuntu et Debian, il est préinstallé. Pour l'installer sur un serveur CentOS ou Rocky Linux : sudo dnf install openssl. Aucun redémarrage du serveur n'est nécessaire après installation.
Contrairement à un panneau d'administration qui liste les certificats SSL stockés localement, openssl s_client interroge le certificat tel qu'il est présenté en production sur l'adresse IP et le port TCP du serveur. C'est la seule façon de détecter un décalage entre le certificat renouvelé sur le disque et celui encore servi par le daemon web.
Lire la date d'expiration avec openssl s_client
La commande de base de ce tutoriel combine openssl s_client pour établir la connexion TLS et openssl x509 pour lire le certificat SSL reçu :
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null \
| openssl x509 -noout -dates
La sortie ressemble à :
notBefore=Jan 15 00:00:00 2026 GMT
notAfter=Apr 15 23:59:59 2026 GMT
Détail de chaque option :
-connect example.com:443: adresse IP ou nom de domaine et port TCP du service TLS. HTTPS utilise le port 443 par défaut.-servername example.com: envoie le Server Name Indication (SNI) pour que le serveur retourne le bon certificat SSL sur un hébergement mutualisé.</dev/null: ferme l'entrée standard pour ques_clientne reste pas en attente de saisie.2>/dev/null: supprime les messages de diagnostic qui pollueraient le pipeline.openssl x509 -noout -dates: affiche les champsnotBeforeetnotAftersans réafficher le certificat encodé.
Pour n'afficher que la date d'expiration, remplacez -dates par -enddate :
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null \
| openssl x509 -noout -enddate
Résultat typique : notAfter=Apr 15 23:59:59 2026 GMT. Comparez cette date avec la sortie de date -u pour calculer le nombre de jours restants. Les administrateurs qui supervisent plusieurs serveurs vps préfèrent automatiser ce calcul avec un script conf dédié.
Comprendre le SNI : pourquoi -servername est obligatoire
Un même serveur peut héberger plusieurs sites web sous une seule adresse IP grâce aux virtual hosts Nginx ou Apache. Le Server Name Indication est une extension TLS qui indique au serveur, avant même l'échange de certificat SSL, quel nom d'hôte le client cherche à atteindre. Sans -servername, le serveur retourne son certificat par défaut selon sa configuration, qui peut être différent de celui attendu.
Sur un VPS Linux hébergeant plusieurs sites web avec Nginx en virtual hosts, omettre -servername est la cause la plus fréquente d'une erreur de vérification du certificat SSL qui n'existe pas dans un navigateur. C'est aussi pour cette raison que le fichier de configuration du serveur doit inclure la directive ssl_certificate_key et un bloc server_name correct.
Lorsque vous connaissez l'adresse IP du serveur mais souhaitez tester un URL précis, passez l'adresse IP dans -connect et le nom de domaine dans -servername :
openssl s_client \
-connect 203.0.113.10:443 \
-servername example.com \
</dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -enddate
Cette technique permet aux administrateurs de tester le certificat SSL sur une adresse IP dont le DNS pointe encore vers l'ancienne adresse lors d'une migration vers un nouveau VPS ou un nouveau serveur dédié.
Vérifier les noms de domaine couverts (SAN)
La validation d'un certificat SSL repose sur le champ Subject Alternative Name (SAN), pas sur le champ Common Name (CN) qui est déprécié pour cette utilisation. Un certificat expiré et un certificat dont le SAN ne couvre pas votre domaine produisent tous deux une erreur dans les navigateurs et les clients HTTP. Pour afficher le SAN :
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null \
| openssl x509 -noout -text \
| grep -A1 "Subject Alternative Name"
Exemple de sortie :
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com
Pour vérifier qu'un nom de domaine précis est couvert, sauvegardez le certificat et utilisez -checkhost :
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null \
| openssl x509 > /tmp/leaf.pem
openssl x509 -in /tmp/leaf.pem -noout -checkhost example.com
La commande affiche Hostname example.com does match certificate si le domaine est présent, ou un message d'échec. Pensez à faire un backup de vos fichiers de configuration avant de modifier les directives SSL dans votre conf Nginx ou Apache.
Détecter une expiration imminente avec -checkend
L'option -checkend d'openssl x509 compare la date d'expiration du certificat SSL avec l'heure système augmentée d'un nombre de secondes. Le code de sortie est exploitable directement dans des scripts d'administration :
- Code 0 : le certificat reste valide au-delà de l'intervalle spécifié.
- Code non nul : le certificat expire dans l'intervalle, est déjà expiré ou ne peut pas être lu.
Pour tester l'expiration dans les 30 prochains jours (2 592 000 secondes) depuis un serveur distant :
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null \
| openssl x509 -noout -checkend 2592000 \
&& echo "Valide plus de 30 jours" \
|| echo "EXPIRE dans moins de 30 jours ou deja expire"
Pour une alerte à 7 jours (604 800 secondes), adaptez la valeur dans vos scripts :
openssl s_client \
-connect example.com:443 \
-servername example.com \
</dev/null 2>/dev/null \
| openssl x509 -noout -checkend 604800 \
&& echo "OK : valide plus de 7 jours" \
|| echo "ALERTE : expire dans moins de 7 jours"
Sur un fichier certificat local dans /etc/letsencrypt/live/ (accessible avec sudo pour les administrateurs) :
sudo openssl x509 \
-in /etc/letsencrypt/live/example.com/cert.pem \
-noout \
-checkend 2592000
Cette variante est utile avant de redémarrer le daemon web, ou pour vérifier la date d'expiration sur un serveur qui n'est pas accessible de l'extérieur. L'authentification par clé SSH est requise pour administrer le serveur avec sudo depuis une connexion distante.
Vérifier la chaîne de confiance
Un certificat SSL de domaine valide ne suffit pas : si le fichier de configuration du serveur web n'inclut pas les certificats intermédiaires, les navigateurs modernes affichent une erreur "unable to get local issuer certificate". openssl s_client le détecte avec l'option -showcerts et la ligne Verify return code en fin de sortie :
openssl s_client \
-connect example.com:443 \
-servername example.com \
-showcerts \
</dev/null 2>&1 \
| grep -E "Verify return code|depth|issuer"
Un code Verify return code: 0 (ok) indique que la chaîne complète est présente et reconnue par le magasin de certificats système. Un code 20 (unable to get local issuer certificate) signifie que la conf du serveur n'envoie pas les certificats intermédiaires.
Pour une vérification stricte qui échoue dès le premier problème de chaîne ou d'authentification :
openssl s_client \
-connect example.com:443 \
-servername example.com \
-verify_hostname example.com \
-verify_return_error \
</dev/null
L'option -verify_return_error change le comportement par défaut de s_client qui, en mode diagnostic, continue même en cas d'erreur de certificat SSL. Ce mode est adapté aux scripts d'administration qui doivent échouer clairement en cas de problème de configuration.
Scripts de supervision multi-domaines
Pour superviser les certificats SSL de plusieurs domaines et sites web depuis votre VPS Linux, voici des scripts de monitoring à intégrer dans une tâche cron :
#!/bin/bash
DOMAINS="example.com api.example.com blog.example.com"
SEUIL_JOURS=30
SEUIL_SECONDES=$((SEUIL_JOURS * 86400))
for DOMAIN in $DOMAINS; do
CERT=$(openssl s_client \
-connect "${DOMAIN}:443" \
-servername "${DOMAIN}" \
</dev/null 2>/dev/null)
if echo "$CERT" | openssl x509 -noout -checkend "$SEUIL_SECONDES" 2>/dev/null; then
EXPIRY=$(echo "$CERT" | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
echo "OK ${DOMAIN} expire le ${EXPIRY}"
else
EXPIRY=$(echo "$CERT" | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
echo "WARN ${DOMAIN} expire le ${EXPIRY} (moins de ${SEUIL_JOURS} jours)"
fi
done
Ces scripts peuvent être enregistrés dans /usr/local/bin/check-ssl-expiry.sh (avec sudo chmod +x) et planifiés dans cron pour s'exécuter chaque nuit. Les administrateurs peuvent rediriger la sortie vers un fichier de log avec >> /var/log/ssl-check.log 2>&1. Sur un serveur dédié hébergeant plusieurs sites web, ils remplacent un outil de supervision externe pour les contrôles de certificats de base.
Cas pratiques : SMTP, IMAP, port non standard
openssl s_client fonctionne avec n'importe quel protocole TLS, pas seulement HTTPS. Pour vérifier le certificat SSL d'un serveur de messagerie SMTP avec STARTTLS :
openssl s_client \
-connect mail.example.com:587 \
-servername mail.example.com \
-starttls smtp \
</dev/null 2>/dev/null \
| openssl x509 -noout -dates
Pour un serveur IMAP en TLS natif (port 993, connexions TCP chiffrées dès le premier octet) :
openssl s_client \
-connect mail.example.com:993 \
-servername mail.example.com \
</dev/null 2>/dev/null \
| openssl x509 -noout -dates
Pour un service sur un port non standard, par exemple une API sur un VPS Linux accessible sur le port 8443, remplacez 443 par le numéro de port :
openssl s_client \
-connect api.example.com:8443 \
-servername api.example.com \
</dev/null 2>/dev/null \
| openssl x509 -noout -enddate
La même logique s'applique aux services HTTPS publiés derrière Nginx en reverse proxy : le certificat SSL vérifié est celui que Nginx présente aux clients, indépendamment du backend applicatif interne.
Erreurs courantes et leur interprétation
Voici les messages les plus fréquents lors de la vérification d'un certificat SSL et leur cause réelle :
- certificate has expired : la date
notAfterest dépassée. Renouvelez le certificat SSL avecsudo certbot renewpuis rechargez la conf du serveur avecsudo systemctl reload nginxousudo systemctl reload apache2. Un redémarrer complet avecsystemctl restartest nécessaire si le daemon ne supporte pas le reload. - hostname mismatch : le nom de domaine que vous testez n'est pas dans le champ SAN du certificat. Vérifiez avec
-ext subjectAltNameet régénérez le certificat en ajoutant le domaine manquant dans les fichiers de configuration de Certbot. - unable to get local issuer certificate (code 20) : la chaîne de certification est incomplète. Modifiez le fichier de configuration du serveur web pour pointer vers
fullchain.pem(Let's Encrypt) plutôt quecert.pemseul, puis effectuez un restart ou un reload. - self-signed certificate (code 18) : le certificat SSL a été signé par une autorité de certification privée non présente dans le magasin système. Comportement attendu sur un environnement de développement ou un intranet interne non exposé au public.
- Connexion refusee ou timeout : le port TCP TLS n'est pas ouvert ou est bloqué par un pare-feu. Vérifiez avec
ss -tlnpet consultez le guide lister les ports en écoute avec ss. Vérifiez aussi les règles avecsudo ufw status. - Sortie vide apres le pipe : la connexion TCP a échoué avant que
s_clientreçoive un certificat SSL. Supprimez2>/dev/nullprovisoirement pour afficher les erreurs de configuration et administrer le diagnostic.
Pour aller plus loin, le guide sécuriser un serveur dédié : premiers réglages couvre l'authentification SSH par clé, les règles de pare-feu et les mises à jour de sécurité automatiques.
Votre VPS Linux ElypseCloud dispose d'OpenSSL préinstallé et d'une connectivité réseau garantie pour que les administrateurs puissent exécuter ces diagnostics de certificats SSL depuis n'importe quel terminal.
Découvrir nos VPS Linux