Funk-lab/admin/k8s/auth-portal.md
ALI YESILKAYA fbec998c21
feat(guacamole): SSO direct — redirection immédiate vers Authentik (#79)
EXTENSION_PRIORITY "openid, *" : plus de formulaire local, l'arrivée sur
portail.lab.local redirige directement vers Authentik. L'admin passe par
un compte SSO avec « Administer system » (guacadmin devient inaccessible ;
retour arrière = remettre "*, openid").

Doc : pièges slug d'application (≠ guacamole → JWKS 404) et anti-bruteforce
(IP Traefik bloquée pour tous après 5 échecs) découverts pendant la mise
en route.

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

114 lines
6.2 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`**.
## 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).
## Pièges / notes
1. **Tout est en HTTP** (pas de TLS sur `*.lab.local`) — OK pour un LAN privé, mais ne
**jamais** exposer le portail sur Internet en l'état.
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, *"`** : arrivée sur le portail = **redirection
immédiate vers Authentik** (pas de formulaire local). Conséquence : `guacadmin` est
inaccessible — l'admin Guacamole passe par un compte SSO auquel on a coché
**« Administer system »** (fait pour `Alkatrazz`). Prérequis absolu avant d'activer :
avoir donné ce droit, sinon plus d'admin. Dépannage si Authentik est HS : remettre
`"*, openid"` dans `k8s/apps/guacamole/deployment.yaml` (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.