
HTTPS avec Certbot et Nginx : configuration avancée et harden...
Configuration complète de Certbot avec Nginx : certificats Let's Encrypt, hardening TLS 1.3, en-têtes de sécurité, renouvellement automatisé et dépannage avancé.
HTTPS avec Certbot et Nginx : configuration avancée et hardening SSL
Ce guide couvre l'installation de Certbot, l'obtention de certificats Let's Encrypt, le durcissement de la configuration TLS sur Nginx et la mise en place d'un monitoring de renouvellement. On cible une note A+ sur SSL Labs.
Pré-requis
- Serveur Ubuntu 22.04 LTS ou Debian 12 avec accès root
- Nginx installé et opérationnel
- Nom de domaine avec enregistrement DNS A et AAAA (si IPv6) pointant vers le serveur
- Ports 80 et 443 ouverts (pare-feu et éventuel security group cloud)
Vérification rapide :
## Confirmer que Nginx répond et que le DNS est résolu
nginx -v
curl -sI http://mondomaine.fr | head -5
dig +short mondomaine.frInstallation de Certbot via Snap
Snap garantit une version à jour indépendante des dépôts de la distribution.
## Installer et mettre à jour le runtime Snap
sudo snap install core && sudo snap refresh core
## Supprimer toute version apt résiduelle
sudo apt remove certbot -y 2>/dev/null
## Installer Certbot avec le plugin Nginx
sudo snap install —classic certbot
sudo ln -sf /snap/bin/certbot /usr/bin/certbot
## Vérifier l'installation
certbot —version
certbot pluginsLa commande certbot plugins doit lister "nginx" parmi les plugins disponibles.
Configuration Nginx pré-Certbot
Avant de lancer Certbot, préparez un bloc serveur propre. Certbot modifiera ce fichier, mais partir d'une base solide évite les surprises.
sudo nano /etc/nginx/sites-available/mondomaine.frContenu :
server {
listen 80;
listen [::]:80;
server_name mondomaine.fr www.mondomaine.fr;
root /var/www/mondomaine.fr;
index index.html;
# Nécessaire pour la validation HTTP-01 de Let's Encrypt
location /.well-known/acme-challenge/ {
root /var/www/mondomaine.fr;
}
location / {
try_files $uri $uri/ =404;
}
}## Activer le site et tester la configuration
sudo ln -sf /etc/nginx/sites-available/mondomaine.fr /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginxObtention du certificat
Méthode automatique (recommandée)
sudo certbot —nginx \
-d mondomaine.fr \
-d www.mondomaine.fr \
—non-interactive \
—agree-tos \
—email admin@mondomaine.fr \
—redirectOptions expliquées :
—non-interactive: pas de questions interactives—redirect: redirection HTTP vers HTTPS automatique—agree-tos: acceptation des conditions Let's Encrypt
Méthode manuelle (certonly)
Si vous préférez configurer Nginx vous-même :
sudo certbot certonly —nginx \
-d mondomaine.fr \
-d www.mondomaine.fr \
—agree-tos \
—email admin@mondomaine.frLes certificats sont stockés dans /etc/letsencrypt/live/mondomaine.fr/.
Certificat wildcard (DNS-01)
Pour un certificat couvrant tous les sous-domaines :
sudo certbot certonly \
—manual \
—preferred-challenges dns \
-d "*.mondomaine.fr" \
-d mondomaine.fr \
—agree-tos \
—email admin@mondomaine.frCertbot demandera d'ajouter un enregistrement DNS TXT _acme-challenge.mondomaine.fr. Ajoutez-le chez votre registrar, attendez la propagation (dig TXT _acme-challenge.mondomaine.fr), puis validez.
Pour automatiser les wildcards, utilisez un plugin DNS (Cloudflare, OVH, etc.) :
## Exemple avec Cloudflare
sudo snap install certbot-dns-cloudflare
## Créer le fichier de credentials
sudo mkdir -p /etc/letsencrypt
cat << 'EOF' | sudo tee /etc/letsencrypt/cloudflare.ini
dns_cloudflare_api_token = VOTRE_TOKEN_CLOUDFLARE
EOF
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
## Obtenir le certificat wildcard automatiquement
sudo certbot certonly \
—dns-cloudflare \
—dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d "*.mondomaine.fr" \
-d mondomaine.frHardening SSL/TLS — Viser la note A+
La configuration par défaut de Certbot donne une note A. Pour atteindre A+, il faut renforcer plusieurs paramètres.
Générer des paramètres Diffie-Hellman
## Générer des paramètres DH de 4096 bits (prend 2-5 minutes)
sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096Snippet de configuration SSL durci
Créez un fichier de paramètres SSL réutilisable :
sudo nano /etc/nginx/snippets/ssl-hardening.conf## Protocoles — TLS 1.2 minimum, TLS 1.3 préféré
ssl_protocols TLSv1.2 TLSv1.3;
## Suites de chiffrement modernes
## Le serveur choisit (pas le client)
ssl_prefer_server_ciphers on;
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';
## Paramètres Diffie-Hellman renforcés
ssl_dhparam /etc/nginx/dhparam.pem;
## Cache de session SSL
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
## OCSP Stapling — le serveur vérifie la validité du certificat
## pour que le navigateur n'ait pas à le faire
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;
## HSTS — forcer HTTPS pendant 1 an, inclure les sous-domaines
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
## En-têtes de sécurité supplémentaires
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 "camera=(), microphone=(), geolocation=()" always;Configuration Nginx complète post-hardening
sudo nano /etc/nginx/sites-available/mondomaine.fr## Redirection HTTP vers HTTPS
server {
listen 80;
listen [::]:80;
server_name mondomaine.fr www.mondomaine.fr;
return 301 https://$host$request_uri;
}
## Bloc HTTPS principal
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mondomaine.fr www.mondomaine.fr;
# Certificats Let's Encrypt
ssl_certificate /etc/letsencrypt/live/mondomaine.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/mondomaine.fr/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/mondomaine.fr/chain.pem;
# Importer le snippet de hardening
include /etc/nginx/snippets/ssl-hardening.conf;
root /var/www/mondomaine.fr;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# Bloquer les fichiers sensibles
location ~ /\. {
deny all;
}
# Logs séparés
access_log /var/log/nginx/mondomaine.fr.access.log;
error_log /var/log/nginx/mondomaine.fr.error.log;
}## Tester et appliquer
sudo nginx -t && sudo systemctl reload nginxGestion du renouvellement
Vérifier le timer systemd
Certbot installé via Snap crée un timer systemd automatiquement :
## Vérifier que le timer est actif
systemctl list-timers | grep certbot
## Ou via Snap
sudo snap logs certbot -n 20Test de renouvellement
## Simulation complète sans modification
sudo certbot renew —dry-runHook post-renouvellement
Pour recharger Nginx après chaque renouvellement :
sudo mkdir -p /etc/letsencrypt/renewal-hooks/deploy
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh#!/bin/bash
## Hook de déploiement — recharger Nginx après renouvellement
systemctl reload nginx
echo "$(date): Nginx rechargé après renouvellement du certificat" >> /var/log/letsencrypt-renewal.logsudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.shScript de monitoring d'expiration
Créez un script qui vérifie la date d'expiration et alerte si le certificat expire dans moins de 14 jours :
sudo nano /usr/local/bin/check-ssl-expiry.sh#!/bin/bash
## Vérifier l'expiration du certificat SSL
## Usage : check-ssl-expiry.sh mondomaine.fr [jours_seuil]
DOMAIN="${1:-mondomaine.fr}"
THRESHOLD="${2:-14}"
EXPIRY_DATE=$(echo | openssl s_client -servername "$DOMAIN" -connect "$DOMAIN":443 2>/dev/null \
| openssl x509 -noout -enddate 2>/dev/null \
| cut -d= -f2)
if [ -z "$EXPIRY_DATE" ]; then
echo "ERREUR: Impossible de récupérer le certificat de $DOMAIN"
exit 2
fi
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s 2>/dev/null || date -jf "%b %d %T %Y %Z" "$EXPIRY_DATE" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
if [ "$DAYS_LEFT" -lt "$THRESHOLD" ]; then
echo "ALERTE: Le certificat de $DOMAIN expire dans $DAYS_LEFT jours ($EXPIRY_DATE)"
exit 1
else
echo "OK: Le certificat de $DOMAIN expire dans $DAYS_LEFT jours ($EXPIRY_DATE)"
exit 0
fisudo chmod +x /usr/local/bin/check-ssl-expiry.sh
## Ajouter en cron pour vérification quotidienne
echo "0 8 * * * root /usr/local/bin/check-ssl-expiry.sh mondomaine.fr 14" \
| sudo tee /etc/cron.d/check-ssl-expiryConfiguration Certbot avancée
Fichier CLI par défaut
Pour éviter de répéter les options à chaque commande :
sudo nano /etc/letsencrypt/cli.ini## Configuration par défaut de Certbot
email = admin@mondomaine.fr
authenticator = nginx
installer = nginx
agree-tos = true
no-eff-email = true
key-type = ecdsa
elliptic-curve = secp384r1
rsa-key-size = 4096Le paramètre key-type = ecdsa génère des certificats avec des clés elliptiques, plus petites et plus rapides que RSA.
Révoquer un certificat
## Révoquer par chemin de certificat
sudo certbot revoke —cert-path /etc/letsencrypt/live/mondomaine.fr/cert.pem
## Supprimer les fichiers locaux après révocation
sudo certbot delete —cert-name mondomaine.frCertificats multi-domaines (SAN)
sudo certbot —nginx \
-d mondomaine.fr \
-d www.mondomaine.fr \
-d api.mondomaine.fr \
-d blog.mondomaine.fr \
—expandL'option —expand ajoute les nouveaux domaines au certificat existant.
Dépannage
Erreur : "Could not automatically find a matching server block"
Certbot ne trouve pas de directive server_name correspondante dans Nginx.
## Vérifier que le server_name est correct
grep -r server_name /etc/nginx/sites-enabled/
## Le domaine dans la commande certbot doit correspondre exactementErreur : "Connection refused" ou "Timeout" lors de la validation
Le port 80 est bloqué. Vérifications :
## Tester si le port 80 est ouvert depuis l'extérieur
curl -sI http://mondomaine.fr/.well-known/acme-challenge/test
## Vérifier le pare-feu
sudo ufw status
sudo iptables -L -n | grep -E '80|443'
## Vérifier qu'aucun autre service n'utilise le port 80
sudo ss -tlnp | grep ':80'Erreur : "Too many certificates already issued"
Let's Encrypt impose des limites de débit :
- 50 certificats par domaine enregistré par semaine
- 5 duplicatas par semaine
- 300 nouveaux ordres par compte par 3 heures
Pour les tests, utilisez l'environnement staging :
sudo certbot —nginx —staging -d mondomaine.frErreur : "OCSP stapling not working"
## Vérifier l'OCSP stapling
openssl s_client -connect mondomaine.fr:443 -status < /dev/null 2>/dev/null \
| grep -A 4 "OCSP Response"
## Si "no response sent", vérifier le resolver DNS dans la config Nginx
## et que ssl_trusted_certificate pointe vers chain.pemErreur : "SSL routines:ssl3_read_bytes:tlsv1 alert protocol version"
Un client tente de se connecter avec TLS 1.0 ou 1.1 (désactivés par le hardening). C'est normal et voulu. Si vous devez supporter d'anciens clients :
## Déconseillé mais possible
ssl_protocols TLSv1.2 TLSv1.3;
## Ne PAS réactiver TLS 1.0/1.1Vérifier la note SSL Labs en ligne de commande
## Tester la configuration SSL depuis le terminal
curl -s "https://api.ssllabs.com/api/v3/analyze?host=mondomaine.fr&publish=off" \
| jq '.endpoints[0].grade'Résumé des fichiers et chemins
| Fichier | Rôle |
|————-|———|
| /etc/letsencrypt/live/domaine/fullchain.pem | Certificat complet (cert + intermédiaire) |
| /etc/letsencrypt/live/domaine/privkey.pem | Clé privée |
| /etc/letsencrypt/live/domaine/chain.pem | Certificat intermédiaire (OCSP) |
| /etc/letsencrypt/live/domaine/cert.pem | Certificat seul (rarement utilisé) |
| /etc/letsencrypt/renewal/domaine.conf | Configuration de renouvellement |
| /etc/letsencrypt/cli.ini | Options par défaut de Certbot |
| /etc/nginx/snippets/ssl-hardening.conf | Snippet de durcissement SSL |
| /etc/nginx/dhparam.pem | Paramètres Diffie-Hellman |
| /etc/letsencrypt/renewal-hooks/deploy/ | Scripts post-renouvellement |
Avec cette configuration, le certificat se renouvelle automatiquement, Nginx est rechargé à chaque renouvellement, et le monitoring prévient en cas de problème. La note A+ sur SSL Labs confirme que la chaîne de confiance et le chiffrement sont au niveau des bonnes pratiques actuelles.
À lire aussi
Nmap avancé : audit réseau et détection de vulnérabilités
Maîtrisez les techniques avancées de Nmap : scripts NSE, scan furtif, timing, détection d'OS, export automatisé et intégration dans vos workflows de sécurité.
Scanner son réseau avec Nmap : le guide pas à pas
Apprenez à utiliser Nmap pour détecter les appareils connectés, les ports ouverts et les failles de sécurité sur votre réseau. Guide complet pour débutants.
Audit de mots de passe avec KeePassXC : guide technique avancé
Audit complet de votre base KeePassXC : vérification HIBP en CLI, détection de doublons, automatisation avec keepassxc-cli et hardening de la base de données.