Le WordPress d'aujourd'hui, décodé pour les développeurs

Hébergement & serveurs

« SSL handshake failed » entre un CDN et une origine mal configurée

Après un renouvellement de certificat côté origine, certaines requêtes du CDN échouent de façon intermittente. Diagnostic complet d'un échec de négociation TLS entre deux couches d'infrastructure.

Par WordPress Développement • 18 août 2022 • 5 min de lecture • Aucun commentaire
« SSL handshake failed » entre un CDN et une origine mal configurée

SSL handshake failed: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure. Cette ligne, remontée par les journaux du CDN à raison d’environ une requête sur six pendant plusieurs heures, ne correspondait à aucune alerte côté navigateur : les visiteurs continuaient de voir le site s’afficher normalement, cadenas compris. Le problème ne se situait pas entre le visiteur et le CDN, mais entre le CDN et le serveur d’origine.

Ce cas concerne un site WordPress dont le CDN était déjà en place et fonctionnel depuis plusieurs mois ; la mise en place initiale de ce CDN n’est pas le sujet ici. L’incident a démarré juste après le renouvellement automatique du certificat TLS sur l’un des trois serveurs d’origine d’une ferme derrière un répartiteur de charge.

Symptôme : des échecs intermittents et invisibles pour l’utilisateur

Le comportement le plus déroutant de cet incident tenait à son intermittence. Sur trois serveurs d’origine identiques en apparence, un seul renvoyait des échecs de négociation TLS au CDN, sans qu’aucune erreur ne soit visible côté public : le CDN, configuré pour retenter automatiquement sur un autre serveur d’origine en cas d’échec, masquait le problème aux visiteurs tout en dégradant silencieusement les temps de réponse moyens.

Diagnostic : isoler le serveur fautif

L'essentiel à retenir : Distinguer le certificat vu du navigateur et celui vu du CDN ; Vérifier la chaîne intermédiaire, pas seulement le certificat feuille ; Tester la négociation TLS avec openssl côté origine

Première étape du diagnostic : interroger directement chaque serveur d’origine, en contournant le répartiteur de charge et le CDN, avec openssl s_client pointé successivement sur chacune des trois adresses IP internes.

openssl s_client -connect 10.0.4.12:443 -servername exemple.fr -tls1_2

CONNECTED(00000003)
depth=0 CN = exemple.fr
verify error:num=21:unable to verify the first certificate
---
Certificate chain
 0 s:CN = exemple.fr
   i:C = US, O = Let's Encrypt, CN = R3
---
SSL handshake has read 1834 bytes and written 391 bytes
New, TLSv1.2, Cipher is ECDHE-RSA-AES128-GCM-SHA256

La commande a mis en évidence un détail facile à manquer : sur le serveur fautif, le certificat feuille était bien présent et valide, mais la chaîne intermédiaire renvoyée était incomplète. Le renouvellement automatique venait de basculer d’une autorité intermédiaire à une autre chez Let’s Encrypt, et le fichier de chaîne complète (fullchain.pem) n’avait pas été régénéré correctement sur ce serveur précis lors du dernier passage du script de renouvellement.

Pourquoi le CDN, spécifiquement, était sensible

Un navigateur classique tolère souvent une chaîne intermédiaire incomplète, car il peut aller chercher lui-même le certificat manquant via l’extension AIA (Authority Information Access) du certificat, ou dispose déjà de l’intermédiaire en cache local. Le CDN, lui, effectuait une validation stricte de la chaîne complète sans ce filet de rattrapage, rejetant purement et simplement la connexion vers cette origine dès que la chaîne était incomplète.

Correctif : régénérer et vérifier la chaîne complète

Le correctif a consisté à forcer une régénération du certificat sur le serveur concerné, en vérifiant explicitement le contenu du fichier de chaîne avant de redémarrer le service web.

  • Régénération forcée du certificat via certbot renew --force-renewal sur le serveur identifié.
  • Vérification du fichier fullchain.pem avec openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout, qui doit afficher deux entrées : le certificat du site et l’intermédiaire.
  • Rechargement du service nginx (et non un simple redémarrage) pour prendre en compte le nouveau certificat sans coupure de connexion.
  • Nouveau test openssl s_client confirmant une chaîne complète et une négociation TLS 1.2 réussie sans avertissement.

Prévention : surveiller chaque origine, pas seulement le domaine public

La leçon la plus utile de cet incident concerne la supervision. Un test de certificat classique, effectué depuis l’extérieur sur le nom de domaine public, ne passe que par le CDN et ne révèle jamais l’état réel de chaque serveur d’origine derrière lui. Une supervision efficace doit interroger directement chaque adresse IP d’origine, en contournant volontairement le CDN, pour détecter ce genre de divergence avant qu’elle ne dégrade le service.

Un repère qu’on applique systématiquement depuis cet incident : sur une ferme de plusieurs serveurs d’origine, tester chaque nœud individuellement après chaque renouvellement de certificat, jamais uniquement le nom de domaine public.

En résumé

Un échec de négociation TLS entre un CDN et son origine peut rester totalement invisible côté utilisateur final tout en dégradant la fiabilité du service de façon insidieuse. La cause tient souvent à une chaîne de certificats intermédiaire incomplète, plus tolérée par les navigateurs que par les CDN eux-mêmes. Une vérification systématique de chaque serveur d’origine après tout renouvellement automatique de certificat reste la meilleure prévention contre ce type d’incident silencieux.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi