Credit : Logo officiel
Configurer HTTPS partout : guide SSL/TLS complet
HTTP en 2026, c'est non. Vraiment non.
Un jeudi soir a 23h, sur le serveur d'un client a Lyon, j'ai termine le passage en HTTPS d'un site qui tournait encore en HTTP en 2026. Oui, il en existe encore. Le client perdait du trafic Google sans comprendre pourquoi, son taux de rebond explosait sur Chrome qui affiche des warnings flippants, et son formulaire de contact passait des mots de passe en clair sur le reseau. Cinquante minutes de Certbot, une config Nginx propre, un test sur SSL Labs, et son site est passe en grade A+.
A force de configurer du HTTPS, je le fais presque les yeux fermes. Mais entre activer Let's Encrypt et avoir une config vraiment moderne (TLS 1.3, HSTS, OCSP Stapling, ciphers solides), il y a des etapes qu'on saute souvent et qui font la difference dans les audits de securite. Dans ce guide je couvre tout : installation, config Nginx et Apache, HSTS, certificats wildcard, debug, le tout avec les valeurs que j'utilise vraiment en production.
A noter qu'en 2026, n'importe quel certificat SSL gratuit Let's Encrypt suffit pour 99% des cas. Les certificats payants type EV (Extended Validation) avec la barre verte n'existent plus chez la plupart des navigateurs, et leurs benefices marketing sont nuls. Restez sur Let's Encrypt sauf besoin tres specifique.
Installer Certbot, le client Let's Encrypt
Certbot est l'implementation officielle qui automatise la generation et le renouvellement des certificats Let's Encrypt. Sur Debian 12 et Ubuntu 24.04 :
sudo apt update
sudo apt install certbot python3-certbot-nginx
# Pour Apache
sudo apt install certbot python3-certbot-apache
# Verifier la version
certbot --version
# certbot 2.9.0
Sur des distributions plus anciennes ou pour avoir la derniere version, utilisez snap :
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Generer un certificat avec le plugin Nginx
La commande la plus simple, qui modifie automatiquement votre config Nginx :
sudo certbot --nginx -d monsite.fr -d www.monsite.fr
Certbot vous pose quelques questions :
- Email pour les notifications de renouvellement (mettez-en un valide, vous voulez etre prevenu si un renouvellement echoue)
- Acceptation des CGU
- Choix : redirection automatique HTTP -> HTTPS (oui, toujours oui)
Apres execution, Certbot a ajoute un bloc server { listen 443 ssl; } dans votre conf Nginx, configure les certificats, et redirige le port 80 vers 443. Le site est en HTTPS.
Generer en mode standalone
Si vous n'avez pas encore de serveur web actif, ou si vous preferez gerer la config a la main :
# Arreter Nginx temporairement
sudo systemctl stop nginx
# Generer en standalone
sudo certbot certonly --standalone -d monsite.fr -d www.monsite.fr
# Redemarrer Nginx
sudo systemctl start nginx
Les certificats sont stockes dans /etc/letsencrypt/live/monsite.fr/ :
fullchain.pem: certificat + chaine intermediaireprivkey.pem: cle priveechain.pem: juste la chaine intermediaire (pour OCSP Stapling)
Verifier le renouvellement automatique
Sur Debian/Ubuntu, l'installation de certbot cree automatiquement un timer systemd qui tourne deux fois par jour pour renouveler les certificats qui expirent dans moins de 30 jours.
sudo systemctl list-timers | grep certbot
# certbot.timer ... Wed 2026-05-07 12:00:00 UTC
# Tester un renouvellement a sec (sans rien changer)
sudo certbot renew --dry-run
Si le dry-run passe, vous etes tranquille pour les annees a venir. Si ca plante, regardez les logs dans /var/log/letsencrypt/letsencrypt.log. La cause classique : le port 80 bloque par un firewall, ou le DNS qui ne pointe plus vers ce serveur.
Config Nginx qui tient la route (grade A+ sur SSL Labs)
Voici la config qu'on utilise en prod sur tous nos serveurs. Elle est testee sur des dizaines de domaines, score A+ systematique sur ssllabs.com :
# Redirection HTTP vers HTTPS
server {
listen 80;
listen [::]:80;
server_name monsite.fr www.monsite.fr;
return 301 https://monsite.fr$request_uri;
}
# Redirection www vers non-www en HTTPS
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name www.monsite.fr;
ssl_certificate /etc/letsencrypt/live/monsite.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/monsite.fr/privkey.pem;
return 301 https://monsite.fr$request_uri;
}
# Site principal
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name monsite.fr;
# Certificats
ssl_certificate /etc/letsencrypt/live/monsite.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/monsite.fr/privkey.pem;
# Protocoles modernes uniquement
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;
ssl_prefer_server_ciphers off;
# Session resumption
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/monsite.fr/chain.pem;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
# Headers de securite
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
root /var/www/monsite/public;
index index.php index.html;
# ... votre config applicative
}
Quelques notes importantes sur cette config :
ssl_protocols TLSv1.2 TLSv1.3: on exclut TLS 1.0 et 1.1 qui sont obsoletes et vulnerables. TLS 1.3 est le standard moderne et est supporte par tous les navigateurs depuis 2019.ssl_prefer_server_ciphers off: avec TLS 1.3, le client choisit les ciphers, c'est plus moderne.ssl_session_tickets off: les session tickets etaient vulnerables a certaines attaques, mieux vaut les desactiver et compter sur le cache de session.http2 on: la nouvelle syntaxe Nginx 1.25+. Avant c'etaitlisten 443 ssl http2, maintenant on separe.
Apres modification :
sudo nginx -t
sudo systemctl reload nginx
Config Apache (pour ceux qui sont encore dessus)
Apache reste utilise sur des hebergements legacy. Voici la config equivalente :
<VirtualHost *:80>
ServerName monsite.fr
ServerAlias www.monsite.fr
Redirect permanent / https://monsite.fr/
</VirtualHost>
<VirtualHost *:443>
ServerName monsite.fr
DocumentRoot /var/www/monsite/public
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/monsite.fr/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/monsite.fr/privkey.pem
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite 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
SSLHonorCipherOrder off
SSLUseStapling on
SSLStaplingCache shmcb:/var/run/ocsp(128000)
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
<Directory /var/www/monsite/public>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Activer les modules Apache necessaires :
sudo a2enmod ssl rewrite headers http2
sudo systemctl restart apache2
HSTS : a activer prudemment
HSTS (HTTP Strict Transport Security) dit au navigateur "a partir de maintenant et pour X temps, ne contacte JAMAIS ce domaine en HTTP, meme si l'utilisateur tape http:// dans la barre d'adresse".
Le header :
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Decortiquons :
max-age=63072000: 2 ans en secondes. Le navigateur retient cette directive pendant 2 ans.includeSubDomains: applique HSTS a TOUS les sous-domaines aussi (admin.monsite.fr, api.monsite.fr, etc.)preload: eligible a la preload list de Chrome/Firefox/Safari, qui est compilee en dur dans les navigateurs
Attention au piege. J'ai vu un client activer le preload puis vouloir revenir en HTTP trois mois plus tard pour un sous-domaine interne (un environnement de dev qu'il avait oublie). Bah ce n'est plus possible : le navigateur refuse, et meme si vous virez le header de votre serveur, les navigateurs des visiteurs gardent l'info pendant la duree max-age.
Ma recommandation pragmatique :
- Demarrez avec
max-age=300(5 minutes) pendant que vous testez tous vos sous-domaines - Passez a
max-age=86400(1 jour) pendant 1 semaine - Si tout est ok, passez a
max-age=63072000(2 ans) avec includeSubDomains - Pour la preload list, soumettez sur https://hstspreload.org/ apres avoir confirme que TOUS vos sous-domaines (presents et a venir) seront en HTTPS pour les annees a venir
Une fois preload, c'est tres difficile de revenir en arriere, comptez 6-12 mois de delai pour etre retire de la liste.
OCSP Stapling : un detail qui acce le SSL
Le principe : quand un navigateur se connecte en HTTPS, il doit verifier que le certificat n'est pas revoque. Sans Stapling, il va interroger Let's Encrypt directement, ce qui ajoute de la latence (et fait fuiter votre IP a Let's Encrypt). Avec Stapling, c'est votre serveur qui pre-recupere la reponse OCSP et l'attache aux handshakes SSL.
La config est deja dans la conf Nginx ci-dessus. Verifiez que ca marche :
openssl s_client -connect monsite.fr:443 -status -servername monsite.fr 2>/dev/null | grep -A 17 "OCSP response:"
Si vous voyez OCSP Response Status: successful avec une signature, c'est bon. Sinon, redemarrez Nginx et reessayez (le stapling se met en place apres quelques requetes).
Tester votre config
Les outils que j'utilise systematiquement apres une mise en place HTTPS :
# Verifier les headers
curl -I https://monsite.fr
# Verifier HSTS specifiquement
curl -sI https://monsite.fr | grep -i strict
# Verifier les protocoles supportes
nmap --script ssl-enum-ciphers -p 443 monsite.fr
# Tester le handshake TLS 1.3
openssl s_client -connect monsite.fr:443 -tls1_3 < /dev/null
# Verifier la chaine de certificats
openssl s_client -connect monsite.fr:443 -servername monsite.fr -showcerts < /dev/null
Surtout, lancez un audit complet sur ssllabs.com/ssltest. Visez le grade A+. Avec la config plus haut, vous devriez l'avoir directement. Si vous obtenez A ou B, l'outil vous dit precisement ce qui manque (HSTS, ciphers, etc.).
Autres outils utiles : https://hardenize.com, https://internet.nl, https://observatory.mozilla.org pour des audits HTTP plus larges.
Wildcard SSL pour les sous-domaines multiples
Si vous avez plein de sous-domaines (api.monsite.fr, app.monsite.fr, blog.monsite.fr, etc.), un certificat wildcard *.monsite.fr simplifie la gestion. Let's Encrypt supporte les wildcards mais uniquement via challenge DNS (pas HTTP).
sudo certbot certonly --manual --preferred-challenges dns \
-d monsite.fr -d '*.monsite.fr'
Certbot vous demande d'ajouter un enregistrement TXT _acme-challenge.monsite.fr chez votre DNS provider. Une fois ajoute, attendez la propagation (verifiez avec dig TXT _acme-challenge.monsite.fr), puis appuyez sur Entree. Le certificat est genere.
Probleme : le challenge DNS manuel veut dire qu'il faut refaire l'operation a chaque renouvellement (tous les 90 jours). Pour automatiser, utilisez les plugins DNS Certbot :
# Pour Cloudflare
sudo apt install python3-certbot-dns-cloudflare
# Stocker le token API Cloudflare (avec permission Zone:DNS:Edit)
sudo nano /etc/letsencrypt/cloudflare.ini
# dns_cloudflare_api_token = votreTokenAPI
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
# Generer le wildcard automatiquement
sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d monsite.fr -d '*.monsite.fr'
Des plugins similaires existent pour OVH, Gandi, Route53, DigitalOcean, Hetzner, et beaucoup d'autres registrars/DNS hosts.
Erreurs courantes et leur fix
ERR_SSL_PROTOCOL_ERROR sur Chrome. Vous avez exclu TLS 1.0/1.1 mais des vieux navigateurs essaient de se connecter avec. En 2026, vous pouvez ignorer (les vieux navigateurs sont une fraction infime du trafic). Si vraiment besoin, rajoutez TLSv1.1 dans ssl_protocols.
Certbot echoue avec "Connection refused" sur le port 80. Le firewall bloque le port 80, ou Nginx n'ecoute pas sur le port 80. Verifiez sudo ufw status et la config Nginx. Le port 80 doit etre ouvert et accessible publiquement pour le challenge HTTP-01.
"Too many certificates already issued for: monsite.fr". Limite Let's Encrypt : 50 certificats par domaine racine par semaine. Si vous testez en boucle, utilisez l'environnement de staging :
sudo certbot --nginx --staging -d monsite.fr
Les certifs staging ne sont pas trustes par les navigateurs mais ne comptent pas dans la limite.
Mixed content warnings. Votre site est en HTTPS mais charge des assets en HTTP (images, scripts). Ouvrez la console Chrome, localisez les ressources HTTP, modifiez les URLs en HTTPS ou en chemins relatifs. Pour WordPress, utilisez le plugin Better Search Replace et remplacez http://monsite.fr par https://monsite.fr dans toute la base.
Redirect loop avec Cloudflare. Vous etes en mode SSL Flexible cote Cloudflare. Passez en Full ou Full (Strict). Voir mon article dedie aux boucles de redirection SSL Cloudflare.
Pour aller plus loin
- Certificat SSL wildcard avec Let's Encrypt
- Resoudre les boucles de redirection SSL Cloudflare
- Reverse proxy Nginx avec SSL
- Mettre en place un CDN gratuit avec Cloudflare
- Hardening Linux, securiser un serveur
Conclusion : HTTPS partout, par defaut, sans exception
En 2026, le HTTPS n'est plus un choix, c'est un prerequis. Google retrograde les sites HTTP, les navigateurs affichent des warnings dissuasifs, les nouveaux protocoles HTTP/2 et HTTP/3 ne fonctionnent qu'avec SSL. Et entre Let's Encrypt et Certbot, le cout est nul et la mise en place fait en moins d'une heure.
La difference entre une config par defaut et une config A+ sur SSL Labs ne tient qu'a quelques lignes : HSTS bien configure, ciphers modernes, OCSP Stapling, headers de securite. Utilisez la conf Nginx de cet article comme base, adaptez les chemins, lancez un audit, corrigez les warnings, et oubliez. Vos certificats se renouvellent tout seuls, vos visiteurs sont proteges, votre referencement Google est preserve.
Derniere chose : pensez a mettre une alerte sur l'expiration de vos certificats. Meme avec le renouvellement auto, ca arrive qu'un truc plante (DNS modifie, port 80 bloque par un nouveau firewall). Un check uptime ou un script cron qui verifie openssl x509 -enddate toutes les semaines vous evite la mauvaise surprise du dimanche matin.