infra / nginx
HTTPS et TLS avec Nginx
Explication
Ce que vous allez apprendre
- Générer et renouveler automatiquement un certificat TLS gratuit avec Certbot (Let's Encrypt)
- Rediriger systématiquement le trafic HTTP vers HTTPS
- Durcir une configuration TLS au-delà du minimum "ça marche" (protocoles, ciphers, HSTS)
- Comprendre le rôle de l'OCSP stapling dans la vérification de révocation d'un certificat
- Générer un certificat auto-signé pour un usage de développement local uniquement
Dans quel contexte ?
Un site en production doit passer en HTTPS, aussi bien pour la confiance des visiteurs (le cadenas dans le navigateur) que pour le référencement (Google favorise HTTPS) et la sécurité réelle (chiffrement des données en transit, notamment les mots de passe et informations de paiement). L'équipe doit obtenir un certificat, l'installer, et surtout s'assurer qu'il continuera à être valide dans le temps sans intervention manuelle répétée.
D'abord, la méthode la plus simple pour obtenir un certificat valide
Certbot, l'outil officiel de Let's Encrypt, automatise à la fois la génération du certificat ET la modification de la configuration Nginx du site concerné, en une seule commande (certbot --nginx -d example.com). C'est devenu la méthode standard en production, largement préférée à un achat de certificat commercial pour la majorité des sites.
Une fois le certificat obtenu, un point de vigilance immédiat se pose
Les certificats Let's Encrypt expirent tous les 90 jours — une durée volontairement courte pour inciter à l'automatisation du renouvellement plutôt qu'à une gestion manuelle risquée. Certbot installe automatiquement un timer systemd qui gère ce renouvellement en arrière-plan ; certbot renew --dry-run permet de vérifier que ce mécanisme fonctionnera réellement, sans attendre l'échéance réelle pour le découvrir.
Ensuite, avoir un certificat ne suffit pas : il faut forcer son usage
Un site accessible à la fois en HTTP et en HTTPS laisse la porte ouverte à des sessions non chiffrées. Un return 301 https://$host$request_uri; sur le port 80 redirige systématiquement et de façon permanente vers la version HTTPS, en conservant le chemin exact demandé par le client.
| Réglage TLS | Rôle | Pourquoi c'est important |
|---|---|---|
ssl_protocols TLSv1.2 TLSv1.3 | Exclut les versions TLS obsolètes | SSLv3/TLSv1.0/1.1 ont des vulnérabilités connues |
HSTS (Strict-Transport-Security) | Force le navigateur à toujours utiliser HTTPS pour ce domaine | Empêche un downgrade même via un lien http:// tapé à la main |
ssl_stapling | Le serveur pré-vérifie la révocation du certificat | Évite un aller-retour supplémentaire au navigateur |
ssl_session_cache | Réutilise les sessions TLS entre connexions | Réduit le coût du handshake TLS répété |
Il reste une nuance importante sur le durcissement complet
Une configuration TLS "niveau production" ne se limite pas au certificat lui-même : ssl_ciphers, la désactivation des tickets de session (ssl_session_tickets off;, pour une meilleure forward secrecy) et l'OCSP stapling forment ensemble une posture de sécurité complète, bien au-delà d'un simple certificat valide.
Prérequis
Cette leçon suppose que tu es à l'aise avec la structure d'un server block (leçon 3) : la configuration TLS s'ajoute directement dans le bloc server qui écoute sur le port 443.
Piège fréquent
Utiliser un certificat auto-signé (openssl req -x509 ...) en dehors du développement local est une erreur de sécurité et d'expérience utilisateur : le navigateur affiche un avertissement bloquant pour tout visiteur, car aucune autorité de certification reconnue ne l'a validé. Ce type de certificat n'a de sens qu'en environnement de test isolé.
Bonne pratique
Vérifie régulièrement la configuration TLS effective d'un site en production avec un outil externe (comme SSL Labs) ou en ligne de commande avec openssl s_client : une configuration qui semblait correcte au moment de sa création peut devenir obsolète quelques années plus tard, à mesure que de nouvelles vulnérabilités sont découvertes sur d'anciens protocoles.
Maintenant que le trafic est chiffré, la prochaine leçon s'intéresse à un levier de performance simple à activer : la compression des réponses avec gzip et brotli.
Commandes & code
HTTPS et TLS avec Nginx
# Certificat gratuit avec Certbot (Let's Encrypt) — méthode la plus courante en production
sudo apt install certbot python3-certbot-nginx -y
# Génère le certificat ET modifie automatiquement la config Nginx du site
sudo certbot --nginx -d example.com -d www.example.com
# Renouvellement (les certificats Let's Encrypt expirent tous les 90 jours)
sudo certbot renew --dry-run # simulation, à tester avant de faire confiance au cron
sudo systemctl list-timers | grep certbot # le renouvellement auto tourne déjà en timer systemdserver {
listen 443 ssl;
http2 on; # HTTP/2 quasi gratuit une fois en TLS
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/example.com;
}
# Redirection systématique HTTP -> HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri; # 301 = redirection permanente, préserve le path
}# Configuration TLS durcie (niveau production, pas juste "ça marche")
server {
listen 443 ssl;
http2 on;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; # exclut SSLv3/TLSv1.0/1.1 (obsolètes, vulnérables)
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers off; # TLS 1.3 recommande de laisser le client choisir
ssl_session_cache shared:SSL:10m; # cache de session TLS partagé entre workers
ssl_session_timeout 1d;
ssl_session_tickets off; # désactive les tickets (meilleure forward secrecy)
ssl_stapling on; # OCSP stapling : évite au client de vérifier la révocation lui-même
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}# Certificat auto-signé pour du dev local (jamais en production)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/nginx/ssl/self.key \
-out /etc/nginx/ssl/self.crt \
-subj "/CN=localhost"
# Vérifier une config TLS depuis l'extérieur
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -datesRésumé
- Certbot automatise la génération ET le renouvellement des certificats Let's Encrypt (90 jours de validité).
- Toujours rediriger le port 80 en 301 vers le 443 : un site en prod ne doit jamais rester accessible en clair.
ssl_protocols TLSv1.2 TLSv1.3+ HSTS (Strict-Transport-Security) = base d'une config TLS "niveau expert".ssl_staplingévite au navigateur un aller-retour supplémentaire pour vérifier la révocation du certificat.
Exercices pratiques
Mission : durcir une configuration TLS avant un audit de sécurité
Objectif : Forcer la redirection vers HTTPS et durcir les protocoles/ciphers d'un site qui vient de passer un audit externe.
Contexte
Un audit de sécurité externe signale que https://example.com reste accessible également en clair via http://example.com (sans redirection), et que la configuration TLS actuelle accepte encore TLSv1.0. Le certificat Let's Encrypt est déjà en place et se renouvelle automatiquement.