Funk-lab/admin/k8s/auth-portal.md
alkatrazz edf4a6294d feat(auth): annuaire Authentik + portail consoles Guacamole
- k8s/apps/authentik : IdP OIDC (auth.lab.local), namespace auth —
  server + worker 2026.5.3, Redis in-cluster, PG sur storage-01, PVC media
- k8s/apps/guacamole : portail consoles SSH web s01/g01 (portail.lab.local) —
  guacd + webapp 1.6.0, SSO OIDC vers Authentik, Job initdb idempotent
- ansible : rôle console_user (user sans sudo pour les consoles, s01 + g01),
  bases PG authentik/guacamole, secrets vault (mdp PG + clé SSH console)
- doc : admin/k8s/auth-portal.md (déploiement, config initiale, pièges)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 21:19:23 +02:00

103 lines
5.3 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"`** : garde le formulaire local (guacadmin) accessible
en plus du SSO — sans ça, redirection OIDC forcée et plus d'accès admin local.
4. **User `console` sans sudo** (volontaire) : le portail sert à observer/opérer léger.
L'administration passe par les comptes admin habituels, pas par Guacamole.
5. **Enregistrement des sessions** : possible (guacd + volume partagé) mais non configuré
— gap connu, à ajouter si le portail s'ouvre à d'autres utilisateurs.
6. 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.