175 lines
5.4 KiB
Markdown
175 lines
5.4 KiB
Markdown
# 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)
|
|
```
|