Nginx : HTTPS et certificats
Activer HTTPS avec un certificat gratuit Let’s Encrypt. Les exemples utilisent le domaine fictif exemple.com.
Prérequis
Section intitulée « Prérequis »- Le DNS de
exemple.com(et dewww.exemple.com) pointe vers l’adresse IP publique du serveur. - Un site Nginx fonctionnel en HTTP, avec un
server_namecorrect (voir Sites virtuels). - Les ports 80 et 443 ouverts :
sudo ufw allow 'Nginx Full'.
Installer Certbot
Section intitulée « Installer Certbot »sudo apt install certbot python3-certbot-nginxcertbot --version| Ubuntu | Version de Certbot |
|---|---|
| 24.04 | 2.9 |
| 26.04 | 4.0 |
Obtenir un certificat et configurer Nginx
Section intitulée « Obtenir un certificat et configurer Nginx »sudo certbot --nginx -d exemple.com -d www.exemple.comCertbot demande une adresse e-mail (alertes d’expiration), vérifie que le domaine pointe vers le serveur, obtient le certificat, modifie la configuration du site et propose de rediriger HTTP vers HTTPS. Les certificats sont dans /etc/letsencrypt/live/exemple.com/.
| Fichier | Contenu |
|---|---|
fullchain.pem |
Certificat et chaîne intermédiaire (à utiliser dans ssl_certificate) |
privkey.pem |
Clé privée (secrète) |
Autres modes d’obtention, sans modifier la configuration :
sudo certbot certonly --webroot -w /var/www/exemple.com -d exemple.com # via le dossier du sitesudo certbot certonly --nginx -d exemple.com # via Nginx, sans modifier le sitesudo certbot certonly --standalone -d exemple.com # serveur temporaire (Nginx arrêté)Renouvellement automatique
Section intitulée « Renouvellement automatique »Le paquet installe un minuteur systemd qui renouvelle les certificats à moins de 30 jours de l’expiration :
systemctl list-timers | grep certbotsudo certbot renew --dry-run # simulation du renouvellementsudo certbot certificates # certificats et dates d'expirationPour recharger Nginx après un renouvellement :
sudo tee /etc/letsencrypt/renewal-hooks/deploy/recharger-nginx.sh <<'CONF'#!/bin/shsystemctl reload nginxCONFsudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/recharger-nginx.shConfiguration HTTPS écrite à la main
Section intitulée « Configuration HTTPS écrite à la main »server { listen 80; listen [::]:80; server_name exemple.com www.exemple.com; return 301 https://exemple.com$request_uri; # tout passe en HTTPS}
server { listen 443 ssl; listen [::]:443 ssl; server_name exemple.com;
ssl_certificate /etc/letsencrypt/live/exemple.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/exemple.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; ssl_session_cache shared:SSL:10m; ssl_session_timeout 1d; ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000" always;
root /var/www/exemple.com; location / { try_files $uri $uri/ =404; }}
server { listen 443 ssl; listen [::]:443 ssl; server_name www.exemple.com; ssl_certificate /etc/letsencrypt/live/exemple.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/exemple.com/privkey.pem; return 301 https://exemple.com$request_uri; # www vers le domaine nu}Ne pas forcer la suite de chiffrement : les valeurs par défaut de Nginx et d’OpenSSL sur Ubuntu sont adaptées.
HTTP/2 : syntaxe selon la version
Section intitulée « HTTP/2 : syntaxe selon la version »| Nginx | Syntaxe |
|---|---|
| 1.24 (Ubuntu 24.04) | listen 443 ssl http2; |
| 1.25.1 et plus (dont 1.28 sur Ubuntu 26.04) | listen 443 ssl; puis http2 on; dans le bloc server |
# Nginx 1.28 (Ubuntu 26.04)server { listen 443 ssl; listen [::]:443 ssl; http2 on; # …}# Nginx 1.24 (Ubuntu 24.04)server { listen 443 ssl http2; listen [::]:443 ssl http2; # …}Strict-Transport-Security demande au navigateur de n’utiliser que HTTPS pour ce domaine :
add_header Strict-Transport-Security "max-age=31536000" always;Agrafage OCSP (facultatif)
Section intitulée « Agrafage OCSP (facultatif) »ssl_stapling on;ssl_stapling_verify on;ssl_trusted_certificate /etc/letsencrypt/live/exemple.com/chain.pem;resolver 1.1.1.1 9.9.9.9 valid=300s;Vérifier
Section intitulée « Vérifier »sudo nginx -t && sudo systemctl reload nginxcurl -I https://exemple.comcurl -I http://exemple.com # 301 vers httpsopenssl s_client -connect exemple.com:443 -servername exemple.com </dev/null 2>/dev/null | openssl x509 -noout -dates -subjectsudo apt install nmap && nmap --script ssl-enum-ciphers -p 443 exemple.com # protocoles TLS acceptés : seuls TLSv1.2 et TLSv1.3 doivent apparaîtrecurl -I --http2 https://exemple.com # HTTP/2 actif si la réponse commence par HTTP/2openssl s_client -tls1_1 n’est pas fiable pour ce contrôle : le client OpenSSL d’Ubuntu refuse lui-même ces protocoles (« no protocols available ») sans tester le serveur. Un test externe complet est proposé par ssllabs.com/ssltest.
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
Challenge failed / Timeout during connect |
Le DNS ne pointe pas vers le serveur, ou le port 80 est fermé (UFW, pare-feu de l’hébergeur) |
Too many certificates already issued |
Limite de Let’s Encrypt atteinte : attendre ; utiliser --dry-run ou --staging pour les essais |
nginx: [emerg] cannot load certificate |
Chemin incorrect, ou droits : sudo ls -l /etc/letsencrypt/live/exemple.com/ |
unknown directive "http2" |
Nginx 1.24 : utiliser listen 443 ssl http2; |
Avertissement the "listen ... http2" directive is deprecated |
Nginx 1.25.1 et plus : utiliser http2 on; |
| Boucle de redirection | La redirection HTTPS est aussi active derrière un proxy qui parle HTTP : tester $scheme ou X-Forwarded-Proto |
| Le certificat expire | sudo certbot renew, vérifier systemctl list-timers et journalctl -u certbot |
| Erreur de contenu mixte dans le navigateur | Des ressources http:// dans la page : les passer en https:// |
Ubuntu 24.04 et 26.04 : différences à connaître
Section intitulée « Ubuntu 24.04 et 26.04 : différences à connaître »Pour aller plus loin
Section intitulée « Pour aller plus loin »- Documentation : Configuring HTTPS servers et certbot.eff.org
- Suite : Sécurité