Introduction
Une équipe d’assistance vient de déployer un site d’aide, mais les clients refusent la connexion HTTPS. HTTPS utilise TLS pour chiffrer le trafic et prouver l’identité du serveur qui répond. Le chiffrement seul ne suffit pas : le client doit aussi reconnaître le nom demandé et faire confiance à l’émetteur du certificat.
Vous réparerez des certificats synthétiques de formation sur un vrai serveur Nginx. Une connaissance élémentaire du terminal suffit ; l’inspection des certificats et la configuration du service sont présentées ici. Client et Server sont des sessions et répertoires distincts sur une même VM, pas des ordinateurs séparés. Nginx fonctionne dans un conteneur préparé. HTTPS Monitor, facultatif, affiche des sondes TLS internes réelles ; le cadenas du navigateur concerne une autre connexion externe.
Récupérer un document de référence fiable
Dans cette étape, récupérez un document depuis un service fonctionnel avant de le comparer au site d’aide défaillant. Un nom d’hôte identifie le service demandé. Tous les noms de formation se terminent par .lab.test et sont locaux à cet exercice.
Utilisez l’onglet Client. curl récupère une URL. --cacert root.crt fait confiance à l’autorité de certification (CA) fournie, qui signe les certificats. Cette CA est une ancre de confiance de formation, pas une autorité publique. --resolve associe un nom et un port à une adresse IP tout en conservant ce nom pour TLS et HTTP. 127.0.0.1 désigne cette VM ; le port 8443 mène au service Nginx préparé. --noproxy '*' envoie directement la requête ; les guillemets empêchent le shell de développer *. --fail rejette les erreurs HTTP et --output enregistre le véritable document du service pour la suite.
curl --noproxy '*' --fail --cacert root.crt --resolve status.lab.test:8443:127.0.0.1 --output reference.txt https://status.lab.test:8443/
cat affiche le contenu d’un fichier :
cat reference.txt
status service: training content available
Ce téléchargement est un véritable document de référence, pas un rapport. Demandez maintenant le nom prévu pour le site d’aide. Cette commande doit échouer et rendre la main ; poursuivez ensuite.
curl --noproxy '*' --cacert root.crt --resolve help.lab.test:8443:127.0.0.1 https://help.lab.test:8443/
curl: (60) SSL: no alternative certificate subject name matches target host name 'help.lab.test'
...
La référence fonctionnait avec la même CA et la même adresse. Cette erreur indique précisément un nom incompatible, pas un serveur arrêté. Conservez le nom attendu : changer l’URL testerait une autre identité.
Inspecter et assembler la chaîne de certificats
Dans cette étape, comparez l’identité servie à un certificat préparé et construisez un ensemble utilisable par le serveur. Un certificat contient une clé publique et des informations d’identité. Sa clé privée correspondante reste sur le serveur. Ne collez jamais une clé privée dans un rapport et ne l’envoyez pas aux clients.
Dans Client, inspectez le certificat réellement servi. openssl s_client ouvre une connexion TLS ; -connect indique l’adresse et -servername envoie le nom demandé via Server Name Indication (SNI), permettant à un même point d’écoute Nginx d’héberger plusieurs sites. < /dev/null termine l’entrée interactive. 2>/dev/null masque les diagnostics uniquement pour cette inspection. Le tube | transmet le certificat à openssl x509 ; -noout masque le certificat encodé et les autres options affichent certains champs. Cette inspection ne prouve pas à elle seule la confiance.
openssl s_client -connect 127.0.0.1:8443 -servername help.lab.test </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltName
subject=CN = legacy.lab.test
issuer=CN = LabEx Training Issuing CA
notBefore=...
notAfter=...
X509v3 Subject Alternative Name:
DNS:legacy.lab.test
Le nom alternatif du sujet (SAN) liste les noms acceptés. issuer désigne le signataire ; les dates délimitent la validité. La préparation génère de nouveaux certificats pour cette VM : les certificats terminaux durent 365 jours. Une date valide ne compense pas un nom erroné.
Passez dans Server. openssl x509 -in lit un certificat local plutôt qu’une réponse réseau :
openssl x509 -in certs/help.crt -noout -subject -issuer -dates -ext subjectAltName
Son SAN est DNS:help.lab.test, conforme à la requête. Voici la relation attendue :
| Élément | Rôle |
|---|---|
help.crt et help.key |
Certificat du site d’aide et clé privée associée |
docs.crt et docs.key |
Certificat du site de documentation et clé privée associée |
issuing.crt |
CA intermédiaire ayant signé les deux sites |
../client/root.crt |
CA racine approuvée par le client |
La chaîne suit certificat du site → CA intermédiaire → CA racine approuvée. Nginx doit envoyer le certificat terminal en premier, puis l’intermédiaire. Le client fait déjà confiance à la racine, inutile de l’envoyer. Assemblez cet ensemble public avec cat ; > écrit la sortie dans un fichier, remplaçant son contenu précédent. La clé privée n’en fait pas partie.
cat certs/help.crt certs/issuing.crt > certs/help-fullchain.pem
openssl verify vérifie l’ensemble avec la racine approuvée indiquée. -untrusted fournit des intermédiaires comme liens possibles, pas comme racines supplémentaires ; -verify_hostname vérifie le nom prévu.
openssl verify -CAfile ../client/root.crt -untrusted certs/help-fullchain.pem -verify_hostname help.lab.test certs/help-fullchain.pem
certs/help-fullchain.pem: OK
En cas d’échec, vérifiez l’ordre et l’orthographe des fichiers, puis répétez cat. Cela valide l’ensemble préparé ; le serveur actif doit encore l’utiliser.
Appliquer l’identité du site d’aide
Dans cette étape, faites servir la bonne identité par Nginx tout en préservant le site d’état. Dans Server, affichez la configuration avec cat :
cat conf/help.conf
server_name sélectionne le site. ssl_certificate indique la chaîne publique ; ssl_certificate_key, sa clé privée. Les chemins commençant par /tls/ sont internes au conteneur Nginx et correspondent à certs/ dans ce répertoire. La ligne return 200 fournit le véritable contenu d’aide de formation. Conservez l’écoute, le nom et la réponse.
Ouvrez le fichier avec l’éditeur de texte nano :
nano conf/help.conf
Repérez les deux directives TLS avec les flèches. Remplacez uniquement ces deux lignes par :
ssl_certificate /tls/help-fullchain.pem;
ssl_certificate_key /tls/help.key;
Les points-virgules terminent les directives Nginx. Enregistrez avec Ctrl+O, appuyez sur Enter, puis quittez avec Ctrl+X. Si un chemin est mal saisi, rouvrez ce fichier et corrigez-le.
sudo exécute une commande avec les droits administrateur. docker exec https-edge exécute la commande suivante dans le conteneur préparé. nginx -t teste la configuration sans l’appliquer :
sudo docker exec https-edge nginx -t
Cherchez syntax is ok et test is successful. En cas d’échec, corrigez d’abord le fichier et la ligne indiqués. nginx -s reload demande au service actif de charger la configuration testée :
sudo docker exec https-edge nginx -s reload
Passez dans Client et répétez la requête attendue. Le rechargement peut prendre un instant ; réessayez si l’ancien certificat apparaît encore.
curl --noproxy '*' --fail --cacert root.crt --resolve help.lab.test:8443:127.0.0.1 https://help.lab.test:8443/
help service: training content available
Préservez aussi le fonctionnement normal du site de référence :
curl --noproxy '*' --fail --cacert root.crt --resolve status.lab.test:8443:127.0.0.1 https://status.lab.test:8443/
Ce succès vérifie le nom, la chaîne et les dates réellement servis avant d’accepter la réponse. Modifier seulement un certificat inutilisé ne donnerait pas ce résultat.
Réparer un intermédiaire manquant
Dans cette étape, distinguez une chaîne incomplète du nom incompatible déjà corrigé. Dans Client, demandez le site de documentation préparé. Cet échec est volontaire :
curl --noproxy '*' --cacert root.crt --resolve docs.lab.test:8443:127.0.0.1 https://docs.lab.test:8443/
curl: (60) SSL certificate problem: unable to get local issuer certificate
...
Les deux échecs utilisent le code de sortie 60 ; lisez l’explication associée. Inspectez le certificat servi avec la même forme de commande :
openssl s_client -connect 127.0.0.1:8443 -servername docs.lab.test </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates -ext subjectAltName
Cette fois, le SAN est DNS:docs.lab.test. Le nom est correct, mais Nginx n’envoie que le certificat terminal : le client ne peut pas relier son émetteur à la racine.
Pour une comparaison contrôlée, -k ignore la vérification. Cela montre que le contenu reste accessible malgré une confiance défaillante :
curl --noproxy '*' -k --resolve docs.lab.test:8443:127.0.0.1 https://docs.lab.test:8443/
Voir docs service: training content available ici ne constitue pas une réparation. Retournez dans Server, examinez le fichier actif, puis ouvrez-le :
cat conf/docs.conf
nano conf/docs.conf
Le fichier préparé docs-fullchain.pem contient déjà le certificat terminal puis l’intermédiaire. Remplacez uniquement la ligne ssl_certificate :
ssl_certificate /tls/docs-fullchain.pem;
Conservez /tls/docs.key comme clé privée. Enregistrez et quittez comme précédemment, puis testez et rechargez :
sudo docker exec https-edge nginx -t
sudo docker exec https-edge nginx -s reload
Dans Client, demandez les trois noms prévus sans -k. La boucle affecte successivement chaque valeur à host ; $host insère cette valeur et les guillemets doubles gardent chaque argument complet.
for host in help docs status; do
curl --noproxy '*' --fail --cacert root.crt --resolve "$host.lab.test:8443:127.0.0.1" "https://$host.lab.test:8443/"
done
Attendez les trois réponses correspondantes. Vous pouvez actualiser HTTPS Monitor pour comparer ses sondes indépendantes en direct. Corrigez une erreur dans la configuration appropriée, testez et rechargez ; ne changez ni la racine du client ni les noms prévus. En production, obtenez les certificats approuvés via le processus d’émission de votre organisation ; cet exercice fournit des candidats synthétiques pour se concentrer sur le diagnostic.
Résumé
Vous avez récupéré une référence fiable, inspecté les noms et émetteurs réels, assemblé une chaîne terminale/intermédiaire et l’avez appliquée par un rechargement Nginx testé. Vous avez corrigé un nom incompatible et une chaîne incomplète tout en préservant le service normal. Le défi suivant combine ces décisions pour un autre portail.



