
Quelqu’un vous dit que votre site n’est pas sécurisé. Vous l’ouvrez : cadenas, pas d’avertissement, certificat valide pour encore quatre mois. Vous lui demandez d’essayer à nouveau et ça échoue toujours, sur un réseau que vous ne pouvez pas atteindre, avec un client que vous n’avez pas.
Ni l’un ni l’autre n’a tort, et le certificat n’est pas le problème. Ce qui diffère, c’est tout ce qui se trouve dessous.
Un certificat n’est pas approuvé de lui-même
Votre certificat n’affirme pas qu’il est digne de confiance. Il est signé par un certificat intermédiaire, qui est lui-même signé par une racine, et seule la racine se trouve dans le magasin de certificats de confiance du visiteur. À la connexion, il s’agit de construire ce chemin, et c’est au serveur de fournir le maillon du milieu.
TLS 1.3 spécifie ce que le serveur envoie, et la formulation mérite d’être lue attentivement :
certificate_list : Une séquence (chaîne) de structures CertificateEntry, chacune contenant un certificat unique et un ensemble d’extensions.
Et puis vient la règle qui est généralement ignorée :
Le certificat de l’émetteur DOIT être le premier CertificateEntry de la liste. Chaque certificat suivant DEVRAIT certifier directement celui qui le précède immédiatement. Parce que la validation des certificats exige que les ancres de confiance soient distribuées indépendamment, un certificat qui spécifie une ancre de confiance PEUT être omis de la chaîne, à condition que les pairs pris en charge soient connus pour posséder les certificats omis.
Lisez attentivement la dernière phrase. L’ancre de confiance, c’est-à-dire la racine, peut être omise, car les clients la possèdent déjà. Rien ici ne justifie d’omettre l’intermédiaire. Votre serveur est supposé envoyer tout ce qui se trouve entre votre certificat et la racine, et un intermédiaire est précisément cela.
La mauvaise configuration que vous ne verrez jamais vous-même
Omettre l’intermédiaire ne produit pas un site à moitié défaillant. Cela produit un site qui fonctionne parfaitement pour vous mais échoue pour les autres, ce qui est un résultat considérablement plus coûteux.
Mozilla a décrit le fait de ne pas spécifier les certificats CA intermédiaires appropriés comme « l’un des problèmes de configuration de serveur les plus courants », et a fait quelque chose pour y remédier : Firefox précharge les certificats CA intermédiaires à l’avance, dans une liste qui « contient plus de deux mille entrées », spécifiquement pour réduire les « erreurs d’émetteur inconnu lors de la poignée de main TLS ».
Prenez le temps de saisir ce que cela signifie. Les navigateurs compensent activement cette erreur. Un navigateur qui possède déjà l’intermédiaire complètera la connexion que votre serveur l’ait envoyé ou non, de sorte que votre propre test réussit et la mauvaise configuration reste invisible. Cette compensation est une bonne conception, et c’est aussi la raison pour laquelle personne ne s’en aperçoit.
Pourquoi un client échoue là où un autre réussit
Il existe un deuxième mécanisme qui masque le problème, et il provient du certificat lui-même.
Un certificat peut nommer où le certificat de son issuer peut être trouvé. RFC 5280 définit ce champ et est prudent sur ses fins :
l’OID id-ad-caIssuers est utilisé quand les informations supplémentaires listent les certificats qui ont été émis à l’AC qui a émis le certificat contenant cette extension. La description de l’AC issuer référencée est destinée à aider les utilisateurs de certificats dans la sélection d’un chemin de certification
« Destinée à aider » est la phrase clé. C’est un pointeur, pas une obligation. Un client peut le suivre et récupérer la pièce manquante, et un client peut refuser. Les deux sont conformes.
La spécification TLS est tout aussi honnête sur l’état du monde, notant que les serveurs envoient parfois des certificats supplémentaires ou mal ordonnés et que « d’autres sont simplement mal configurés », avant de demander aux implémentations d’être tolérantes à ce sujet.
- Ce avec quoi vous avez testé
- Un navigateur de bureau récent, qui précharge des milliers d'intermédiaires et récupérera un issuer manquant si nécessaire. Le client le plus indulgent que vous possédez
- Ce que votre visiteur a utilisé
- Quelque chose de plus strict ou plus ancien, qui valide uniquement ce qu'il a reçu et signale un issuer inconnu quand la chaîne ne remonte pas jusqu'à une racine
Donc la tolérance est une décision du client plutôt qu’une propriété de votre configuration, et vous avez testé avec le client le plus susceptible de vous pardonner.
Les rapports que cela génère réellement
Parce que les clients indulgents sont les navigateurs, les défaillances se situent ailleurs, et elles arrivent rarement décrites comme un problème de certificat.
- Un webhook arrête d’être livré. Le serveur de quelqu’un d’autre est maintenant le client, et il n’a pas de liste préchargée et n’a aucun intérêt à récupérer votre issuer.
- Une application mobile ne peut pas se connecter alors que le même compte fonctionne sur le web, parce que la pile réseau de l’application n’est pas le navigateur système.
- Une intégration de paiement ou d’expédition échoue par rapport à votre URL de rappel, généralement avec un message sur un issuer inconnu ou non approuvé.
- Un bureau ou un appareil plus ancien ne peut pas atteindre le site du tout, et tout le monde d’autre le peut.
Aucun de ceux-ci ne ressemble à « la chaîne de certificats est incomplète », c’est pourquoi les heures se perdent au mauvais endroit en premier.
L’intermédiaire est l’unité du rayon d’impact
Une autre bonne raison de savoir quel intermédiaire vous utilisez, que vous le transmettiez ou non.
Un intermédiaire signe un grand nombre de certificats. Si l’un est retiré, discrédité ou autorisé à expirer, tous les certificats qu’il a signés cessent d’être valides au même moment. Votre certificat peut être à des mois de sa propre expiration, inchangé, et toujours échouer, car ce qui s’est cassé est un maillon au-dessus et n’a jamais été le vôtre.
La plupart des outils de surveillance des certificats regardent une seule date : celle à laquelle votre certificat expire. C’est la bonne date à surveiller, mais ce n’est pas la seule, et l’autre date appartient à un certificat que vous n’avez pas choisi et que vous ne pouvez probablement pas nommer.
Vérifier cela prend environ trente secondes
Demandez au serveur ce qu’il envoie réellement, depuis quelque chose qui n’est pas votre navigateur :
openssl s_client -showcerts -connect example.com:443 -servername example.com </dev/null
Deux choses à lire dans la sortie. Comptez les certificats : une chaîne publique typique transmet votre certificat et au moins un intermédiaire, donc exactement un certificat est le symptôme classique de ce défaut. Ensuite, lisez l’issuer de votre propre certificat et vérifiez qu’un certificat avec ce subject est présent plus bas.
Session Replay
Extension Chrome gratuite. Un clic sur la page qui ne fonctionne pas capture la capture d'écran, la console et le journal réseau, et vous fournit un lien à coller dans le ticket.
Si ce que vous recevez est une capture d’écran d’un écran d’avertissement à la place, les cinq défauts différents derrière cette page valent la peine d’être séparés avant de commencer : votre connexion n’est pas privée.
Ce qu’il faut en retenir
Un certificat est un lien, pas un justificatif. Il est approuvé parce qu’un chemin peut être construit à partir de celui-ci vers quelque chose que le visiteur fait déjà confiance, et votre serveur est responsable du maillon du milieu.
Le mode de défaillance est inhabituellement cruel parce que la compensation est si bonne. Les navigateurs préchargent des milliers d’intermédiaires et poursuivront un issuer manquant, de sorte que le client avec lequel vous testez est le client le moins susceptible de vous le dire. Ceux qui vous le disent sont les webhooks, les applications mobiles et les intégrations de paiement, et ils vous le disent en mots qui ne mentionnent jamais les certificats.
Les spécifications sont RFC 8446 pour ce qu’un serveur doit envoyer et RFC 5280 pour le champ qui nomme l’emplacement d’un issuer.