Configurer Let's Encrypt SSL/TLS pour Nginx sur Debian 12 et Ubuntu 24.04
Obtenez et renouvelez automatiquement des certificats TLS gratuits avec Certbot pour Nginx sur Debian 12 ou Ubuntu 24.04. Ce guide couvre la configuration DNS, l'installation de Certbot, la redirection HTTP vers HTTPS, le durcissement TLS, HTTP/2, HSTS et la fin du service OCSP.
Configurer Let's Encrypt SSL/TLS pour Nginx sur Debian 12 et Ubuntu 24.04
Ce tutoriel vous guide dans l'obtention d'un certificat TLS gratuit aupres de Let's Encrypt avec Certbot, la configuration de Nginx pour HTTPS et la mise en place du renouvellement automatique. Chaque etape inclut une commande de verification pour confirmer le resultat avant de passer a la suite.
Si vous n'avez pas encore installe Nginx, commencez par Installer Nginx sur Debian 12 et Ubuntu 24.04. Pour une vue d'ensemble de la gestion de Nginx sur un VPS, consultez Administration de Nginx sur un VPS.
De quoi avez-vous besoin avant de demander un certificat ?
Avant que Certbot puisse emettre un certificat, votre domaine doit pointer vers l'adresse IP de votre serveur, et Nginx doit tourner avec un server block pour ce domaine. Let's Encrypt valide la propriete du domaine en envoyant une requete HTTP a votre serveur. Si le DNS ne resout pas vers votre VPS ou si Nginx n'ecoute pas, le challenge echoue.
Vous avez besoin de :
- Un VPS sous Debian 12 ou Ubuntu 24.04 avec Nginx installe depuis le depot officiel (Installer Nginx sur Debian 12 et Ubuntu 24.04)
- Un nom de domaine enregistre (nous utiliserons
example.comtout au long du guide) - Un enregistrement A pointant
example.comvers l'adresse IPv4 de votre serveur - Un enregistrement AAAA pointant vers votre adresse IPv6 (si votre serveur en possede une)
- Le port 80 ouvert dans votre pare-feu (Certbot utilise les challenges HTTP-01)
- Un server block Nginx fonctionnel pour votre domaine (Nginx Server Blocks)
Configurer les enregistrements DNS
Creez un enregistrement A chez votre fournisseur DNS :
| Type | Nom | Valeur | TTL |
|---|---|---|---|
| A | example.com | 203.0.113.10 | 300 |
| AAAA | example.com | 2001:db8::1 | 300 |
Remplacez les adresses IP par celles de votre serveur. Definissez un TTL bas (300 secondes) pendant la configuration pour que les changements se propagent rapidement. Vous pourrez l'augmenter par la suite.
Verifier la resolution DNS
Attendez quelques minutes apres la creation des enregistrements, puis verifiez depuis votre machine locale (pas depuis le serveur) :
dig +short example.com A
dig +short example.com AAAA
Vous devriez voir les adresses IP de votre serveur dans la sortie. Si vous ne voyez rien ou une IP differente, l'enregistrement ne s'est pas encore propage. Patientez et reessayez.
Verifiez que Nginx repond sur le port 80 depuis votre machine locale :
curl -I http://example.com
Vous devriez obtenir une reponse HTTP/1.1 200 OK avec Server: nginx. Si la connexion expire, verifiez vos regles de pare-feu.
Comment installer Certbot sur Debian 12 et Ubuntu 24.04 ?
Installez Certbot et son plugin Nginx depuis le depot de paquets de votre distribution avec apt. Le plugin Nginx permet a Certbot de modifier automatiquement vos server blocks pour activer TLS.
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
Verifiez l'installation :
certbot --version
Sur Debian 12, cela installe Certbot 2.1.0. Sur Ubuntu 24.04, vous obtenez Certbot 2.9.0. Les deux versions fonctionnent pour tout ce qui est presente dans ce tutoriel.
A noter : si vous avez installe Nginx depuis le depot officiel nginx.org (comme recommande dans Installer Nginx sur Debian 12 et Ubuntu 24.04), le plugin Certbot pour Nginx fonctionnera sans configuration supplementaire. Il detecte les server blocks dans /etc/nginx/conf.d/ et /etc/nginx/sites-enabled/.
Comment obtenir un certificat Let's Encrypt pour Nginx ?
Lancez certbot --nginx avec votre nom de domaine. Certbot contacte Let's Encrypt, prouve que vous controlez le domaine via un challenge HTTP-01, obtient le certificat et modifie votre server block Nginx pour l'utiliser. L'ensemble du processus prend environ 30 secondes.
sudo certbot --nginx -d example.com -d www.example.com
Certbot vous demandera votre adresse e-mail (pour les rappels de renouvellement) et votre accord avec les conditions d'utilisation. Il effectue ensuite les operations suivantes :
- Place un fichier de challenge HTTP-01 dans votre racine web
- Demande a Let's Encrypt de le verifier
- Telecharge le certificat signe
- Modifie votre server block Nginx pour ajouter les directives TLS
- Recharge Nginx
Verifiez que le certificat a ete emis :
sudo ls -la /etc/letsencrypt/live/example.com/
Vous devriez voir :
lrwxrwxrwx 1 root root ... cert.pem -> ../../archive/example.com/cert1.pem
lrwxrwxrwx 1 root root ... chain.pem -> ../../archive/example.com/chain1.pem
lrwxrwxrwx 1 root root ... fullchain.pem -> ../../archive/example.com/fullchain1.pem
lrwxrwxrwx 1 root root ... privkey.pem -> ../../archive/example.com/privkey1.pem
Ce sont des liens symboliques. fullchain.pem contient votre certificat plus la chaine de l'autorite de certification intermediaire. privkey.pem est votre cle privee.
Verifiez que Nginx tourne avec la nouvelle configuration :
sudo nginx -t && sudo systemctl status nginx
nginx -t teste la syntaxe de la configuration. S'il affiche test is successful, la configuration est valide.
Que modifie Certbot dans votre configuration Nginx ?
Certbot ajoute plusieurs lignes a votre server block. Voici ce qu'il insere (les lignes marquees # managed by Certbot) :
server {
server_name example.com www.example.com;
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
# ... your existing location blocks ...
}
Le fichier options-ssl-nginx.conf contient les parametres TLS par defaut de Certbot. Nous les remplacerons par des parametres plus stricts dans la section de durcissement ci-dessous.
Certbot cree aussi un second server block pour rediriger HTTP vers HTTPS. Nous ameliorerons cette redirection dans la section suivante.
Vous pouvez voir exactement ce qui a change en comparant votre configuration :
sudo diff /etc/nginx/conf.d/example.com.conf /etc/nginx/conf.d/example.com.conf.bak 2>/dev/null || echo "No backup found. Certbot modifies in place."
Comment rediriger HTTP vers HTTPS dans Nginx ?
Tout le trafic HTTP doit etre redirige vers HTTPS avec une redirection 301 (permanente). Certbot peut ajouter cette redirection automatiquement, mais sa version par defaut utilise une instruction if a l'interieur du server block existant. C'est un anti-pattern dans Nginx. Un server block dedie est plus propre et plus fiable.
Remplacez la redirection de Certbot par un server block separe. Editez votre fichier de configuration (le chemin depend de votre installation ; generalement /etc/nginx/conf.d/example.com.conf) :
# HTTP -> HTTPS redirect (separate server block, not an if-statement)
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
Ce bloc va dans le meme fichier que votre server block HTTPS, ou dans un fichier separe. Assurez-vous de supprimer le bloc de redirection genere par Certbot pour eviter les doublons.
Testez et rechargez :
sudo nginx -t
sudo systemctl reload nginx
Verifiez la redirection depuis votre machine locale :
curl -I http://example.com
Sortie attendue :
HTTP/1.1 301 Moved Permanently
Location: https://example.com/
Comment durcir les parametres TLS pour un serveur de production ?
La configuration TLS par defaut de Certbot (options-ssl-nginx.conf) est volontairement conservative. Pour un serveur de production, vous voulez des parametres plus stricts. Nous suivrons le profil Intermediate de Mozilla issu du SSL Configuration Generator, qui offre un bon equilibre entre securite et compatibilite client jusqu'a Firefox 27, Chrome 31 et Android 4.4.2.
Creez un fichier snippet que vous pourrez inclure (include) depuis chaque server block :
sudo nano /etc/nginx/snippets/tls-params.conf
Ajoutez le contenu suivant :
# TLS protocol versions — TLS 1.2 and 1.3 only
# TLS 1.0 and 1.1 are deprecated (RFC 8996)
ssl_protocols TLSv1.2 TLSv1.3;
# Ciphers — Mozilla Intermediate profile (January 2026)
# Source: https://ssl-config.mozilla.org/
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
# DH parameters — 2048-bit, RFC 7919 ffdhe2048
ssl_dhparam /etc/nginx/dhparam.pem;
# Session settings
ssl_session_timeout 1d;
ssl_session_cache shared:TLS:10m;
ssl_session_tickets off;
# HSTS — tell browsers to always use HTTPS (2 years)
# Only add includeSubDomains if ALL subdomains use HTTPS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
# Hide Nginx version in error pages and headers
server_tokens off;
Generez le fichier de parametres DH (cela prend quelques secondes) :
sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048
Verifiez que le fichier a ete cree :
sudo ls -la /etc/nginx/dhparam.pem
Mettez maintenant a jour votre server block HTTPS pour utiliser ces parametres au lieu des valeurs par defaut de Certbot. Supprimez la ligne include /etc/letsencrypt/options-ssl-nginx.conf; et la ligne ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;. Remplacez-les par :
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# TLS hardening (replaces Certbot defaults)
include snippets/tls-params.conf;
# ... your location blocks ...
}
Testez et rechargez :
sudo nginx -t
sudo systemctl reload nginx
Quelles versions TLS et quels chiffrements utiliser ?
Mozilla publie trois profils TLS. Voici la comparaison :
| Profil | Protocoles | Client le plus ancien compatible | Cas d'usage |
|---|---|---|---|
| Modern | TLS 1.3 uniquement | Firefox 63, Chrome 70, Android 10 | Services ou tous les clients sont recents |
| Intermediate | TLS 1.2 + 1.3 | Firefox 27, Chrome 31, Android 4.4 | Serveurs web generalistes |
| Old | TLS 1.0 + 1.1 + 1.2 + 1.3 | Firefox 1, Chrome 1, IE 8 | Systemes herites uniquement |
Utilisez Intermediate sauf raison specifique de faire autrement. Ce profil couvre plus de 99,9 % des navigateurs actuels tout en excluant les protocoles faibles. TLS 1.0 et 1.1 ont ete officiellement deprecies par la RFC 8996 en mars 2021.
La liste de chiffrements dans notre snippet n'utilise que des chiffrements AEAD (GCM et ChaCha20-Poly1305). ssl_prefer_server_ciphers off laisse le client choisir son chiffrement prefere. C'est la recommandation de Mozilla, car les clients modernes font de meilleurs choix qu'une preference statique cote serveur.
Let's Encrypt supporte-t-il encore l'agrafage OCSP ?
Non. Let's Encrypt a arrete son service OCSP (Online Certificate Status Protocol) le 6 aout 2025. Les certificats emis apres mai 2025 ne contiennent plus d'URL de repondeur OCSP. Le statut de revocation est desormais publie exclusivement via des listes de revocation de certificats (CRL). Si vous n'utilisez que des certificats Let's Encrypt, supprimez toute directive ssl_stapling de votre configuration Nginx.
Voici la chronologie :
- Decembre 2024. Let's Encrypt a annonce le plan d'abandon de l'OCSP.
- 30 janvier 2025. Les certificats demandant l'extension OCSP Must-Staple ont commence a echouer.
- 7 mai 2025. Les nouveaux certificats ont cesse d'inclure les URL de repondeur OCSP. Les URL CRL ont ete ajoutees a la place.
- 6 aout 2025. Le service OCSP a ete completement arrete. Tous les certificats precedemment emis avec des URL OCSP ont depuis expire.
Si vous voyez ssl_stapling on; ou ssl_stapling_verify on; dans un guide ou un snippet de configuration, c'est un conseil obsolete pour les utilisateurs de Let's Encrypt. Ces directives sont inoffensives (Nginx les ignore silencieusement en l'absence d'URL de repondeur OCSP), mais elles ajoutent de l'encombrement inutile. Supprimez-les.
Si vous utilisez des certificats d'une autre autorite de certification qui fournit encore l'OCSP, ces directives restent valides pour ces certificats.
Pourquoi Let's Encrypt a-t-il abandonne l'OCSP ? Deux raisons. L'OCSP est un risque pour la vie privee : a chaque fois qu'un navigateur verifiait la revocation d'un certificat via OCSP, l'autorite de certification apprenait quel site etait visite et depuis quelle adresse IP. A son pic, le service OCSP de Let's Encrypt traitait 340 milliards de requetes par mois. Le passage aux CRL elimine cette fuite de donnees privees. Les CRL sont telecharges en masse par les navigateurs, donc aucune requete individuelle n'est envoyee a l'autorite de certification pour chaque visite.
Comment activer HTTP/2 avec Nginx ?
HTTP/2 multiplexe les requetes sur une seule connexion, ce qui reduit la latence. Si vous avez installe Nginx depuis le depot officiel nginx.org (version 1.25.1 ou ulterieure), activez HTTP/2 avec la directive http2 dans votre server block.
Ajoutez http2 on; dans votre server block HTTPS :
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include snippets/tls-params.conf;
# ... your location blocks ...
}
La directive http2 on; a remplace la syntaxe obsolete listen 443 ssl http2; dans Nginx 1.25.1. L'ancienne syntaxe fonctionne encore mais produit des avertissements de depreciation dans le journal d'erreurs. Si vous utilisez le Nginx fourni par la distribution (1.22 sur Debian 12, 1.24 sur Ubuntu 24.04), utilisez l'ancienne syntaxe listen 443 ssl http2; a la place.
Testez et rechargez :
sudo nginx -t
sudo systemctl reload nginx
Verifiez que HTTP/2 est actif :
curl -I --http2 -s https://example.com | head -1
Sortie attendue :
HTTP/2 200
Si vous voyez HTTP/1.1 a la place, verifiez que http2 on; est bien dans le bon server block et que votre version de Nginx le supporte.
Comment fonctionne le renouvellement automatique des certificats ?
Les certificats Let's Encrypt expirent apres 90 jours. Certbot installe un timer systemd (certbot.timer) qui verifie deux fois par jour si un certificat arrive a moins de 30 jours de son expiration. Si c'est le cas, il le renouvelle automatiquement. Vous n'avez pas besoin de configurer une tache cron.
Verifiez que le timer est actif :
systemctl status certbot.timer
Vous devriez voir Active: active (waiting) et une ligne indiquant la prochaine heure de declenchement.
Verifiez quand le prochain renouvellement aura lieu :
systemctl list-timers certbot.timer
Cela affiche les heures NEXT et LAST d'execution.
Tester le renouvellement sans renouveler reellement
Lancez un essai a blanc pour verifier que le processus de renouvellement fonctionne de bout en bout :
sudo certbot renew --dry-run
Cette commande contacte le serveur de staging de Let's Encrypt et simule un renouvellement complet. Si elle affiche Congratulations, all simulated renewals succeeded, votre configuration est correcte.
Configurer un hook de deploiement pour recharger Nginx
Quand Certbot renouvelle un certificat, Nginx doit etre recharge pour prendre en compte les nouveaux fichiers. Configurez un hook de deploiement (deploy hook) qui s'execute uniquement apres un renouvellement reussi :
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
Ajoutez :
#!/bin/bash
/usr/bin/systemctl reload nginx
Rendez-le executable :
sudo chmod 700 /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
Verifiez les permissions :
ls -la /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh
La sortie attendue affiche -rwx------ (seul root peut lire et executer).
Le repertoire de hooks deploy execute les scripts uniquement apres un renouvellement reussi, pas a chaque declenchement du timer. Cela evite les rechargements inutiles.
Comment verifier que votre configuration TLS est correcte ?
Apres avoir termine toutes les etapes ci-dessus, lancez ces commandes de verification. Chacune verifie un aspect different de votre configuration.
Verifier la chaine de certificats avec OpenSSL
Depuis votre machine locale :
openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>/dev/null | openssl x509 -noout -dates -subject -issuer
Sortie attendue :
notBefore=Mar 19 00:00:00 2026 GMT
notAfter=Jun 17 00:00:00 2026 GMT
subject=CN = example.com
issuer=C = US, O = Let's Encrypt, CN = R12
A noter : la date notAfter devrait etre environ 90 jours apres l'emission. L'emetteur (issuer) devrait etre Let's Encrypt. Les intermediaires RSA actuels sont R12 et R13. Pour les certificats ECDSA, cherchez E7 ou E8.
Verifier la version TLS et le chiffrement utilises
openssl s_client -connect example.com:443 -servername example.com < /dev/null 2>/dev/null | grep -E "Protocol|Cipher"
Resultat attendu :
Protocol : TLSv1.3
Cipher : TLS_AES_256_GCM_SHA384
Si vous voyez TLSv1.2, c'est egalement correct. Cela depend de la version d'OpenSSL que votre machine locale prefere.
Verifier les en-tetes HTTPS
curl -I https://example.com
Recherchez :
HTTP/2 200
strict-transport-security: max-age=63072000; includeSubDomains
Si strict-transport-security est absent, verifiez la ligne add_header dans votre snippet TLS. Le parametre always garantit que l'en-tete est envoye meme sur les reponses d'erreur.
Resume des commandes de verification
| Commande | Ce qu'elle verifie | Ce qu'il faut chercher |
|---|---|---|
dig +short example.com |
Resolution DNS | L'IP de votre serveur |
curl -I http://example.com |
Redirection HTTP | 301 avec Location: https:// |
curl -I https://example.com |
HTTPS + en-tetes | HTTP/2 200, en-tete HSTS |
openssl s_client -connect ... |
Chaine de certificats, version TLS | Emetteur Let's Encrypt, TLSv1.2 ou 1.3 |
certbot renew --dry-run |
Processus de renouvellement | all simulated renewals succeeded |
systemctl status certbot.timer |
Timer de renouvellement auto | active (waiting) |
Tester avec SSL Labs
Pour un audit externe approfondi, soumettez votre domaine au SSL Labs Server Test. Avec la configuration de ce guide, vous devriez obtenir un score A ou A+. Le A+ necessite HSTS, que nous avons active dans le snippet TLS.
Configuration Nginx complete de reference
Voici le server block complet avec tous les parametres de ce tutoriel combines :
# HTTP -> HTTPS redirect
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# HTTPS server block
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name example.com www.example.com;
# Let's Encrypt certificate
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# TLS hardening
include snippets/tls-params.conf;
root /var/www/example.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# Deny access to hidden files
location ~ /\. {
deny all;
}
}
Et le snippet TLS dans /etc/nginx/snippets/tls-params.conf :
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers off;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:TLS:10m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
server_tokens off;
Pour des en-tetes de securite supplementaires comme Content-Security-Policy, X-Frame-Options et Permissions-Policy, consultez Durcissement de la securite Nginx.
Quelque chose ne fonctionne pas ?
Certbot affiche « Could not automatically find a matching server block »
Certbot recherche une directive server_name correspondant au domaine passe avec -d. Assurez-vous que votre fichier de server block est dans /etc/nginx/conf.d/ ou /etc/nginx/sites-enabled/ et contient server_name example.com;.
Certbot affiche « Connection refused » ou « Challenge failed » Le port 80 doit etre ouvert. Verifiez votre pare-feu :
sudo ufw status # if using UFW
sudo nft list ruleset # if using nftables
Verifiez aussi que Nginx ecoute sur le port 80 :
sudo ss -tlnp | grep ':80'
« SSL: error » dans le journal d'erreurs Nginx apres modification des parametres TLS Vous avez probablement une erreur de syntaxe dans la chaine de chiffrements ou un chemin de fichier manquant. Verifiez :
sudo nginx -t
sudo journalctl -u nginx -n 20 --no-pager
Le navigateur affiche « NET::ERR_CERT_DATE_INVALID » Le certificat a peut-etre expire. Verifiez l'expiration :
sudo certbot certificates
S'il a expire, forcez un renouvellement :
sudo certbot renew --force-renewal
certbot renew --dry-run echoue
Cause frequente : le DNS du domaine ne pointe plus vers ce serveur, ou le port 80 est bloque. Certbot a besoin d'un acces HTTP-01 pour le renouvellement.
HTTP/2 ne fonctionne pas
Verifiez votre version de Nginx : nginx -v. Si elle est inferieure a 1.25.1, utilisez listen 443 ssl http2; au lieu de la directive separee http2 on;. Si elle est en 1.25.1 ou superieure, assurez-vous que http2 on; est bien dans le bon bloc server (pas dans http ou location).
Copyright 2026 Virtua.Cloud. Tous droits reserves. Ce contenu est une creation originale de l'equipe Virtua.Cloud. Toute reproduction, republication ou redistribution sans autorisation ecrite est interdite.
Prêt à essayer ?
Déployez votre serveur en quelques secondes. Linux, Windows ou FreeBSD.
Voir les offres VPS