Mettre en place SSL/TLS
Ce guide accompagne la mise en HTTPS d'un site derrière Apache avec des certificats Let's Encrypt (Certbot). Il suppose que vous savez déjà administrer un serveur Linux et manipuler des VirtualHosts. Remplacez systématiquement <VOTRE_DOMAINE> par votre domaine réel.
Obtenir un certificat
Installer Certbot
sudo apt install certbot python3-certbot-apache -y
Émettre le certificat
Un seul domaine :
sudo certbot --apache -d <VOTRE_DOMAINE>
Domaine + sous-domaine www (certificat multi-SAN) :
sudo certbot --apache -d <VOTRE_DOMAINE> -d www.<VOTRE_DOMAINE>
Le plugin --apache configure le VirtualHost pour vous. Si vous préférez garder la main sur la configuration, utilisez certonly (voir plus bas) et référencez les certificats manuellement.
Vérifier le renouvellement automatique
Certbot installe un timer de renouvellement. Testez-le Ă blanc :
sudo certbot renew --dry-run
En cas de certificat désynchronisé ou corrompu, forcez le renouvellement :
# tous les certificats sudo certbot renew --force-renewal # un certificat précis sudo certbot renew --cert-name <VOTRE_DOMAINE> --force-renewal
Configurer Apache
Activer les modules
sudo a2enmod ssl headers http2
VirtualHost HTTP → HTTPS
Redirigez tout le trafic port 80 vers HTTPS :
<VirtualHost *:80> ServerName <VOTRE_DOMAINE> Redirect permanent / https://<VOTRE_DOMAINE> </VirtualHost>
VirtualHost HTTPS
<VirtualHost *:443> ServerName <VOTRE_DOMAINE> Protocols h2 http/1.1 DocumentRoot /var/www/<VOTRE_SITE>/public <Directory /var/www/<VOTRE_SITE>/public> AllowOverride None Require all granted </Directory> # Certificats SSLEngine on SSLCertificateFile /etc/letsencrypt/live/<VOTRE_DOMAINE>/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/<VOTRE_DOMAINE>/privkey.pem # Protocoles et chiffrements : on désactive tout ce qui est obsolète SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite HIGH:!aNULL:!MD5 SSLHonorCipherOrder on # En-têtes de sécurité Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" Header always set X-Frame-Options "SAMEORIGIN" Header always set X-Content-Type-Options "nosniff" Header always set Referrer-Policy "strict-origin-when-cross-origin" </VirtualHost>
Deux réglages structurants côté sécurité :
SSLProtocol ... -TLSv1 -TLSv1.1coupe les versions de TLS jugées faibles : on ne garde que TLS 1.2 et au-dessus.HIGH:!aNULL:!MD5écarte les suites de chiffrement sans authentification et le MD5. Pour un réglage à jour et généré selon votre cible, appuyez-vous sur le générateur Mozilla (voir Ressources).
Publier le VirtualHost
sudo a2ensite <VOTRE_SITE>.conf sudo apachectl configtest sudo systemctl reload apache2
Déboguer
Inspecter le certificat sur disque
# domaines couverts (CN et SAN) sudo openssl x509 -in /etc/letsencrypt/live/<VOTRE_DOMAINE>/fullchain.pem \ -noout -text | grep -E "(Subject:|DNS:)" # dates de validité sudo openssl x509 -in /etc/letsencrypt/live/<VOTRE_DOMAINE>/fullchain.pem \ -noout -dates
Inspecter le certificat réellement servi
echo | openssl s_client -connect <VOTRE_DOMAINE>:443 -servername <VOTRE_DOMAINE> 2>/dev/null \ | openssl x509 -noout -subject -dates -ext subjectAltName
Comparer le certificat sur disque et celui servi est la manœuvre de diagnostic la plus utile : la plupart des incidents viennent d'un écart entre les deux.
Vérifier côté client
curl -I --http2 https://<VOTRE_DOMAINE> curl -Iv https://<VOTRE_DOMAINE> # voir la négociation TLS
Vérifier la configuration Apache
sudo apachectl -t -D DUMP_VHOSTS | grep 443 sudo apachectl configtest
Erreurs courantes
« no alternative certificate subject name matches target hostname »
Le certificat ne couvre pas le domaine demandé (CN/SAN incomplet). Comparez le certificat sur disque et le certificat servi (commandes ci-dessus). Si le certificat est incomplet, ré-émettez-le avec tous les domaines :
sudo certbot certonly --apache -d <VOTRE_DOMAINE> -d www.<VOTRE_DOMAINE> sudo systemctl reload apache2
VirtualHost en double (conflit SNI)
Apache sert le certificat d'un autre domaine parce qu'un même ServerName apparaît dans plusieurs VirtualHosts *:443.
# repérer les doublons sudo apachectl -t -D DUMP_VHOSTS | grep 443 sudo grep -r "ServerName <VOTRE_DOMAINE>" /etc/apache2/sites-enabled/
Règle : un ServerName ne doit apparaître qu'une seule fois parmi les VirtualHosts *:443. Supprimez ou fusionnez les configurations en conflit, puis configtest + reload.
Certificat expiré
sudo certbot certificates # constater l'expiration sudo certbot renew --force-renewal sudo systemctl reload apache2
Mixed content (ressources en HTTP sur une page HTTPS)
Forcez la mise Ă niveau des requĂŞtes dans le VirtualHost *:443 :
Header always set Content-Security-Policy "upgrade-insecure-requests"
Pages d'erreur mal encodées (ISO-8859-1)
Les pages d'erreur générées par Apache peuvent partir en Latin-1. Forcez l'UTF-8, y compris sur les réponses 4xx/5xx :
Header always edit Content-Type "^text/html(;.*)?$" "text/html; charset=UTF-8"
Le mot-clé always est indispensable pour couvrir les codes d'erreur.
« SSLCertificateFile: file does not exist »
Apache ne démarre pas car le chemin de certificat est faux ou le lien symbolique est cassé :
sudo ls -la /etc/letsencrypt/live/<VOTRE_DOMAINE>/ sudo readlink -f /etc/letsencrypt/live/<VOTRE_DOMAINE>/fullchain.pem
Corrigez le chemin dans le VirtualHost, puis configtest + reload.
Valider le résultat
# HTTP/2 actif curl -I --http2 https://<VOTRE_DOMAINE> | head -1 # attendu : HTTP/2 200 # HSTS présent curl -I https://<VOTRE_DOMAINE> | grep -i strict-transport-security # redirection HTTP → HTTPS curl -I http://<VOTRE_DOMAINE> # attendu : 301 + Location https://
Complétez par un audit externe (SSL Labs) pour noter la chaîne de certificats et les suites de chiffrement.
Checklist
- Certbot installé, certificat émis pour tous les domaines
- VirtualHost 80 → 443 en redirection permanente
- Certificats correctement référencés, aucun doublon de
ServerNameen*:443 - TLS 1.2+ uniquement, suites de chiffrement sûres
- En-têtes de sécurité (HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy)
- HTTP/2 actif
- Redirection et HSTS validés (curl + audit externe)
- Renouvellement automatique testé (
--dry-run)
Ressources
- Documentation Certbot — https://certbot.eff.org/
- Mozilla SSL Configuration Generator — https://ssl-config.mozilla.org/
- SSL Labs Server Test — https://www.ssllabs.com/ssltest/
- Let's Encrypt — https://letsencrypt.org/docs/