Funk-lab/admin/k8s/auth-portal.md
alkatrazz 0957db2832 docs(portal): doc d'administration + guide utilisateur
- 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:34:52 +02:00

8.1 KiB
Raw Permalink Blame History

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 :

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.frtout 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 guacamoleRedirect 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.