diff --git a/docs/auth-stack.md b/docs/auth-stack.md new file mode 100644 index 0000000..89bd149 --- /dev/null +++ b/docs/auth-stack.md @@ -0,0 +1,201 @@ +# Auth Stack — LLDAP + Authelia + Redis (DSM 7.3 / Synology DS220+) + +## Objectif +Fournir une pile d’authentification robuste (anti-lockout) pour protéger des services web via reverse-proxy : +- Annuaire utilisateurs : **LLDAP** +- Portail / SSO / MFA : **Authelia** +- Cache/sessions (optionnel selon config) : **Redis** +- Exposition publique : **Reverse proxy** (Synology / Nginx / Traefik) vers Authelia + +--- + +## Architecture + +### Composants +- **LLDAP** + - UI admin (HTTP) : `127.0.0.1:17170` + - LDAP : `127.0.0.1:3890` + - Base : sqlite dans `/volume2/docker/auth/data/lldap` + +- **Authelia** + - API/portal : `127.0.0.1:9091` + - Stockage : sqlite dans `/volume2/docker/auth/data/authelia/db.sqlite3` + - Accès externe : via reverse proxy -> `https://auth.` + +- **Redis** + - Local uniquement : `127.0.0.1:6379` + - (peut servir plus tard à sessions/rate-limit selon config) + +### Exposition réseau (principe de sécurité) +- Tous les services **bindés sur 127.0.0.1** (loopback NAS) +- Seul le **reverse proxy** expose `https://auth.` vers `127.0.0.1:9091` + +--- + +## Fichiers de référence + +### 1) docker-compose.auth.yml +- Déploie redis + lldap + authelia. +- Recommandation DSM : **network_mode: host** + bind sur localhost. + - Supprime les aléas “bridge + DNS + subnets” + - Évite les timeouts LDAP sporadiques. + +### 2) /volume2/docker/auth/compose/.env +Variables attendues : + +#### LLDAP +- `LLDAP_JWT_SECRET=...` (random 32+) +- `LLDAP_KEY_SEED=...` (random 32+) +- `LLDAP_LDAP_USER_PASS=...` (mot de passe admin LLDAP) + +#### Authelia +- `AUTHELIA_JWT_SECRET=...` (utilisé ici comme source pour reset_password) +- `AUTHELIA_SESSION_SECRET=...` +- `AUTHELIA_STORAGE_ENCRYPTION_KEY=...` + +> Ne jamais committer `.env`. Stocker dans DSM / secrets. + +### 3) /volume2/docker/auth/config/authelia/configuration.yml +- LDAP address en mode robuste : `ldap://127.0.0.1:3890` +- Cookie domain : `archicratie.trans-hands.synology.me` +- `authelia_url` : `https://auth.archicratie.trans-hands.synology.me` +- `default_redirection_url` : service principal (ex: gitea) + +--- + +## Procédures opératoires + +### Restart safe (redémarrage propre) +en bash : +cd /volume2/docker/auth/compose +sudo docker compose --env-file .env -f docker-compose.auth.yml down --remove-orphans +sudo docker compose --env-file .env -f docker-compose.auth.yml up -d --force-recreate + +### Tests santé (sans dépendances DSM) +curl -fsS http://127.0.0.1:17170/ >/dev/null && echo "LLDAP UI OK" +curl -fsS http://127.0.0.1:9091/api/health && echo "AUTHELIA LOCAL OK" +curl -kfsS https://auth.archicratie.trans-hands.synology.me/api/health && echo "AUTHELIA HTTPS OK" + +### Test TCP LDAP : +sudo docker run --rm --network host nicolaka/netshoot:latest sh -lc 'nc -vz -w2 127.0.0.1 3890' + +### Rotate secrets (rotation) + +# Principes : + +Rotation = redémarrage forcé d’Authelia (sessions invalidées) + +Rotation de LLDAP_KEY_SEED est sensible : peut affecter chiffrement des mots de passe. + +# Procédure conseillée : + +Sauvegarder DBs : + +/volume2/docker/auth/data/lldap/users.db + +/volume2/docker/auth/data/authelia/db.sqlite3 + +Changer d’abord secrets Authelia (AUTHELIA_SESSION_SECRET, AUTHELIA_STORAGE_ENCRYPTION_KEY) + +docker compose up -d --force-recreate authelia + +Vérifier /api/health + login. + +Reset admin LLDAP (break-glass) + +# Si tu perds le mot de passe admin : + +Activer temporairement LLDAP_FORCE_LDAP_USER_PASS_RESET=true dans l’environnement LLDAP + +Redémarrer LLDAP une seule fois + +Désactiver immédiatement après. + +⚠️ Ne jamais laisser ce flag en permanence : il force le reset à chaque boot. + +## Checklist anti-lockout (indispensable) +### 1) Accès direct local (bypass) + +LLDAP UI accessible en local : http://127.0.0.1:17170 + +Authelia health local : http://127.0.0.1:9091/api/health + +### 2) Règle Authelia : domaine auth en bypass + +Dans configuration.yml : +access_control: + rules: + - domain: "auth." + policy: bypass + +But : pouvoir charger le portail même si les règles des autres domaines cassent. + +### 3) Route de secours reverse-proxy + +Prévoir une route non protégée (ou protégée différemment) pour pouvoir corriger : + +ex: https://admin./ ou un vhost interne LAN-only. + +### 4) Fenêtre privée pour tester + +Toujours tester login/authelia dans un onglet privé pour éviter cookies “fantômes”. + +## Troubleshooting (ce qu’on a rencontré et résolu) +### A) YAML/Compose cassé (tabs, doublons) + +# Symptômes : + +mapping key "ports" already defined + +found character that cannot start any token + +# Fix : + +supprimer tabs + +supprimer doublons (volumes/ports/networks) + +valider : docker compose ... config + +### B) Substitution foireuse des variables dans healthcheck + +# Problème : + +$VAR évalué par compose au parse-time + +# Fix : + +utiliser $$VAR dans CMD-SHELL si nécessaire. + +### C) /config monté read-only + +# Symptômes : + +chown: /config/... Read-only file system + +# Fix : + +monter /config en :rw si Authelia doit écrire des backups/keys. + +### D) Timeouts LDAP aléatoires en bridge + +# Symptômes : + +dial tcp :3890: i/o timeout + +IP Docker “surprise” (subnet 192.168.32.0/20 etc.) + +# Fix robuste DSM : + +passer en network_mode: host + bind 127.0.0.1 + +Authelia -> ldap://127.0.0.1:3890 + +### E) “Authelia OK mais Gitea redemande login” + +# Normal : + +tant que Gitea n’est pas configuré en OIDC vers Authelia, ce n’est pas du SSO. + +Authelia protège l’accès, mais ne crée pas de session Gitea. + diff --git a/docs/gitea-pr-main-protege.md b/docs/gitea-pr-main-protege.md new file mode 100644 index 0000000..acd51c5 --- /dev/null +++ b/docs/gitea-pr-main-protege.md @@ -0,0 +1,67 @@ +# Workflow Git/Gitea — main protégé (PR only) + +## Objectif +Éviter toute casse de `main` : on travaille **toujours** via branche + Pull Request. + +## 1) Démarrer propre (local) +en bash : + +git fetch origin --prune +git checkout main +git reset --hard origin/main +git clean -fd + +## 2) Créer une branche + +git checkout -b fix/ma-modif + +## 3) Modifier, tester, commit + +npm test +git add -A +git commit -m "Mon changement" + +## 4) Push (création branche distante) + +git push -u origin fix/ma-modif + +## 5) Créer la Pull Request (UI Gitea) + +Gitea → repository → Pull Requests → New Pull Request + + base : main + compare : fix/ma-modif + +Si “je ne vois pas de PR” + +Vérifie d’abord qu’il y a un diff réel : + +git log --oneline origin/main..HEAD + +Si la commande ne sort rien : ta branche ne contient aucun commit différent → PR inutile/invisible. + +## 6) Conflits + +Ne merge pas en local vers main (push refusé si main protégé). +On met à jour la branche de PR : + +Option A (simple) : merge main dans la branche + +git fetch origin +git merge origin/main +# résoudre conflits +npm test +git push + +Option B (plus propre) : rebase + +git fetch origin +git rebase origin/main +# résoudre conflits, puis: +npm test +git push --force-with-lease + +## 7) Merge + +Toujours depuis l’UI de la Pull Request (ou via un mainteneur). +