Funk-lab/admin/k8s/auth-portal.md
ALI YESILKAYA dc9fc884ac
docs(portal): doc d'administration + guide utilisateur (#83)
- admin/k8s/auth-portal-admin.md : exploitation au quotidien — cycle de
  vie utilisateur (créer/groupe guacamole/assigner/révoquer), gestion des
  machines et des apps du hub, durcissement (MFA), table de débogage
- docs/portail-guide-utilisateur.md : guide grand public à envoyer aux
  utilisateurs (connexion, console, presse-papiers, règles, dépannage)
- renvois croisés depuis auth-portal.md et CLAUDE.md

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 11:37:10 +02:00

148 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Annuaire + portail consoles — Authentik & Guacamole
Annuaire d'identités **Authentik** (IdP OIDC/LDAP) et portail **Guacamole** donnant
accès aux consoles SSH de storage-01 et gpu-01 **dans le navigateur**, avec un compte
unique par utilisateur. Namespace k8s : **`auth`**.
> Ce document = architecture, déploiement, pièges. Voir aussi :
> **`admin/k8s/auth-portal-admin.md`** (administration au quotidien : utilisateurs,
> machines, apps du hub, révocation) et **`docs/portail-guide-utilisateur.md`**
> (guide à envoyer aux utilisateurs).
## Vue d'ensemble
```
Utilisateur ──▶ portail.lab.local (Guacamole) ──login OIDC──▶ auth.lab.local (Authentik)
└──▶ guacd ──SSH (user « console », clé ed25519)──▶ s01 / g01
```
| URL | Service | Rôle |
|---|---|---|
| `http://auth.lab.local` | Authentik | Annuaire : comptes, groupes, SSO OIDC |
| `http://portail.lab.local` | Guacamole | Portail : consoles SSH web s01/g01 |
## Composants
- **Authentik** (`k8s/apps/authentik/`) : server + worker (`ghcr.io/goauthentik/server:2026.5.3`),
Redis in-cluster, PVC `authentik-media` (RWX, nfs), base **PostgreSQL sur storage-01**
(même pattern que Ghostfolio/n8n).
- **Guacamole** (`k8s/apps/guacamole/`) : webapp `guacamole/guacamole:1.6.0` + proxy
`guacamole/guacd:1.6.0`, base PostgreSQL sur storage-01 (connexions, permissions).
Le Job ArgoCD `guacamole-initdb` pose le schéma si absent (idempotent).
- **Ansible** : rôle `postgresql` (bases `authentik` + `guacamole`), rôle **`console_user`**
(user `console` **sans sudo** sur s01 et g01, clé publique Guacamole).
## Secrets
Vault Ansible (`make vault-view`) :
| Variable | Usage |
|---|---|
| `vault_pg_authentik_password` | Base PG `authentik` |
| `vault_pg_guacamole_password` | Base PG `guacamole` |
| `vault_console_ssh_private_key` | Clé privée SSH des connexions Guacamole (user `console`) |
Secrets k8s (créés à la main, **hors git**, comme `ghostfolio-secret`) — mots de passe
identiques au vault, `secret-key` = 48+ caractères aléatoires :
```bash
kubectl create ns auth
kubectl -n auth create secret generic authentik-secret \
--from-literal=secret-key='<clé aléatoire>' \
--from-literal=pg-password='<vault_pg_authentik_password>' \
--from-literal=redis-password='<aléatoire>'
kubectl -n auth create secret generic guacamole-secret \
--from-literal=pg-password='<vault_pg_guacamole_password>'
```
## Déploiement (ordre)
1. `ansible-playbook -i inventory.yml playbooks/storage-01.yml --tags postgresql,console_user`
2. `ansible-playbook -i inventory.yml playbooks/gpu-01.yml --tags console_user`
3. Créer les secrets k8s ci-dessus (avant le premier sync, sinon pods en `CreateContainerConfigError`)
4. Merge sur `main` → ArgoCD crée les Applications `authentik` et `guacamole` (~3 min)
## Configuration initiale — Authentik
1. **Compte admin** : ouvrir `http://auth.lab.local/if/flow/initial-setup/` (valable
uniquement tant qu'aucun admin n'existe) → définir mot de passe de `akadmin`.
2. **Provider OIDC** pour Guacamole — Admin → Applications → Providers → Create
*OAuth2/OpenID Provider* :
- Name : `guacamole` — Authorization flow : *implicit-consent*
- Client type : **Public** (Guacamole utilise le flux implicite, pas de client secret)
- Client ID : `guacamole`
- Redirect URI : `http://portail.lab.local/`
- **Signing Key : sélectionner le certificat self-signed** (sinon JWKS vide → login KO)
3. **Application** — Applications → Create : Name `Portail consoles`,
**slug `guacamole`** (doit correspondre à `/application/o/guacamole/` configuré côté
Guacamole : issuer + JWKS), Provider `guacamole`.
4. **Utilisateurs** — Directory → Users → Create (+ groupes si besoin). Le
`preferred_username` Authentik devient le nom de compte Guacamole.
## Configuration initiale — Guacamole
1. Se connecter en **`guacadmin` / `guacadmin`** (formulaire local, extension base) et
**changer ce mot de passe immédiatement** (portail exposé à tout le LAN).
2. Settings → Connections → New connection (×2) :
- Protocol `SSH` — Hostname `192.168.10.1` (s01) ou `192.168.10.20` (g01) — Port `22`
- Username `console` — Private key : coller `vault_console_ssh_private_key`
3. Settings → Users : les comptes Authentik apparaissent après leur **premier login**
(`POSTGRESQL_AUTO_CREATE_ACCOUNTS=true`) → leur assigner les connexions (READ).
## Accès externe (Internet) — Authentik en hub utilisateur
**Authentik est la porte d'entrée** (page « My applications » : une tuile par app
autorisée), le SSO fait le reste. Choix assumé 2026-07-07 : exposition directe sans
VPN, simplicité d'abord (WireGuard reste dispo, cf. `admin/infra/wireguard.md`).
| URL publique | Service | Chaîne |
|---|---|---|
| `http://kaya.freeboxos.fr:9081` | **Authentik** (hub + login) | Freebox `9081/tcp → s01` → DNAT → VIP MetalLB `192.168.10.201:9000` |
| `http://kaya.freeboxos.fr:9080` | Guacamole (via tuile SSO) | Freebox `9080/tcp → s01` → DNAT → VIP `192.168.10.202:8080` |
- **URL canonique unique** : les endpoints OIDC de Guacamole pointent sur
`kaya.freeboxos.fr`**tout le monde, LAN inclus**, doit utiliser ces URLs (le LAN
repasse par la Freebox, hairpin NAT). `portail.lab.local` affiche encore l'UI mais
le SSO ramène sur l'URL publique.
- Les VIPs dédiées **contournent Traefik** : un DNAT par port ne peut pas router par
Host sur l'entrypoint unique :80.
- **Un seul compte par personne (Authentik)** — plus de comptes locaux Guacamole.
Parcours ami : `kaya.freeboxos.fr:9081` → login → tuile « Portail consoles » →
console. Nouvelle app plus tard = nouveau provider + tuile, zéro compte en plus.
- **Garde-fous** : rate-limit nftables (30 connexions neuves/min par service) +
protections applicatives (Authentik : flows/lockout ; Guacamole : ban 5 échecs).
⚠️ HTTP **non chiffré** : mots de passe interceptables en théorie — mots de passe
dédiés, MFA/TOTP Authentik recommandé pour durcir, TLS (vrai domaine + Let's
Encrypt) si l'usage s'installe.
Config côté Authentik (UI) : provider `guacamole` → **Redirect URI
`http://kaya.freeboxos.fr:9080/`** ; application « Portail consoles » → **Launch URL
`http://kaya.freeboxos.fr:9080/`**.
## Pièges / notes
1. **Tout est en HTTP** (pas de TLS) — accepté y compris pour l'accès Internet
(cf. section ci-dessus), avec garde-fous réseau + mots de passe dédiés.
2. **JWKS via le Service interne** (`authentik.auth.svc.cluster.local:9000`) : l'appel
serveur→serveur de Guacamole ne dépend pas de la résolution `lab.local` des pods.
L'issuer, lui, reste `http://auth.lab.local/...` (doit matcher le claim `iss` des
tokens émis via le navigateur).
3. **`EXTENSION_PRIORITY="openid, *"`** : arriver sur Guacamole = redirection
immédiate vers Authentik (le hub). Conséquence : `guacadmin` inaccessible —
l'admin passe par le compte SSO `Alkatrazz` (« Administer system »). Dépannage si
Authentik est HS : remettre `"*, openid"` dans le deployment + re-sync (le
formulaire local revient).
4. **Le slug de l'application Authentik doit être exactement `guacamole`** : Authentik
le génère depuis le nom (« Portail consoles » → `portail-consoles`) et l'issuer/JWKS
deviennent faux → log Guacamole `Non 200 status code (404) ... /o/guacamole/jwks/`
et token rejeté. Corriger : Applications → Edit → Slug.
5. **Anti-bruteforce intégré** (extension `ban`) : 5 échecs → IP bloquée ~5 min. Derrière
Traefik, l'IP vue est celle du proxy → **le blocage touche tout le monde**. Patienter
ou redémarrer le pod guacamole pour purger.
6. **User `console` sans sudo** (volontaire) : le portail sert à observer/opérer léger.
L'administration passe par les comptes admin habituels, pas par Guacamole.
7. **Enregistrement des sessions** : possible (guacd + volume partagé) mais non configuré
— gap connu, à ajouter si le portail s'ouvre à d'autres utilisateurs.
8. La config Authentik (provider, app, utilisateurs) et les connexions Guacamole vivent
**en base, pas en IaC** — comme le Server Manager Satisfactory. Backup PG = gap connu.