Introduction
Les mises à niveau et migrations de certificats TLS peuvent provoquer des interruptions évitables lorsqu'elles sont réalisées à l'improviste. Un SAN oublié, un client incapable de négocier ECDSA, ou une modification de chaîne appliquée en pleine charge figurent parmi les pannes fréquentes.
Ce guide propose un chemin concret et peu risqué : planifier le changement, le prouver en local, déployer via un canari, valider le comportement, et garder un rollback à une commande. Vous verrez des exemples fonctionnels pour Nginx et Kubernetes Ingress sous Linux afin de vous entraîner avant la production. Les notions clés (TLS certificates upgrade, TLS certificates migration, TLS certificates validation et TLS certificates rollback) sont mises en pratique tout au long du guide.
Aperçu du workflow
Utilisez cette checklist pour réduire le risque et garder la progression visible.
- Inventorier la terminaison TLS
- Reverse proxies : Nginx, Envoy, HAProxy
- Kubernetes : Ingress controllers et gateways
- Load balancers managés et tout listener TLS direct
- Cartographier où résident certificats/clefs et comment s'opèrent les recharges
- Définir le périmètre de la mise à niveau
- Algorithme de clé : RSA 2048 -> RSA 3072, ou passage à ECDSA P‑256
- Signature et chaîne : nouvel intermédiaire ou racine, format du chain file
- Modifications de SAN et de noms d'hôtes : ajout/retrait, wildcard vs SAN spécifiques
- Durée de vie du certificat et flux de renouvellement
- Rétrocompatibilité : envisager des certificats doubles (ECDSA + RSA) pour couvrir les anciens clients
- Préparer les artefacts
- Générer clés et CSR sur un hôte durci (security hardening)
- Planifier le stockage : permissions de fichiers, audit, sauvegardes des clés privées
- Pour une pile double, produire les artefacts RSA et ECDSA
- Mettre en scène en sécurité
- Charger les nouveaux certificats sur un proxy non‑prod ou un hôte canari
- Confirmer les protocoles pris en charge (TLS 1.2 et 1.3) et désactiver les plus anciens
- Vérifier la chaîne complète et le comportement d'OCSP stapling si activé
- Plan de déploiement
- Privilégier les bascules atomiques : symlinks pour les fichiers, secrets versionnés sous Kubernetes
- Utiliser un hostname ou un chemin canari pour exercer le nouveau certificat avec du trafic réel
- Recharger en douceur uniquement après validation réussie
- Valider à fond
- Nom d'hôte, SAN, algorithme de signature, ordre de chaîne
- Négociation de protocole : TLS 1.2 et 1.3
- Négociation de chiffrements pour ECDSA et RSA si applicable
- Comportement applicatif et taux d'erreurs
- Observer
- Surveiller les logs des proxys et controllers pour les erreurs de handshake/certificat
- Suivre les taux 4xx/5xx et les retours clients pendant la fenêtre
- Être prêt au rollback
- Conserver l'ancien certificat et sa clé installés mais inactifs
- Revenir en arrière en rebasculant un symlink ou en changeant la référence de secret Kubernetes
- Recharger le proxy et re‑valider
- Nettoyer et documenter
- Retirer l'ancien matériel après une fenêtre de sécurité
- Capturer commandes, chemins et vérifications dans un runbook
Plan pilote local
Démarrez avec un unique hostname ou une route facile à exercer. Prouvez avant la production :
- Vous pouvez installer le nouveau certificat aux côtés de l'ancien
- Vous savez valider la chaîne, les protocoles et les suites de chiffrement en local
- Vous pouvez basculer et faire un rollback en moins d'une minute
Générer clés et CSR (Linux, OpenSSL)
ECDSA P‑256 :
openssl ecparam -name prime256v1 -genkey -noout -out server-ecdsa.key
openssl req -new -key server-ecdsa.key -out server-ecdsa.csr \
-subj '/CN=example.com' \
-addext 'subjectAltName=DNS:example.com, DNS:www.example.com'
RSA 3072 :
openssl genrsa -out server-rsa.key 3072
openssl req -new -key server-rsa.key -out server-rsa.csr \
-subj '/CN=example.com' \
-addext 'subjectAltName=DNS:example.com, DNS:www.example.com'
Quand ils sont émis, vous devez disposer des clés privées et des fichiers de chaîne complète, par exemple :
- server-ecdsa.key et example-ecdsa-fullchain.pem
- server-rsa.key et example-rsa-fullchain.pem
Appliquez des permissions strictes aux clés privées :
sudo chown root: root server-*.key
sudo chmod 600 server-*.key
Nginx reverse proxy : canari à double certificat
- Placez certificats et clés dans un chemin versionné et faites pointer des symlinks stables vers la version active :
sudo install -d -m 0750 /etc/nginx/certs/releases/2024-07-20
sudo cp example-ecdsa-fullchain.pem /etc/nginx/certs/releases/2024-07-20/
sudo cp server-ecdsa.key /etc/nginx/certs/releases/2024-07-20/
sudo cp example-rsa-fullchain.pem /etc/nginx/certs/releases/2024-07-20/
sudo cp server-rsa.key /etc/nginx/certs/releases/2024-07-20/
sudo ln -sfn /etc/nginx/certs/releases/2024-07-20/example-ecdsa-fullchain.pem /etc/nginx/certs/example-ecdsa-fullchain.pem
sudo ln -sfn /etc/nginx/certs/releases/2024-07-20/server-ecdsa.key /etc/nginx/certs/example-ecdsa.key
sudo ln -sfn /etc/nginx/certs/releases/2024-07-20/example-rsa-fullchain.pem /etc/nginx/certs/example-rsa-fullchain.pem
sudo ln -sfn /etc/nginx/certs/releases/2024-07-20/server-rsa.key /etc/nginx/certs/example-rsa.key
- Configurez Nginx pour proposer ECDSA et RSA, et restreindre les protocoles :
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers off;
ssl_ecdh_curve X25519: secp256r1;
# Certificat ECDSA
ssl_certificate /etc/nginx/certs/example-ecdsa-fullchain.pem;
ssl_certificate_key /etc/nginx/certs/example-ecdsa.key;
# Certificat RSA
ssl_certificate /etc/nginx/certs/example-rsa-fullchain.pem;
ssl_certificate_key /etc/nginx/certs/example-rsa.key;
location / {
proxy_pass http://app:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto https;
}
}
- Tester et recharger :
sudo nginx -t && sudo systemctl reload nginx
- Valider la négociation et la chaîne en local :
# Vérifier TLS 1.3
openssl s_client -connect example.com:443 -servername example.com -tls1_3 -brief </dev/null
# Forcer une suite ECDSA pour confirmer le chemin ECDSA
openssl s_client -connect example.com:443 -servername example.com \
-cipher ECDHE-ECDSA-AES128-GCM-SHA256 </dev/null
# Forcer une suite RSA pour confirmer le fallback RSA
openssl s_client -connect example.com:443 -servername example.com \
-cipher ECDHE-RSA-AES128-GCM-SHA256 </dev/null
# Curl avec association hôte->IP pour les prévisualisations
curl -v --resolve example.com:443:203.0.113.10 https://example.com/
- Plan de rollback pour Nginx :
- Conservez les anciens certificats sous un chemin de release antérieur
- Repositionnez les symlinks et rechargez si nécessaire
sudo ln -sfn /etc/nginx/certs/releases/2024-06-01/example-ecdsa-fullchain.pem /etc/nginx/certs/example-ecdsa-fullchain.pem
sudo ln -sfn /etc/nginx/certs/releases/2024-06-01/server-ecdsa.key /etc/nginx/certs/example-ecdsa.key
sudo ln -sfn /etc/nginx/certs/releases/2024-06-01/example-rsa-fullchain.pem /etc/nginx/certs/example-rsa-fullchain.pem
sudo ln -sfn /etc/nginx/certs/releases/2024-06-01/server-rsa.key /etc/nginx/certs/example-rsa.key
sudo nginx -t && sudo systemctl reload nginx
Kubernetes Ingress : canari puis bascule
- Créez un nouveau secret pour le hostname canari :
kubectl -n web create secret tls web-tls-new \
--cert=example-fullchain.pem --key=server.key
- Créez un Ingress canari avec le nouveau secret et un hôte séparé :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-canary
namespace: web
spec:
ingressClassName: nginx
tls:
- hosts:
- canary.example.com
secretName: web-tls-new
rules:
- host: canary.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
Appliquez et testez :
kubectl apply -f web-canary.yaml
curl -v https://canary.example.com/
openssl s_client -connect canary.example.com:443 -servername canary.example.com -brief </dev/null
- Basculez l'Ingress de production vers le nouveau secret :
- Conservez l'ancien secret, par exemple
web-tls-old - Mettez à jour
spec.tls.secretNamede l'Ingress de prod versweb-tls-new
# Extrait de l'Ingress de production
spec:
tls:
- hosts:
- example.com
- www.example.com
secretName: web-tls-new
Appliquez et surveillez les logs du controller pour les mises à jour :
kubectl -n web apply -f web-ingress.yaml
kubectl -n ingress-nginx logs deploy/ingress-nginx-controller -f | grep -i tls
- Plan de rollback pour Kubernetes :
- Rétablissez
secretNameversweb-tls-oldet appliquez - Conservez les deux secrets durant la fenêtre de rollback
Checklist de validation
- Nom d'hôte et SAN alignés avec l'usage réel des clients
- Protocoles : TLS 1.2 et 1.3 activés, anciens désactivés
- Négociation des suites : chemin ECDSA disponible, fallback RSA opérationnel si nécessaire
- Chaîne complète et ordre corrects
- Absence d'erreurs de handshake ou de certificat dans les logs
- Trafic et taux d'erreur normaux après la bascule
Observabilité et notes de sécurité
- Nginx : suivez
error.logpour des erreursSSL_do_handshakependant la fenêtre - Ingress controller : surveillez les logs pour les mises à jour de secrets et problèmes de handshake
- Prévoyez une courte fenêtre de maintenance, une astreinte, et des déclencheurs de rollback explicites
Conclusion
Les mises à niveau réussies suivent un schéma reproductible : inventorier, préparer les artefacts, déployer en canari, valider de manière agressive, et garder un rollback à une seule commande. Démarrez par un pilote étroit que vous pouvez inspecter localement, prouvez la négociation et l'intégrité de la chaîne, puis étendez le modèle à davantage de services. Documentez commandes, chemins et contrôles, et programmez les renouvellements bien avant l'expiration pour que les rotations futures deviennent routinières. En procédant ainsi, votre TLS certificates upgrade ou TLS certificates migration reste maîtrisée, et votre TLS certificates validation garantit une bascule sûre, avec un TLS certificates rollback prêt en cas d'imprévu.