Aller au contenu

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.local et AC Lab SISR sont 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.

  1. Quelle est la durée de validité de la racine ? Pourquoi est-elle plus longue que celle d'un certificat de serveur ? ______________________
  2. Quel fichier est le plus sensible ? Que se passe-t-il si quelqu'un le copie ? ______________________
  3. Qu'est-ce qui distingue CA:TRUE de CA: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.

  1. Quels fichiers sont passés du « serveur » vers l'« AC » ? Lequel n'est jamais sorti du serveur ? ______________________
  2. Que signifient www.crt: OK d'une part, et l'erreur « unable to get local issuer certificate » d'autre part ? ______________________
  3. Que contient index.txt ? À quoi sert-il pour l'inventaire ? ______________________
  4. 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.

  1. Que renvoie curl -I http://www.lab.local ? Quel code et quelle destination ? ______________________
  2. Quelle version de TLS et quelle suite de chiffrement ont été négociées ? ______________________
  3. Quelle est la différence entre --cacert et update-ca-certificates ? Lequel est le plus risqué ? ______________________
  4. Teste openssl s_client -connect www.lab.local:443 -tls1_2 puis -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.

  1. À quoi sert -checkend ? Comment l'utiliser pour surveiller l'expiration (par exemple avec cron) ? ______________________
  2. Un utilisateur écrit : « Le site affiche un avertissement, je clique sur continuer ». Que lui réponds-tu, et que fais-tu côté technique ? ______________________
  3. 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
  1. Que lis-tu dans index.txt pour le certificat 1000 ? (première lettre) ______________________
  2. Quel message donne openssl verify -crl_check ? ______________________
  3. Pourquoi la révocation n'a-t-elle d'effet que si les clients vérifient la CRL (ou OCSP) ? ______________________
  4. 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
  1. 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 : ______________________