Retour au cours

infra / reseaux-tcp-ip

HTTP/HTTPS et TLS en profondeur

Leçon 131 exercice

Explication

Ce que vous allez apprendre

  • Comprendre la structure d'une requête et d'une réponse HTTP, et le sens des principaux codes de statut
  • Comprendre pourquoi TLS s'intercale entre TCP et HTTP pour chiffrer et authentifier l'échange
  • Inspecter un certificat TLS en ligne de commande avec openssl s_client et openssl x509
  • Générer un certificat de test et automatiser un certificat de production avec Let's Encrypt/certbot
  • Diagnostiquer un problème TLS (version, cipher, expiration) avant qu'il n'impacte les utilisateurs

Dans quel contexte ?

Un client signale que son navigateur affiche "Votre connexion n'est pas privée" sur exemple.com, alors que le site fonctionnait parfaitement la veille. L'administrateur lance echo | openssl s_client -connect exemple.com:443 -servername exemple.com | openssl x509 -noout -enddate et découvre que le certificat a expiré la nuit précédente : le renouvellement automatique de certbot avait silencieusement échoué depuis plusieurs semaines, faute de surveillance.

HTTP : le langage du web

HTTP est le protocole qui structure la quasi-totalité des échanges sur le web : un client formule une requête (que veut-il faire ? sur quelle ressource ?), un serveur renvoie une réponse (avec un code indiquant si ça s'est bien passé). Les méthodes HTTP (GET, POST, PUT...) expriment une intention claire, et les codes de statut (200, 404, 500...) sont un langage commun compris par n'importe quel client ou serveur dans le monde, quel que soit le langage de programmation utilisé derrière.

Plage de codesSignificationExemples
2xxSuccès200 OK, 201 Created
3xxRedirection301, 302, 304 Not Modified
4xxErreur côté client400, 401, 403, 404, 429
5xxErreur côté serveur500, 502, 503, 504

Piège fréquent

Un certificat expiré casse immédiatement la confiance, quelle que soit la qualité du reste de la configuration TLS. certbot renew --dry-run teste le renouvellement sans l'appliquer : à automatiser via cron et à surveiller activement, plutôt que de découvrir l'expiration en même temps que les utilisateurs.

Pourquoi HTTPS a remplacé HTTP par défaut

HTTP transmet tout en clair : n'importe quel intermédiaire sur le trajet (un réseau Wi-Fi public, un fournisseur d'accès) peut lire ou modifier les échanges. TLS ajoute une couche de chiffrement et d'authentification avant même que le premier échange HTTP ne commence, garantissant confidentialité (personne ne lit) et intégrité (personne ne modifie), et vérifiant qu'on parle bien au vrai serveur et non à un imposteur.

Le certificat : une pièce d'identité vérifiable

Un certificat TLS ne fait pas que chiffrer, il prouve une identité : une autorité de certification, reconnue de confiance, atteste que ce certificat appartient bien au domaine en question. C'est cette chaîne de confiance qui empêche, en théorie, quelqu'un d'usurper l'identité d'un site en présentant un faux certificat.

Pourquoi la vérification de l'expiration compte

Un certificat expiré casse immédiatement la confiance : le navigateur affiche un avertissement bloquant, quelle que soit la qualité du reste de la configuration. Automatiser le renouvellement (comme le fait Let's Encrypt/certbot) et surveiller les dates d'expiration sont des réflexes opérationnels indispensables, pas de simples détails techniques.

Commandes & code

HTTP/HTTPS et TLS en profondeur

bash
# Anatomie d'une requête/réponse HTTP brute (visible avec telnet/nc sur du HTTP simple)
printf 'GET / HTTP/1.1\r\nHost: exemple.com\r\nConnection: close\r\n\r\n' | nc exemple.com 80

# Méthodes HTTP et cas d'usage
curl -X GET https://api.exemple.com/users              # récupérer une ressource
curl -X POST -d '{"nom":"X"}' https://api.exemple.com/users     # créer
curl -X PUT -d '{"nom":"Y"}' https://api.exemple.com/users/1      # remplacer entièrement
curl -X PATCH -d '{"nom":"Z"}' https://api.exemple.com/users/1      # modifier partiellement
curl -X DELETE https://api.exemple.com/users/1                        # supprimer
curl -X OPTIONS -i https://api.exemple.com/users                        # méthodes autorisées (CORS)

# Codes de statut à connaître par coeur
# 2xx succès : 200 OK, 201 Created, 204 No Content
# 3xx redirection : 301 permanente, 302 temporaire, 304 Not Modified (cache)
# 4xx erreur client : 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests
# 5xx erreur serveur : 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout
text
# --- TLS handshake (simplifié, TLS 1.3) ---
Client                                              Serveur
  |---- ClientHello (versions/ciphers supportés) -->|
  |<---- ServerHello + certificat + clé publique ---|
  |    (le client vérifie le certificat via la CA)  |
  |---- clé de session chiffrée avec la clé publique->|
  |<========= canal chiffré établi ================>|
  |========= échange HTTP chiffré (HTTPS) ===========|

# TLS 1.3 réduit le handshake à 1 aller-retour (contre 2 pour TLS 1.2) -> latence réduite
bash
# Inspecter le certificat d'un site
openssl s_client -connect exemple.com:443 -servername exemple.com </dev/null 2>/dev/null | openssl x509 -noout -text
curl -vI https://exemple.com 2>&1 | grep -A5 "Server certificate"

# Vérifier la date d'expiration d'un certificat (typique d'un script de monitoring)
echo | openssl s_client -connect exemple.com:443 -servername exemple.com 2>/dev/null \
  | openssl x509 -noout -enddate

# Générer un certificat auto-signé (dev/test uniquement, jamais en prod)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes \
  -subj "/CN=dev.exemple.local"

# Certificat gratuit et automatisé en prod : Let's Encrypt via certbot
sudo certbot --nginx -d exemple.com -d www.exemple.com
sudo certbot renew --dry-run        # teste le renouvellement automatique sans l'appliquer

# Forcer HTTPS et ajouter des headers de sécurité (nginx)
# server { listen 80; return 301 https://$host$request_uri; }
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

# Diagnostiquer un problème TLS (version, cipher supporté)
openssl s_client -connect exemple.com:443 -tls1_2
nmap --script ssl-enum-ciphers -p 443 exemple.com     # liste les ciphers acceptés par le serveur

Résumé

  • TLS établit un canal chiffré avant tout échange HTTP ; TLS 1.3 réduit le handshake à un seul aller-retour.
  • openssl s_client et openssl x509 sont les outils de référence pour inspecter un certificat en ligne de commande.
  • Let's Encrypt/certbot a rendu le HTTPS gratuit et automatisable ; toujours planifier le renouvellement (certbot renew).

Exercices pratiques

1 disponible
1

Mission : comprendre un certificat renouvelé mais toujours affiché comme expiré

Objectif : Diagnostiquer pourquoi un certificat TLS renouvelé avec succès sur disque n'est pas pris en compte par le serveur, et évaluer l'impact de TLS 1.3 sur la latence.

Contexte

certbot renew s'exécute sans erreur pour exemple.com : le nouveau certificat est bien présent dans /etc/letsencrypt/live/exemple.com/. Pourtant, en visitant le site, le navigateur affiche toujours l'avertissement de certificat expiré.

Résoudre l’exercice →