Introduction
Les certificats Transport Layer Security (TLS) sont la base de la confiance pour les services web modernes. Ils authentifient votre serveur auprès des clients et chiffrent le trafic en transit. Mais un certificat n'est aussi sûr que la façon dont vous gérez sa clé privée et sa configuration. Un certificat mal configuré peut exposer vos utilisateurs à des attaques de type man-in-the-middle, casser votre site ou entraîner des échecs de conformité.
Ce guide présente des étapes pratiques de durcissement des certificats TLS. Vous apprendrez à inventorier votre environnement, à verrouiller l'accès aux clés, à définir des permissions restrictives, à configurer Nginx en toute sécurité, à vérifier votre configuration avec des commandes concrètes et à récupérer après des échecs courants. Chaque étape inclut une commande ou un extrait de configuration avec le résultat attendu pour que vous puissiez l'appliquer immédiatement.
Pourquoi est-ce important ? Une seule clé privée divulguée peut compromettre tout le trafic vers votre domaine. Des permissions de fichiers trop permissives sont une erreur courante qui transforme un utilisateur local en voleur de certificat. Des paramètres TLS faibles vous rendent vulnérable aux attaques par rétrogradation. À la fin de cet article, vous disposerez d'une liste de contrôle reproductible pour durcir vos certificats TLS et les garder en sécurité.
Inventaire des versions et de l'environnement
Avant de modifier quoi que ce soit, documentez ce que vous avez. Vous devez connaître votre système d'exploitation, la version de votre serveur web, la version d'OpenSSL et l'emplacement de vos certificats et clés. Cet inventaire vous aide à choisir des paramètres compatibles et à éviter de casser votre service.
Commencez par vérifier les versions de votre système d'exploitation et de votre serveur web. Sur un serveur Linux typique exécutant Nginx, lancez :
cat /etc/os-release | head -n 2
nginx -v
openssl version
Le résultat attendu ressemblera à ceci (les versions varient selon la distribution) :
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
nginx version: nginx/1.18.0 (Ubuntu)
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)
Localisez maintenant vos fichiers de certificat et de clé. Les emplacements courants incluent /etc/ssl/, /etc/nginx/ssl/ ou /etc/letsencrypt/live/. Utilisez find pour les lister :
sudo find /etc -name "*.crt" -o -name "*.pem" -o -name "*.key" 2>/dev/null
Exemple de sortie :
/etc/ssl/certs/example.com.crt
/etc/ssl/private/example.com.key
Notez les chemins et les permissions. Nous les resserrerons dans la section suivante. Vérifiez également si des certificats sont groupés avec des autorités de certification intermédiaires ; vous pourriez avoir un fichier fullchain. Si vous utilisez une autorité de certification comme Let's Encrypt, les fichiers sont souvent des liens symboliques, soyez donc prudent avec les changements de propriétaire.
Enfin, vérifiez la validité et les détails du certificat avec OpenSSL :
sudo openssl x509 -in /etc/ssl/certs/example.com.crt -noout -dates -subject -issuer
Sortie :
notBefore=Jul 1 00:00:00 2024 GMT
notAfter=Sep 29 23:59:59 2024 GMT
subject=CN = example.com
issuer=C = US, O = Let's Encrypt, CN = R3
Cela vous indique que le certificat est actuellement valide et émis par Let's Encrypt. Conservez cet inventaire dans votre documentation.
Chemin de configuration sûr
L'objectif est de minimiser l'exposition des clés privées tout en gardant votre serveur web fonctionnel. Nous ajusterons les permissions des fichiers, la propriété et la configuration Nginx étape par étape. Sauvegardez toujours avant de modifier quoi que ce soit.
Étape 1 : Sauvegarder la configuration et les certificats actuels
Créez une sauvegarde horodatée de votre répertoire de certificats et de la configuration Nginx :
sudo tar -czf /var/backups/tls-backup-$(date +%Y%m%d).tar.gz /etc/ssl /etc/nginx
Vérifiez que la sauvegarde existe :
ls -lh /var/backups/tls-backup-*.tar.gz
Sortie attendue :
-rw-r--r-- 1 root root 2.3M Aug 20 14:35 /var/backups/tls-backup-20240820.tar.gz
Cette sauvegarde capture l'état actuel, vous permettant de revenir rapidement en arrière en cas de problème. Stockez-la dans un endroit sûr, séparé du serveur si possible.
Étape 2 : Définir des permissions restrictives sur les clés privées
La clé privée est le fichier le plus sensible. Elle ne doit être lisible que par l'utilisateur qui exécute le serveur web (souvent www-data ou nginx). Sur la plupart des systèmes, le processus maître Nginx s'exécute en tant que root et les processus workers en tant que www-data. Nous pouvons définir la propriété sur root:www-data et les permissions sur 640, ce qui permet à root de lire/écrire et au groupe de lire. Si votre serveur web doit lire la clé en tant qu'utilisateur non root, assurez-vous que cet utilisateur est dans le groupe.
Vérifiez l'utilisateur actuel du serveur web :
ps aux | grep nginx | grep -v grep | awk '{print $1}' | sort -u
Exemple de sortie :
root
www-data
Définissez maintenant les permissions :
sudo chown root:www-data /etc/ssl/private/example.com.key
sudo chmod 640 /etc/ssl/private/example.com.key
Vérifiez :
ls -l /etc/ssl/private/example.com.key
Sortie attendue :
-rw-r----- 1 root www-data 1704 Jul 1 00:00 /etc/ssl/private/example.com.key
Le fichier de certificat lui-même est public, donc les permissions peuvent être 644 :
sudo chmod 644 /etc/ssl/certs/example.com.crt
Remarque : Si vous utilisez Let's Encrypt, le répertoire live contient des liens symboliques. Changer les permissions sur la cible du lien symbolique peut être réinitialisé lors du renouvellement des certificats. Dans ce cas, envisagez d'ajuster le hook de renouvellement pour définir les permissions après le renouvellement.
Étape 3 : Durcir la configuration TLS de Nginx
Modifiez votre bloc serveur Nginx (généralement dans /etc/nginx/sites-available/). Ajoutez ou mettez à jour les directives suivantes à l'intérieur du bloc server pour HTTPS :
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
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;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# HSTS (optionnel mais recommandé)
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
}
Explication :
ssl_protocolsdésactive les anciens TLS 1.0 et 1.1, qui présentent des vulnérabilités connues.ssl_ciphersspécifie des suites de chiffrement modernes et sécurisées en donnant la priorité à ECDHE pour la confidentialité persistante (forward secrecy).ssl_session_tickets offréduit le risque de compromission de la clé des tickets de session.- HSTS indique aux navigateurs d'utiliser toujours HTTPS.
Après édition, testez la configuration :
sudo nginx -t
Sortie attendue :
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Puis rechargez Nginx :
sudo systemctl reload nginx
Étape 4 : Protéger contre l'exposition des clés dans les journaux et les sauvegardes
Assurez-vous que votre fichier de clé n'est pas inclus accidentellement dans le contrôle de version ou des sauvegardes lisibles par tous. Ajoutez une règle à votre script de sauvegarde pour exclure les clés privées, ou chiffrez les sauvegardes. Vérifiez également que les permissions ne sont pas réinitialisées par des processus automatisés.
Par exemple, si vous utilisez une tâche cron pour copier des fichiers, assurez-vous qu'elle utilise cp -p pour préserver les permissions ou qu'elle les définit explicitement après la copie.
Vérification et diagnostic
Après avoir appliqué les modifications, vérifiez que votre configuration TLS fonctionne comme prévu. Utilisez à la fois des outils en ligne de commande et des vérifications externes.
Vérifier localement avec OpenSSL
Testez la poignée de main TLS et la négociation du protocole/du chiffrement :
echo | openssl s_client -connect example.com:443 -servername example.com -tls1_2 2>/dev/null | grep -E "Protocol|Cipher"
Sortie attendue (exemple) :
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Cela montre que seul TLS 1.2 a été utilisé (nous avons désactivé 1.0/1.1). Pour tester TLS 1.3 :
echo | openssl s_client -connect example.com:443 -servername example.com -tls1_3 2>/dev/null | grep -E "Protocol|Cipher"
Sortie attendue :
Protocol : TLSv1.3
Cipher : TLS_AES_128_GCM_SHA256
Vérifier la chaîne de certificats
Vérifiez que la chaîne complète est servie correctement :
openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null | grep -E "s:|i:"
La sortie doit inclure votre certificat de serveur et l'autorité de certification intermédiaire. Si la chaîne est incomplète, certains clients peuvent échouer à valider.
Utiliser des testeurs en ligne (attention : service externe)
Vous pouvez utiliser des outils comme SSL Labs (https://www.ssllabs.com/ssltest/) pour un rapport complet. C'est un service externe, ne l'utilisez donc pas pour les systèmes internes uniquement. Le rapport note votre configuration de A à F et met en évidence les faiblesses.
Vérifier les permissions des fichiers après rechargement
Assurez-vous que les permissions restent correctes après tout redémarrage du service :
ls -l /etc/ssl/private/example.com.key
Attendu : -rw-r----- 1 root www-data ...
Tester l'en-tête HSTS
Utilisez curl pour voir les en-têtes de réponse :
curl -I https://example.com 2>/dev/null | grep -i strict
Sortie attendue :
Strict-Transport-Security: max-age=63072000; includeSubDomains
Pièges courants et comment les éviter
Même les administrateurs expérimentés commettent des erreurs avec les certificats TLS. Voici les pièges les plus fréquents, pourquoi ils surviennent et comment les prévenir ou s'en remettre.
1. Fichiers de clé privée trop permissifs
Pourquoi cela arrive : Les permissions de fichier par défaut des outils de génération de certificats ou des copies manuelles peuvent être trop ouvertes (par exemple, 644), permettant à tout utilisateur local de lire la clé privée.
Comment éviter : Définissez toujours les permissions de la clé privée sur 640 avec le groupe www-data (ou le groupe du serveur web) immédiatement après l'installation. Utilisez umask 077 lors de la génération des clés pour garantir des valeurs par défaut restrictives.
Reprise : Si une clé a été exposée, révoquez le certificat, générez une nouvelle paire de clés et réémettez. Ensuite, restreignez les permissions.
2. Utilisation de contenu mixte ou de protocoles non sécurisés
Pourquoi cela arrive : Les applications héritées ou les équilibreurs de charge mal configurés peuvent encore négocier TLS 1.0 ou des chiffrements faibles, rendant le serveur vulnérable aux attaques par rétrogradation.
Comment éviter : Appliquez TLS 1.2 et 1.3 uniquement dans tous les blocs serveur. Testez avec openssl s_client pour chaque protocole et chiffrement.
Reprise : Mettez à jour la configuration Nginx pour désactiver les anciens protocoles, puis redémarrez. Utilisez SSL Labs pour confirmer la note.
3. Ne pas renouveler les certificats avant expiration
Pourquoi cela arrive : La gestion manuelle des certificats sans surveillance conduit à des certificats expirés, provoquant des avertissements de navigateur et des interruptions de service.
Comment éviter : Automatisez le renouvellement. Pour Let's Encrypt, certbot renew dans une tâche cron avec --deploy-hook pour recharger Nginx. Mettez en place des alertes de surveillance pour l'expiration.
Reprise : Renouvelez et rechargez immédiatement. Si le certificat est déjà expiré, les clients refuseront la connexion jusqu'à correction.
4. Chaîne de certificats incomplète
Pourquoi cela arrive : Configurer uniquement le certificat feuille sans l'autorité de certification intermédiaire entraîne des échecs de validation pour certains clients.
Comment éviter : Utilisez toujours le fichier de chaîne complet fourni par votre autorité de certification (par exemple, fullchain.pem). Vérifiez avec openssl s_client -showcerts.
Reprise : Remplacez le fichier de certificat par la chaîne complète et rechargez Nginx.
5. Mauvaise configuration HSTS cassant les sous-domaines
Pourquoi cela arrive : Activer HSTS avec includeSubDomains alors qu'un sous-domaine ne prend pas en charge HTTPS bloque l'accès à ce sous-domaine.
Comment éviter : Avant d'activer includeSubDomains, assurez-vous que tous les sous-domaines ont des certificats valides et que HTTPS fonctionne. Commencez avec un max-age court et augmentez progressivement.
Reprise : Supprimez includeSubDomains ou corrigez le HTTPS du sous-domaine, mais notez que les navigateurs peuvent mettre en cache la politique HSTS pour la durée spécifiée, donc la reprise peut être retardée.
6. Fichier de clé accidentellement validé dans le contrôle de version
Pourquoi cela arrive : Les développeurs peuvent ajouter le fichier de clé à un dépôt s'il se trouve dans le répertoire du projet.
Comment éviter : Stockez les clés en dehors de la racine web et des répertoires de contrôle de version. Utilisez .gitignore pour exclure .key et .pem. Implémentez des hooks de pré-commit pour rechercher les secrets.
Reprise : Faites pivoter la clé immédiatement, mettez à jour la configuration du serveur et purgez le fichier de l'historique du dépôt.
Modes de défaillance et reprise
Même avec une planification minutieuse, les choses peuvent mal tourner. Voici des scénarios de défaillance courants et comment s'en remettre.
Défaillance : Nginx ne démarre pas ou ne recharge pas après des modifications de configuration
Si vous avez fait une erreur dans le fichier de configuration, Nginx refusera de recharger. Symptômes : nginx -t échoue, ou le service ne démarre pas. Exécutez toujours nginx -t avant de recharger. Si vous avez déjà essayé de recharger et que cela a échoué, l'ancienne configuration est toujours active. Corrigez l'erreur de syntaxe et rechargez à nouveau. Si vous devez revenir en arrière, restaurez la sauvegarde :
sudo cp /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-available/example.com.conf.bak
sudo cp /etc/nginx/sites-available/example.com.conf.orig /etc/nginx/sites-available/example.com.conf
sudo nginx -t && sudo systemctl reload nginx
Défaillance : Permissions de clé privée trop restrictives
Si vous avez défini les permissions de la clé trop strictement (par exemple, 600 appartenant à root), les processus workers Nginx peuvent ne pas pouvoir lire la clé. Vérifiez les journaux d'erreurs Nginx :
sudo tail -f /var/log/nginx/error.log
Vous pourriez voir : cannot load certificate key ... Permission denied. Pour corriger, ajustez la propriété de groupe au groupe du serveur web et définissez 640 comme décrit précédemment.
Défaillance : Le certificat expire de manière inattendue
Surveillez l'expiration du certificat à l'aide d'une tâche cron ou d'un outil de surveillance. S'il expire, les clients verront des avertissements. Pour récupérer, renouvelez le certificat immédiatement et rechargez Nginx. Pour Let's Encrypt, exécutez :
sudo certbot renew --nginx
Défaillance : Chaîne de certificats incomplète
Si vous n'avez configuré que le certificat feuille sans intermédiaires, certains clients peuvent échouer. Vérifiez avec openssl s_client ou un testeur en ligne. Pour corriger, obtenez la chaîne complète (généralement un fullchain.pem de votre autorité de certification) et configurez ssl_certificate pour pointer vers elle.
Défaillance : HSTS causant des problèmes avec les sous-domaines
Si vous avez défini HSTS avec includeSubDomains et qu'un sous-domaine ne prend pas en charge HTTPS, les utilisateurs ne pourront pas y accéder. Supprimez includeSubDomains ou assurez-vous que tous les sous-domaines ont des certificats valides.
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour les revues régulières et après tout changement. Attribuez un responsable unique pour chaque élément—par exemple, l'administrateur système ou l'ingénieur DevOps—et révisez la liste mensuellement ou après tout changement de certificat ou de configuration.
| Élément | Commande | Résultat attendu | Responsable | Fréquence de revue |
|---|---|---|---|---|
| Vérifier l'expiration du certificat | sudo openssl x509 -in /etc/ssl/certs/example.com.crt -noout -enddate | Date dans le futur | Administrateur système (Jane Doe) | Mensuelle |
| Vérifier les permissions de la clé privée | ls -l /etc/ssl/private/example.com.key | -rw-r----- root www-data | Administrateur système (Jane Doe) | Mensuelle |
| Tester la configuration Nginx | sudo nginx -t | Syntaxe OK, test réussi | Ingénieur DevOps (John Smith) | Après changements |
| Vérifier les versions du protocole TLS | openssl s_client -connect example.com:443 -tls1_1 | Échec de connexion (TLS 1.1 désactivé) | Ingénieur sécurité (Alice Lee) | Trimestrielle |
| Vérifier le support TLS 1.3 | openssl s_client -connect example.com:443 -tls1_3 | Protocole : TLSv1.3 | Ingénieur sécurité (Alice Lee) | Trimestrielle |
| Vérifier l'en-tête HSTS | curl -I https://example.com | Strict-Transport-Security présent | Ingénieur DevOps (John Smith) | Après changements |
| Vérifier l'intégrité de la sauvegarde | tar -tzf /var/backups/tls-backup-latest.tar.gz | Fichiers listés sans erreur | Administrateur système (Jane Doe) | Mensuelle |
Chaque responsable est chargé d'exécuter la vérification, de documenter les résultats et de remédier à tout problème constaté. La colonne de fréquence de revue indique à quelle fréquence chaque vérification doit être effectuée.
Conclusion
Le durcissement des certificats TLS ne se limite pas à leur installation. En inventoriant votre environnement, en définissant des permissions restrictives sur les clés privées, en configurant Nginx avec des paramètres TLS modernes et en vérifiant avec des commandes concrètes, vous réduisez le risque de compromission des clés et de vulnérabilités protocolaires.
Vous disposez maintenant d'un processus reproductible :
- Inventorier les versions et les emplacements des fichiers.
- Sauvegarder avant les modifications.
- Appliquer des permissions de moindre privilège.
- Durcir les directives TLS de Nginx.
- Vérifier localement et avec des outils externes.
- Savoir comment récupérer après des échecs courants.
- Utiliser la liste de contrôle des opérations pour une sécurité continue.
Adoptez ces pratiques dans le cadre de votre configuration de serveur standard. Pour les systèmes de production, intégrez ces vérifications dans vos plans de surveillance et de réponse aux incidents. Avec une attention particulière, vos certificats TLS resteront un point d'ancrage de confiance solide pour vos utilisateurs.