Retour au cours

infra / nginx

HTTPS et TLS avec Nginx

Leçon 71 exercice

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 TLSRôlePourquoi c'est important
ssl_protocols TLSv1.2 TLSv1.3Exclut les versions TLS obsolètesSSLv3/TLSv1.0/1.1 ont des vulnérabilités connues
HSTS (Strict-Transport-Security)Force le navigateur à toujours utiliser HTTPS pour ce domaineEmpêche un downgrade même via un lien http:// tapé à la main
ssl_staplingLe serveur pré-vérifie la révocation du certificatÉvite un aller-retour supplémentaire au navigateur
ssl_session_cacheRéutilise les sessions TLS entre connexionsRé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

bash
# 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 systemd
nginx
server {
    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
}
nginx
# 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;
}
bash
# 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 -dates

Ré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

1 disponible
1

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.

Résoudre l’exercice →