- 6 docs racine (README, HANDOVER, ARCHITECTURE, DECISIONS, INSTALL, OPERATIONS) - 9 docs thématiques dans docs/ - 10 templates docker-compose dans configs/ - 7 scripts Python/Shell d'import Furious vers Zitadel - 2 matrices RBAC Etat infra au 5 juin 2026 : - 88 users Furious importes dans Zitadel - 8 roles RBAC crees et attribues - Intranet filtre les cartes selon role (Approche A) - 7 outils SSO operationnels
487 lines
11 KiB
Markdown
487 lines
11 KiB
Markdown
# 09 — Troubleshooting
|
|
|
|
> Problèmes fréquents rencontrés et leurs solutions.
|
|
|
|
---
|
|
|
|
## 🔍 Démarrage de tout diagnostic
|
|
|
|
Avant d'essayer n'importe quoi, vérifier :
|
|
|
|
```bash
|
|
# 1. Conteneurs en route
|
|
sudo docker ps
|
|
|
|
# 2. Espace disque
|
|
df -h /
|
|
|
|
# 3. Mémoire libre
|
|
free -h
|
|
|
|
# 4. Charge système
|
|
uptime
|
|
|
|
# 5. Logs Traefik récents (souvent la source des problèmes)
|
|
sudo docker logs --tail 50 traefik
|
|
```
|
|
|
|
---
|
|
|
|
## 🔴 Problèmes critiques
|
|
|
|
### "Tout est down, je ne peux plus accéder à rien"
|
|
|
|
#### Diagnostic
|
|
|
|
```bash
|
|
# SSH au serveur
|
|
ssh hedi@<server>
|
|
|
|
# Vérifier Docker
|
|
sudo systemctl status docker
|
|
sudo docker ps | wc -l
|
|
# Doit afficher > 20 (24 conteneurs attendus)
|
|
|
|
# Vérifier ports 80/443
|
|
sudo netstat -tlnp | grep -E "80|443"
|
|
|
|
# Vérifier les certificats Let's Encrypt
|
|
sudo ls -la ~/docker/traefik/letsencrypt/
|
|
```
|
|
|
|
#### Causes possibles
|
|
|
|
**Cause 1 — Docker daemon down** :
|
|
```bash
|
|
sudo systemctl restart docker
|
|
sudo docker compose -f ~/docker/traefik/docker-compose.yml up -d
|
|
# Démarrer dans l'ordre : Traefik, puis Zitadel, puis les autres
|
|
```
|
|
|
|
**Cause 2 — Disque plein** :
|
|
```bash
|
|
# Nettoyer Docker
|
|
sudo docker system prune -a --volumes
|
|
# Nettoyer logs si > 1 Go
|
|
sudo du -sh /var/lib/docker/containers/*/
|
|
sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log
|
|
```
|
|
|
|
**Cause 3 — IP du serveur a changé** :
|
|
- Vérifier DNS : `dig +short sso.seizeconsulting.com`
|
|
- Si IP différente → mettre à jour DNS chez le registrar
|
|
|
|
---
|
|
|
|
### "Le SSO ne fonctionne plus depuis 5 minutes"
|
|
|
|
Symptôme : tous les outils SSO renvoient une boucle de redirection ou un "Bad Gateway".
|
|
|
|
#### Diagnostic — Vérifier dans cet ordre
|
|
|
|
**1. Zitadel répond ?**
|
|
```bash
|
|
curl -sI https://sso.seizeconsulting.com
|
|
# Doit retourner 200 ou 302
|
|
```
|
|
|
|
Si non : `docker logs zitadel-zitadel-api-1 --tail 50`
|
|
|
|
**2. Traefik ForwardAuth marche ?**
|
|
```bash
|
|
grep -A 8 "authRequestHeaders" ~/docker/traefik/dynamic.yml
|
|
# La ligne "- Cookie" doit être présente
|
|
```
|
|
|
|
**3. OAuth2-Proxy de l'outil tourne ?**
|
|
```bash
|
|
sudo docker ps | grep oauth2-proxy
|
|
# Tous doivent être Up
|
|
```
|
|
|
|
**4. Logs OAuth2-Proxy ?**
|
|
```bash
|
|
sudo docker logs --tail 50 oauth2-proxy
|
|
sudo docker logs --tail 50 oauth2-proxy-n8n
|
|
# Chercher : "error", "unauthorized", "context deadline exceeded"
|
|
```
|
|
|
|
#### Solutions courantes
|
|
|
|
**Solution 1** : Restart de Traefik
|
|
```bash
|
|
cd ~/docker/traefik
|
|
docker compose down
|
|
docker compose up -d
|
|
```
|
|
|
|
**Solution 2** : Restart d'OAuth2-Proxy de l'outil concerné
|
|
```bash
|
|
cd ~/docker/oauth2-proxy-<outil>
|
|
docker compose down
|
|
docker compose up -d
|
|
```
|
|
|
|
**Solution 3** : Vérifier que les certificats TLS sont OK
|
|
```bash
|
|
echo | openssl s_client -connect sso.seizeconsulting.com:443 2>/dev/null | openssl x509 -noout -dates
|
|
# notAfter doit être dans > 7 jours
|
|
```
|
|
|
|
---
|
|
|
|
### "Le bug Traefik Cookie est revenu (boucle de redirect)"
|
|
|
|
C'est **le** bug historique. Cf. [DECISIONS.md D3](../DECISIONS.md).
|
|
|
|
#### Fix immédiat
|
|
|
|
Vérifier que `~/docker/traefik/dynamic.yml` contient :
|
|
|
|
```yaml
|
|
http:
|
|
middlewares:
|
|
oauth2-headers:
|
|
forwardAuth:
|
|
address: "http://oauth2-proxy:4180/oauth2/auth"
|
|
authRequestHeaders:
|
|
- Cookie # ← CRITIQUE
|
|
- Authorization
|
|
authResponseHeaders:
|
|
- X-Auth-Request-User
|
|
- X-Auth-Request-Email
|
|
```
|
|
|
|
Si la ligne `- Cookie` manque → l'ajouter, puis :
|
|
```bash
|
|
cd ~/docker/traefik
|
|
docker compose restart
|
|
```
|
|
|
|
---
|
|
|
|
## 🟡 Problèmes courants
|
|
|
|
### "Le certificat Let's Encrypt va expirer / a expiré"
|
|
|
|
Traefik renouvelle automatiquement. Si pas le cas :
|
|
|
|
```bash
|
|
# Vérifier les logs Let's Encrypt
|
|
sudo docker logs traefik 2>&1 | grep -i "letsencrypt\|acme" | tail -20
|
|
|
|
# Causes possibles :
|
|
# 1. Rate limit Let's Encrypt (trop de tentatives) → attendre 1h
|
|
# 2. DNS pas correct → vérifier dig
|
|
# 3. Port 80 bloqué → vérifier firewall
|
|
|
|
# Forcer le renouvellement
|
|
cd ~/docker/traefik
|
|
docker compose down
|
|
docker compose up -d
|
|
```
|
|
|
|
⚠️ Cas critique : `acme.json` corrompu :
|
|
```bash
|
|
sudo cp letsencrypt/acme.json letsencrypt/acme.json.backup
|
|
sudo rm letsencrypt/acme.json
|
|
sudo touch letsencrypt/acme.json
|
|
sudo chmod 600 letsencrypt/acme.json
|
|
docker compose restart
|
|
```
|
|
|
|
→ Recrée tous les certificats (peut prendre 5 min).
|
|
|
|
---
|
|
|
|
### "Un user ne peut pas se logger"
|
|
|
|
#### Vérifier dans cet ordre
|
|
|
|
**1. Le compte existe-t-il dans Zitadel ?**
|
|
- Console Zitadel → Users → Search par email
|
|
- Status doit être "Active" (pas "Inactive" ou "Deleted")
|
|
|
|
**2. L'email est-il vérifié ?**
|
|
- Console → User → General → Email verified ?
|
|
- Si non : Actions → Resend verification (mais SMTP doit être configuré)
|
|
- Ou : Set as verified manually
|
|
|
|
**3. Le MFA est-il bloqué ?**
|
|
- Si l'user a perdu son téléphone : Reset MFA
|
|
- Console → User → Multi-factor authentication → Remove
|
|
|
|
**4. Lockout actif ?**
|
|
- Console → User → Activity → vérifier les failed attempts
|
|
- Reset : Actions → Unlock
|
|
|
|
**5. L'user a-t-il un rôle ?**
|
|
- Si "Only authorized users" est coché sur le project, il faut un rôle
|
|
- Console → User → Authorizations → Add role
|
|
|
|
---
|
|
|
|
### "Le script Python d'import échoue"
|
|
|
|
#### Erreur 401 / 403
|
|
|
|
```bash
|
|
cd ~/furious-to-zitadel
|
|
source venv/bin/activate
|
|
|
|
# Vérifier la clé JSON
|
|
python3 -c "
|
|
import json
|
|
data = json.load(open('zitadelfuriousimportkey.json'))
|
|
print('UserId:', data.get('userId'))
|
|
print('KeyId:', data.get('keyId'))
|
|
"
|
|
# Si erreur → la clé est corrompue, en régénérer une
|
|
|
|
# Vérifier les permissions du service account
|
|
# Console Zitadel → Users → furious-import-service → IAM Members
|
|
# Doit avoir IAM_USER_MANAGER
|
|
```
|
|
|
|
#### Erreur 400 sur certains users
|
|
|
|
```bash
|
|
# Voir les détails dans le log
|
|
tail -100 import.log | grep -B 2 "ERROR"
|
|
|
|
# Causes courantes :
|
|
# - Email invalide dans Furious (espaces, caractères spéciaux)
|
|
# - Mdp trop court / ne respecte pas la policy
|
|
# - Username déjà existant
|
|
```
|
|
|
|
#### Erreur de connexion Furious
|
|
|
|
```bash
|
|
./test-auth.sh
|
|
# Doit retourner un JSON valide
|
|
# Si 401 → identifiants Furious à régénérer
|
|
# Si timeout → API Furious peut être down, vérifier status
|
|
```
|
|
|
|
---
|
|
|
|
### "L'intranet ne montre pas les bonnes cartes"
|
|
|
|
Voir [07-rbac-intranet.md](./07-rbac-intranet.md) section Troubleshooting.
|
|
|
|
Rapide :
|
|
1. Console JS (F12) → vérifier le log `[RBAC] User: ... | Rôle: ...`
|
|
2. Si rôle null → `roles-mapping.json` à régénérer
|
|
3. Si email = `__USER_EMAIL__` → nginx sub_filter pas appliqué
|
|
|
|
---
|
|
|
|
### "Le conteneur xxx redémarre en boucle"
|
|
|
|
```bash
|
|
# Voir les logs
|
|
sudo docker logs <container> --tail 50
|
|
|
|
# Voir le statut détaillé
|
|
sudo docker inspect <container> --format '{{.State.Health}}'
|
|
|
|
# Causes courantes :
|
|
# 1. Healthcheck failed → vérifier la commande de healthcheck
|
|
# 2. Erreur de config (mauvais env) → vérifier .env
|
|
# 3. Volume manquant ou permissions → vérifier les paths
|
|
# 4. Port déjà utilisé → docker compose down + up
|
|
|
|
# Voir les events Docker récents
|
|
sudo docker events --since 10m
|
|
```
|
|
|
|
---
|
|
|
|
### "Espace disque saturé"
|
|
|
|
```bash
|
|
# Voir où va l'espace
|
|
sudo du -sh /var/lib/docker/* | sort -h
|
|
sudo du -sh /home/*
|
|
|
|
# Nettoyer Docker
|
|
sudo docker system prune -a --volumes
|
|
# ⚠️ Supprime tout ce qui n'est pas utilisé activement
|
|
|
|
# Nettoyer les logs Docker
|
|
sudo find /var/lib/docker/containers -name "*-json.log" -exec truncate -s 0 {} \;
|
|
|
|
# Configurer la rotation des logs (à mettre dans /etc/docker/daemon.json) :
|
|
{
|
|
"log-driver": "json-file",
|
|
"log-opts": {
|
|
"max-size": "100m",
|
|
"max-file": "3"
|
|
}
|
|
}
|
|
# Restart Docker après modif
|
|
sudo systemctl restart docker
|
|
```
|
|
|
|
---
|
|
|
|
## 🟢 Problèmes mineurs
|
|
|
|
### "L'image d'un conteneur est obsolète"
|
|
|
|
```bash
|
|
cd ~/docker/<service>
|
|
docker compose pull
|
|
docker compose up -d
|
|
```
|
|
|
|
### "Comment voir les logs en temps réel ?"
|
|
|
|
```bash
|
|
docker compose logs -f
|
|
# Ctrl+C pour quitter
|
|
```
|
|
|
|
### "Comment redémarrer juste un service sans toucher les autres ?"
|
|
|
|
```bash
|
|
sudo docker restart <container_name>
|
|
# Plus rapide qu'un docker compose
|
|
```
|
|
|
|
### "Comment exécuter une commande dans un conteneur ?"
|
|
|
|
```bash
|
|
sudo docker exec -it <container> sh
|
|
# ou bash si dispo
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 Débogage avancé
|
|
|
|
### Nginx Diagnostic (debug RBAC)
|
|
|
|
⚠️ **Procédure temporaire** — supprimer immédiatement après usage.
|
|
|
|
Pour voir ce que les headers HTTP contiennent réellement :
|
|
|
|
```bash
|
|
# Créer une config nginx diagnostic
|
|
cat > ~/docker/intranet/nginx-diagnostic.conf << 'EOF'
|
|
events {}
|
|
http {
|
|
server {
|
|
listen 80;
|
|
location /debug {
|
|
add_header Content-Type text/plain;
|
|
return 200 "=== Headers reçus ===
|
|
X-Forwarded-User: $http_x_forwarded_user
|
|
X-Forwarded-Email: $http_x_forwarded_email
|
|
X-Forwarded-Preferred-Username: $http_x_forwarded_preferred_username
|
|
X-Forwarded-Groups: $http_x_forwarded_groups
|
|
Authorization: $http_authorization
|
|
";
|
|
}
|
|
location / { try_files $uri /index.html =404; }
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# Modifier docker-compose pour utiliser cette config
|
|
nano ~/docker/intranet/docker-compose.yml
|
|
# Ajouter le volume : ./nginx-diagnostic.conf:/etc/nginx/nginx.conf:ro
|
|
|
|
# Restart
|
|
docker compose up -d
|
|
|
|
# Accéder à : https://intranet.seizeconsulting.com/debug
|
|
# (en étant logué)
|
|
|
|
# ⚠️ AVANT DE FERMER : restaurer la config normale !
|
|
rm ~/docker/intranet/nginx-diagnostic.conf
|
|
# Remettre nginx-rbac.conf dans docker-compose.yml
|
|
```
|
|
|
|
### Décoder un token JWT
|
|
|
|
Si tu as un token et veux voir son contenu (claims, exp, etc.) :
|
|
|
|
```bash
|
|
# Méthode 1 : jwt.io (en ligne, ATTENTION ne pas coller de vrais tokens)
|
|
# Méthode 2 : ligne de commande
|
|
|
|
TOKEN="<ton_jwt>"
|
|
echo $TOKEN | cut -d "." -f2 | base64 -d 2>/dev/null | python3 -m json.tool
|
|
```
|
|
|
|
### Vérifier la communication réseau entre 2 conteneurs
|
|
|
|
```bash
|
|
sudo docker exec -it traefik wget -qO- http://intranet:80
|
|
sudo docker exec -it oauth2-proxy wget -qO- http://intranet:80
|
|
```
|
|
|
|
Si erreur → vérifier que les conteneurs partagent un réseau Docker commun.
|
|
|
|
### Voir les connexions actives
|
|
|
|
```bash
|
|
sudo ss -tunlp | grep -E "80|443"
|
|
|
|
# Connexions en cours
|
|
sudo netstat -anp | grep ESTABLISHED | grep ":443" | wc -l
|
|
```
|
|
|
|
---
|
|
|
|
## 📋 Checklist quand quelque chose ne va pas
|
|
|
|
- [ ] Tous les conteneurs `Up` ? → `sudo docker ps`
|
|
- [ ] DNS OK ? → `dig +short <domain>`
|
|
- [ ] HTTPS valide ? → `curl -sI https://<domain>`
|
|
- [ ] Logs Traefik sans erreur ? → `docker logs --tail 50 traefik | grep -i error`
|
|
- [ ] Logs OAuth2-Proxy sans erreur ? → `docker logs --tail 50 oauth2-proxy*`
|
|
- [ ] Espace disque OK ? → `df -h /`
|
|
- [ ] Mémoire OK ? → `free -h`
|
|
- [ ] Authentification Zitadel OK depuis incognito ?
|
|
- [ ] Vérifier que rien n'a été modifié récemment (fichier .yml ou .env)
|
|
|
|
---
|
|
|
|
## 📞 Quand escalader
|
|
|
|
### Vers Philippe (sponsor)
|
|
|
|
- Service critique down > 30 min
|
|
- Demande de modification d'architecture
|
|
- Validation d'une décision business
|
|
|
|
### Vers le support Scaleway
|
|
|
|
- Serveur inaccessible (panne réseau ou hardware)
|
|
- Quota dépassé sur le compte
|
|
- Problème de facturation
|
|
|
|
### Vers le support Furious
|
|
|
|
- API Furious down ou très lente
|
|
- Permissions API qui ne fonctionnent pas malgré une bonne config
|
|
- Problèmes de données RH (départs mal renseignés, etc.)
|
|
|
|
### Vers la communauté Zitadel
|
|
|
|
- Discord Zitadel : https://discord.gg/zitadel
|
|
- Issues GitHub : https://github.com/zitadel/zitadel
|
|
- Forum : https://community.zitadel.com/
|
|
|
|
---
|
|
|
|
## 📚 Liens vers les docs internes
|
|
|
|
- [INSTALL.md](../INSTALL.md) — Procédure d'install from scratch
|
|
- [OPERATIONS.md](../OPERATIONS.md) — Maintenance et opérations courantes
|
|
- [HANDOVER.md](../HANDOVER.md) — Actions urgentes à mener
|
|
- [DECISIONS.md](../DECISIONS.md) — Anti-patterns à éviter
|