# Runbook — Certificat TLS Expiré ou Expirant **Alerte :** `VeylantCertExpiringSoon` (severity: warning, J-30) ou certificat déjà expiré **SLA impact :** Interruption totale (HTTPS refusé) si certificat expiré **Temps de résolution cible :** < 20 minutes (renouvellement cert-manager automatique) --- ## Symptômes - Alerte `VeylantCertExpiringSoon` : expiry < 30 jours - Erreurs navigateur : `NET::ERR_CERT_DATE_INVALID` - Erreurs curl : `SSL certificate has expired` ou `certificate verify failed` - k6 / smoke tests échouent avec des erreurs TLS - Logs Traefik : `"certificate expired"` ou `"acme: error: 403"` --- ## Diagnostic ### 1. Vérifier l'expiration du certificat en production ```bash # Expiration du certificat TLS externe echo | openssl s_client -connect api.veylant.ai:443 2>/dev/null | \ openssl x509 -noout -enddate -subject # Via kubectl (cert-manager Certificate resource) kubectl get certificate -n veylant kubectl describe certificate veylant-tls -n veylant | grep -A5 "Conditions:" ``` ### 2. Vérifier l'état cert-manager ```bash # État des CertificateRequest en cours kubectl get certificaterequest -n veylant # Logs cert-manager kubectl logs -n cert-manager deploy/cert-manager --since=30m | \ grep -E "(error|certificate|acme|renewal)" # Vérifier les ClusterIssuers kubectl get clusterissuer kubectl describe clusterissuer letsencrypt-production | grep -A10 "Status:" ``` ### 3. Diagnostiquer l'échec ACME (Let's Encrypt) ```bash # Vérifier les challenges ACME en cours (HTTP-01 ou DNS-01) kubectl get challenge -n veylant kubectl describe challenge -n veylant | grep -A10 "Reason:" # Si HTTP-01 : vérifier que le chemin /.well-known/acme-challenge/ est accessible curl -sf https://api.veylant.ai/.well-known/acme-challenge/test-token ``` --- ## Remédiation ### A — Renouvellement automatique via cert-manager (normal) Si le certificat expire dans > 7 jours, cert-manager se charge du renouvellement automatique (renewal 30 jours avant expiry). **Aucune action requise** — surveiller que le renouvellement s'effectue. ### B — Forcer le renouvellement cert-manager ```bash # Supprimer le certificat actuel pour forcer la re-création kubectl delete certificate veylant-tls -n veylant # cert-manager recrée automatiquement le certificat kubectl get certificate -n veylant -w # Observer la re-création # Attendre Ready=True (1-2 minutes pour HTTP-01, 1-5 minutes pour DNS-01) kubectl wait certificate veylant-tls -n veylant \ --for=condition=Ready --timeout=300s echo "Certificate renewed successfully" ``` ### C — Certificat déjà expiré (urgence) #### C1. Renouvellement d'urgence ```bash # Annotate le Certificate pour forcer la re-création immédiate kubectl annotate certificate veylant-tls -n veylant \ cert-manager.io/issue-temporary-certificate=true --overwrite # Si ACME rate-limited (trop de renouvellements) → basculer sur staging Let's Encrypt kubectl patch clusterissuer letsencrypt-production --type=merge -p \ '{"spec":{"acme":{"server":"https://acme-staging-v02.api.letsencrypt.org/directory"}}}' # ATTENTION: staging LE ne génère pas des certs de confiance — maintenance mode obligatoire ``` #### C2. Rollback TLS — certificat auto-signé temporaire **Uniquement si le renouvellement ACME échoue et que le service est totalement indisponible.** ```bash # Générer un certificat auto-signé valable 7 jours openssl req -x509 -nodes -days 7 \ -newkey rsa:2048 \ -keyout /tmp/tls-emergency.key \ -out /tmp/tls-emergency.crt \ -subj "/CN=api.veylant.ai" # Créer le secret TLS d'urgence kubectl create secret tls veylant-tls-emergency \ --cert=/tmp/tls-emergency.crt \ --key=/tmp/tls-emergency.key \ -n veylant # Patcher le déploiement Traefik pour utiliser ce secret temporairement # (voir documentation Traefik TLS configuration) kubectl annotate ingress veylant-ingress \ kubernetes.io/tls-acme=false \ --overwrite ``` **IMPORTANT :** Le certificat auto-signé déclenchera des warnings navigateur. Notifier immédiatement les clients. --- ## Rollback TLS Si le nouveau certificat pose des problèmes : ```bash # Restaurer l'ancien secret TLS depuis un backup # (si cert-manager gérait un secret nommé veylant-tls, une copie est dans le backup S3) aws s3 cp s3://veylant-backups-production/certs/veylant-tls-$(date +%Y%m%d).yaml - | \ kubectl apply -n veylant -f - kubectl rollout restart deployment/veylant-proxy-blue -n veylant ``` --- ## Prévention - Alerte `VeylantCertExpiringSoon` déclenchée 30 jours avant expiry (règle Prometheus) - cert-manager configuré pour renouveler 30 jours avant expiry (cert-manager default) - Rotation automatique — aucun renouvellement manuel nécessaire en fonctionnement normal - Vérification quotidienne du certificat dans le smoke test CI --- ## Post-mortem Template ```markdown ## Post-mortem — Certificat TLS [DATE] **Certificat :** [domaine] **Impact :** [durée d'indisponibilité TLS] **Cause :** [Renouvellement raté / ACME challenge échoué / Rate limit LE] ### Timeline - HH:MM — Alerte CertExpiringSoon / découverte expiration - HH:MM — Diagnostic cert-manager - HH:MM — Action : [forcer renouvellement / rollback] - HH:MM — Certificat valide rétabli ### Root Cause [Description] ### Actions correctives - [ ] Vérifier la configuration ACME challenge - [ ] Tester le renouvellement en staging mensuellement - [ ] Ajouter monitoring expiry à J-60 (alerte précoce) ```