TP – Construire une mini-PKI, publier un site en HTTPS et diagnostiquer les erreurs de certificat
BTS SIO SISR 1re année – Bloc 3 – S12
Note
But. Situation : Comment faire pour qu'un site interne soit en HTTPS sans avertissement, et comment diagnostiquer une erreur de certificat ?
Comment ce TP fonctionne. Avant de manipuler, tu écris ce que tu anticipes (« J'anticipe »). Puis tu testes et tu notes ce que tu constates. Tu comprends ce que fait chaque commande (« Je comprends »). Un bilan de compétences clôt la séance. Les manipulations se font sur des machines virtuelles de laboratoire, isolées du réseau de l'établissement. Les identifiants communs d'un TP sont des identifiants de laboratoire : ils ne se réutilisent jamais ailleurs.
Objectif
Construire une autorité de certification de laboratoire, émettre un certificat de serveur, publier un site en HTTPS que le poste client reconnaît, provoquer et diagnostiquer les erreurs courantes, puis révoquer un certificat.
Contraintes
- Binôme, durée : 3 h 20. Une seule VM Debian de laboratoire joue les trois rôles (AC, serveur, client).
- Les noms
www.lab.localetAC Lab SISRsont fictifs ; l'AC n'a de sens que dans ta VM. - À la fin, tu retires l'AC de laboratoire du magasin de confiance de la VM (étape E3).
- La clé de l'AC est ici sans mot de passe (laboratoire). Dans une vraie entreprise, elle est protégée et hors ligne.
Partie A. Créer l'autorité de certification (40 min)
A1. Préparer l'arborescence
mkdir -p ~/pki/{private,newcerts} && cd ~/pki
chmod 700 private
touch index.txt
echo 1000 > serial
echo 01 > crlnumber
A2. Écrire la configuration
Enregistre le fichier openssl-ca.cnf :
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = .
database = $dir/index.txt
new_certs_dir = $dir/newcerts
serial = $dir/serial
crlnumber = $dir/crlnumber
private_key = $dir/private/ca.key
certificate = $dir/ca.crt
default_md = sha256
default_days = 90
default_crl_days = 30
policy = policy_lab
copy_extensions = copy
unique_subject = no
[ policy_lab ]
countryName = optional
organizationName = supplied
commonName = supplied
[ v3_ca ]
basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier = hash
[ v3_server ]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
crlDistributionPoints = URI:http://pki.lab.local/ca.crl
Je comprends.
| Ligne | Rôle |
|---|---|
database, serial |
Fichiers qui enregistrent les certificats émis et le prochain numéro de série |
default_days = 90 |
Durée de validité d'un certificat émis : courte |
copy_extensions = copy |
Recopie les noms alternatifs (SAN) demandés dans la CSR |
[ v3_ca ] : CA:TRUE, keyCertSign, cRLSign |
Cette clé peut signer des certificats et des listes de révocation |
[ v3_server ] : CA:FALSE, serverAuth |
Un certificat de serveur ne signe pas d'autres certificats ; il sert à authentifier un serveur |
A3. Créer le certificat racine
openssl req -x509 -newkey rsa:3072 -nodes -keyout private/ca.key -out ca.crt -days 3650 \
-subj "/C=FR/O=Lab SISR/CN=AC Lab SISR" -config openssl-ca.cnf -extensions v3_ca
chmod 600 private/ca.key
openssl x509 -in ca.crt -noout -subject -issuer -dates -ext basicConstraints
J'anticipe. Un certificat racine est auto-signé. Que verras-tu pour le sujet et l'émetteur ? ______________________
Éléments de réponse
Les mêmes : la racine se signe elle-même. Sa confiance ne vient pas d'une signature, mais du fait qu'elle est installée volontairement dans le magasin de confiance des clients.
Questions.
- Quelle est la durée de validité de la racine ? Pourquoi est-elle plus longue que celle d'un certificat de serveur ? ______________________
- Quel fichier est le plus sensible ? Que se passe-t-il si quelqu'un le copie ? ______________________
- Qu'est-ce qui distingue
CA:TRUEdeCA:FALSE? ______________________
Partie B. Émettre un certificat de serveur (35 min)
Le serveur crée sa clé et sa demande ; l'AC signe.
cd ~/pki
# Côté serveur : clé privée + demande (CSR)
openssl req -new -newkey rsa:2048 -nodes -keyout www.key -out www.csr \
-subj "/C=FR/O=Lab SISR/CN=www.lab.local" -addext "subjectAltName=DNS:www.lab.local"
chmod 600 www.key
openssl req -in www.csr -noout -subject -verify
# Côté AC : signature
openssl ca -batch -config openssl-ca.cnf -extensions v3_server -in www.csr -out www.crt
openssl x509 -in www.crt -noout -subject -issuer -dates -ext subjectAltName,basicConstraints,extendedKeyUsage
openssl verify -CAfile ca.crt www.crt
openssl verify www.crt
cat index.txt
Questions.
- Quels fichiers sont passés du « serveur » vers l'« AC » ? Lequel n'est jamais sorti du serveur ? ______________________
- Que signifient
www.crt: OKd'une part, et l'erreur « unable to get local issuer certificate » d'autre part ? ______________________ - Que contient
index.txt? À quoi sert-il pour l'inventaire ? ______________________ - Quels noms le certificat couvre-t-il ? Serait-il valable pour
lab.local? ______________________
Partie C. Publier le site en HTTPS (60 min)
C1. Installer nginx et déposer les fichiers
sudo apt install -y nginx curl
sudo mkdir -p /etc/nginx/pki /var/www/lab
sudo cp ~/pki/www.crt ~/pki/www.key /etc/nginx/pki/
sudo chown root:root /etc/nginx/pki/www.key && sudo chmod 600 /etc/nginx/pki/www.key
echo "<h1>Intranet de laboratoire</h1>" | sudo tee /var/www/lab/index.html
echo "127.0.0.1 www.lab.local" | sudo tee -a /etc/hosts
Crée /etc/nginx/sites-available/lab (avec sudo) :
server {
listen 443 ssl;
server_name www.lab.local;
ssl_certificate /etc/nginx/pki/www.crt;
ssl_certificate_key /etc/nginx/pki/www.key;
ssl_protocols TLSv1.2 TLSv1.3;
root /var/www/lab;
}
server {
listen 80;
server_name www.lab.local;
return 301 https://$host$request_uri;
}
sudo ln -s /etc/nginx/sites-available/lab /etc/nginx/sites-enabled/lab
sudo nginx -t
sudo systemctl reload nginx
curl -I https://www.lab.local
curl -I http://www.lab.local
J'anticipe. La première requête https va-t-elle réussir sans avertissement ? ______________________
Éléments de réponse
Non : curl répond que le certificat n'est pas vérifié (autorité inconnue). Le certificat est valable, mais ta VM ne connaît pas encore l'AC.
C2. Faire confiance à l'AC
curl --cacert ~/pki/ca.crt -I https://www.lab.local
sudo cp ~/pki/ca.crt /usr/local/share/ca-certificates/ca-lab-sisr.crt
sudo update-ca-certificates
curl -I https://www.lab.local
echo | openssl s_client -connect www.lab.local:443 -servername www.lab.local -verify_hostname www.lab.local 2>/dev/null | grep -E "Verif|Protocol|Cipher"
Je comprends.
| Élément | Rôle |
|---|---|
nginx -t |
Teste la configuration avant de recharger |
curl --cacert ca.crt |
Fait confiance uniquement pour cette commande à l'AC indiquée |
update-ca-certificates |
Ajoute l'AC au magasin de confiance de tout le système |
s_client -verify_hostname |
Vérifie aussi que le nom correspond au certificat |
return 301 https://… |
Redirige le trafic HTTP vers HTTPS |
Questions.
- Que renvoie
curl -I http://www.lab.local? Quel code et quelle destination ? ______________________ - Quelle version de TLS et quelle suite de chiffrement ont été négociées ? ______________________
- Quelle est la différence entre
--cacertetupdate-ca-certificates? Lequel est le plus risqué ? ______________________ - Teste
openssl s_client -connect www.lab.local:443 -tls1_2puis-tls1_3. Les deux fonctionnent-ils ? Que deviendrait un client trop ancien qui ne parle que TLS 1.0 ? ______________________
Partie D. Diagnostiquer trois erreurs (35 min)
D1. Mauvais nom
echo | openssl s_client -connect 127.0.0.1:443 -servername www.lab.local -verify_hostname autre.lab.local 2>/dev/null | grep -E "Verif"
D2. Certificat expiré
Émets un certificat déjà expiré (dates imposées), puis vérifie-le :
cd ~/pki
openssl req -new -newkey rsa:2048 -nodes -keyout old.key -out old.csr \
-subj "/C=FR/O=Lab SISR/CN=www.lab.local" -addext "subjectAltName=DNS:www.lab.local"
openssl ca -batch -config openssl-ca.cnf -extensions v3_server \
-startdate 20250101000000Z -enddate 20250201000000Z -in old.csr -out old.crt
openssl verify -CAfile ca.crt old.crt
openssl x509 -in www.crt -noout -checkend $((86400*30)) && echo "valable encore 30 jours"
openssl x509 -in www.crt -noout -checkend $((86400*200)) || echo "expire dans moins de 200 jours"
D3. Autorité inconnue
sudo rm /usr/local/share/ca-certificates/ca-lab-sisr.crt
sudo update-ca-certificates --fresh
curl -I https://www.lab.local
Remplis :
| Cas | Message observé | Cause | Correction |
|---|---|---|---|
| D1 mauvais nom | |||
| D2 expiré | |||
| D3 autorité inconnue |
Questions.
- À quoi sert
-checkend? Comment l'utiliser pour surveiller l'expiration (par exemple aveccron) ? ______________________ - Un utilisateur écrit : « Le site affiche un avertissement, je clique sur continuer ». Que lui réponds-tu, et que fais-tu côté technique ? ______________________
- Quel autre facteur peut faire apparaître une erreur d'expiration sur un certificat pourtant valable ? ______________________
Partie E. Révoquer un certificat (30 min)
E1. Révoquer et publier la CRL
On suppose que la clé de www.key a été volée.
cd ~/pki
openssl ca -config openssl-ca.cnf -revoke www.crt
openssl ca -config openssl-ca.cnf -gencrl -out ca.crl
openssl crl -in ca.crl -noout -text | grep -A3 "Revoked"
openssl verify -CAfile ca.crt -crl_check -CRLfile ca.crl www.crt
cat index.txt
- Que lis-tu dans
index.txtpour le certificat1000? (première lettre) ______________________ - Quel message donne
openssl verify -crl_check? ______________________ - Pourquoi la révocation n'a-t-elle d'effet que si les clients vérifient la CRL (ou OCSP) ? ______________________
- Quelles étapes complètes d'un plan de réponse faut-il prévoir après une clé volée ? ______________________
E2. Remplacer le certificat
Émets un nouveau certificat avec une nouvelle clé (reprends la partie B avec les noms www2.key, www2.csr, www2.crt), vérifie-le, puis remplace-le dans nginx.
E3. Nettoyer
sudo rm -f /usr/local/share/ca-certificates/ca-lab-sisr.crt
sudo update-ca-certificates --fresh
sudo sed -i '/www.lab.local/d' /etc/hosts
- Pourquoi est-il important de retirer l'AC de laboratoire du magasin de confiance de la VM ? ______________________
Défi facultatif
Ajoute une AC intermédiaire : crée-la, signe-la avec la racine (CA:TRUE, pathlen:0), émets le certificat du serveur depuis l'intermédiaire, puis fais servir par nginx la chaîne (certificat du serveur suivi de celui de l'intermédiaire). Vérifie avec openssl verify -CAfile ca.crt -untrusted inter.crt www.crt.
Retour en entreprise
Si ta situation le permet : observe comment ton entreprise traite ce sujet, note en quelques lignes l'écart avec le TP, et, avec l'accord de ton tuteur, réalise une partie sur une situation réelle. Anonymise tes captures. Voir Transfert en entreprise.
Bilan de la séance
Remplis ce bilan seul, honnêtement : il sert à décider ce qu'il faut reprendre. Niveau : Non maîtrisé, Maîtrise partielle, Bonne maîtrise ou Excellente maîtrise (le vocabulaire des grilles nationales d'évaluation) ; Non évalué si tu n'as pas travaillé la compétence aujourd'hui.
| Compétence du référentiel | Ce que j'ai fait dans cette séance | Niveau |
|---|---|---|
| B3.2 – Préserver l'identité numérique de l'organisation | ||
| B3.4 – Garantir la disponibilité, l'intégrité et la confidentialité des services informatiques et des données de l'organisation face à des cyberattaques | ||
| B3.5A – Assurer la cybersécurité d'une infrastructure réseau, d'un système, d'un service |
Note
Les codes sont ceux du référentiel (l'arrêté numérote des activités : les codes « B… » sont un usage courant).
Je sais faire, sans aide :
- Créer une AC interne et émettre un certificat de serveur ;
- Configurer nginx en HTTPS avec redirection ;
- Installer une AC de laboratoire comme racine de confiance, puis la retirer ;
- Reconnaître les erreurs de nom, d'expiration et de chaîne ;
- Révoquer un certificat et vérifier la liste de révocation.
Ce que je dois reprendre : ______________________
Ma question à poser à l'enseignant : ______________________