From 67699e7841cad2410b9a605c82cff2e4ab4d5bdb Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Fri, 3 Jul 2026 13:15:52 -0400 Subject: [PATCH] =?UTF-8?q?Grafana=20branch=C3=A9=20au=20SSO=20OIDC=20(?= =?UTF-8?q?=C2=AB=20Se=20connecter=20avec=20Chezlepro=20=C2=BB)=20?= =?UTF-8?q?=E2=80=94=20prouv=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit serveur_grafana : config OIDC via GF_AUTH_GENERIC_OAUTH_* (client grafana, realm chezlepro, secret vault_grafana_oidc). serveur_loki/prometheus/grafana déployés sur obs-01. Fix serveur_loki : créer le groupe loki (paquet crée l'user en nogroup). Prouvé (flux authorization code headless via l'edge) : testmail (LDAP) se connecte à Grafana par le SSO ; /api/user renvoie login/email/name fédérés depuis LDAP. Chaîne LDAP → Keycloak → Grafana. Gaps notés : enregistrement du client OIDC dans Keycloak fait via kcadm à la main (à codifier) ; résolution keycloak→edge sur obs-01 = /etc/hosts manuel (PowerDNS devrait porter les A d'exposition) ; mapping de rôles Grafana. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 13 +++++++++++++ docs/catalogue-services.md | 6 ++++-- roles/serveur_grafana/defaults/main.yml | 12 ++++++++++++ roles/serveur_grafana/templates/setops.conf.j2 | 11 +++++++++++ roles/serveur_loki/tasks/main.yml | 10 ++++++++++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f21741..4e6bda7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,19 @@ group_var). **Gaps notés** : (1) recharger nginx au **renouvellement** du cert (le cert-renewer renouvelle en place, nginx ne recharge pas seul — hook à ajouter) ; (2) **auto-dériver** les SANs d'exposition de l'edge depuis le plan (au lieu de les lister dans le group_var). +- **Grafana branché au SSO OIDC (« Se connecter avec Chezlepro ») — prouvé de bout en bout.** + `serveur_grafana` : config OIDC via `GF_AUTH_GENERIC_OAUTH_*` (client confidentiel `grafana`, + realm `chezlepro`, secret `vault_grafana_oidc`). `serveur_loki` + `serveur_prometheus` + + `serveur_grafana` déployés sur `obs-01` (🔧→⭐). **Bug de rôle corrigé** : `serveur_loki` créait + le répertoire en `group: loki` alors que le paquet crée l'utilisateur en `nogroup` sans groupe + `loki` → ajout de la création du groupe. **Prouvé (flux authorization code headless, via l'edge + HTTPS)** : `testmail` (user LDAP) se connecte à Grafana par le SSO — `/api/user` renvoie + `login: testmail`, email et nom **fédérés depuis LDAP**. Chaîne complète LDAP → Keycloak → + Grafana. **Gaps notés (pour rendre 100 % déclaratif)** : (1) l'**enregistrement du client OIDC** + dans Keycloak a été fait via `kcadm` **à la main** (à codifier — rôle grafana ou liste de clients + côté keycloak) ; (2) la **résolution** `keycloak.…internal → edge` sur obs-01 est un `/etc/hosts` + manuel (**PowerDNS devrait porter les A d'exposition** — chaînon récurrent) ; (3) mapping de + rôles Grafana (tous Viewer par défaut). ## 2026-07-02 diff --git a/docs/catalogue-services.md b/docs/catalogue-services.md index decbb84..9a5fa3b 100644 --- a/docs/catalogue-services.md +++ b/docs/catalogue-services.md @@ -37,8 +37,10 @@ et la **pile courriel complète** `serveur_dovecot` + `serveur_postfix` + `serve (flux SMTP→LDAP→LMTP→IMAP + antispam + DKIM prouvé). Plus, **le SSO et sa base** : `serveur_postgresql` (provisionne les bases du registre — **binding app→base prouvé**) et `serveur_keycloak` (26.0.7, mode prod, 87 tables écrites dans PostgreSQL, token admin obtenu). -Restent « code non éprouvé » : `serveur_redis`, `serveur_prometheus`, `serveur_loki`, -`serveur_grafana`, `serveur_icinga`, `serveur_forgejo`, `serveur_sendmail`. +Plus l'**observabilité sous SSO** (2026-07-03) : `serveur_loki` + `serveur_prometheus` + +`serveur_grafana` sur `obs-01`, avec **Grafana branché au SSO OIDC** (« Se connecter avec +Chezlepro » prouvé : `testmail` LDAP → Keycloak → Grafana). Restent « code non éprouvé » : +`serveur_redis`, `serveur_icinga`, `serveur_forgejo`, `serveur_sendmail`. > **Lacunes connues sur Keycloak** (déployé mais pas complet) : la **fédération LDAP** (Keycloak > → OpenLDAP, modèle d'identité A) n'est **pas encore automatisée** dans le rôle ; l'**edge nginx** diff --git a/roles/serveur_grafana/defaults/main.yml b/roles/serveur_grafana/defaults/main.yml index 32dac5a..74c2b78 100644 --- a/roles/serveur_grafana/defaults/main.yml +++ b/roles/serveur_grafana/defaults/main.yml @@ -16,6 +16,18 @@ serveur_grafana_loki_url: "http://localhost:3100" # Secret OBLIGATOIRE (Ansible Vault). serveur_grafana_admin_password: "{{ vault_grafana_admin | default('') }}" # rempli depuis la voute (vault_grafana_admin) +# --- SSO OIDC (Keycloak, realm applicatif) --- +# « Se connecter avec Chezlepro » : Grafana délègue l'auth à Keycloak (client confidentiel). +# Requiert client_pki sur ce nœud (confiance step_ca pour les appels serveur→Keycloak) + +# résolution de l'hôte Keycloak (edge). Le client OIDC doit exister dans le realm. +serveur_grafana_oidc_actif: true +serveur_grafana_oidc_nom: "Chezlepro" +serveur_grafana_oidc_client_id: "grafana" +serveur_grafana_oidc_client_secret: "{{ vault_grafana_oidc | default('') }}" # voûte (vault_grafana_oidc) +serveur_grafana_oidc_realm: "chezlepro" +serveur_grafana_oidc_base: "https://keycloak.{{ domaine_interne }}/realms/{{ serveur_grafana_oidc_realm }}/protocol/openid-connect" +serveur_grafana_oidc_scopes: "openid email profile" + # Depot apt officiel Grafana (partage avec serveur_loki). serveur_grafana_depot_cle_url: "https://apt.grafana.com/gpg-full.key" serveur_grafana_depot_cle_fichier: "/etc/apt/keyrings/grafana.asc" diff --git a/roles/serveur_grafana/templates/setops.conf.j2 b/roles/serveur_grafana/templates/setops.conf.j2 index bdf601d..bc26ef0 100644 --- a/roles/serveur_grafana/templates/setops.conf.j2 +++ b/roles/serveur_grafana/templates/setops.conf.j2 @@ -3,3 +3,14 @@ Environment=GF_SERVER_DOMAIN={{ serveur_grafana_hostname }} Environment=GF_SERVER_ROOT_URL={{ serveur_grafana_root_url }} Environment=GF_SECURITY_ADMIN_PASSWORD={{ serveur_grafana_admin_password }} Environment=GF_USERS_ALLOW_SIGN_UP=false +{% if serveur_grafana_oidc_actif %} +Environment=GF_AUTH_GENERIC_OAUTH_ENABLED=true +Environment=GF_AUTH_GENERIC_OAUTH_NAME={{ serveur_grafana_oidc_nom }} +Environment=GF_AUTH_GENERIC_OAUTH_CLIENT_ID={{ serveur_grafana_oidc_client_id }} +Environment=GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET={{ serveur_grafana_oidc_client_secret }} +Environment="GF_AUTH_GENERIC_OAUTH_SCOPES={{ serveur_grafana_oidc_scopes }}" +Environment=GF_AUTH_GENERIC_OAUTH_AUTH_URL={{ serveur_grafana_oidc_base }}/auth +Environment=GF_AUTH_GENERIC_OAUTH_TOKEN_URL={{ serveur_grafana_oidc_base }}/token +Environment=GF_AUTH_GENERIC_OAUTH_API_URL={{ serveur_grafana_oidc_base }}/userinfo +Environment=GF_AUTH_GENERIC_OAUTH_LOGIN_ATTRIBUTE_PATH=preferred_username +{% endif %} diff --git a/roles/serveur_loki/tasks/main.yml b/roles/serveur_loki/tasks/main.yml index d454ade..889d251 100644 --- a/roles/serveur_loki/tasks/main.yml +++ b/roles/serveur_loki/tasks/main.yml @@ -27,6 +27,16 @@ state: present update_cache: true +- name: Assurer le groupe loki (le paquet cree l'utilisateur en nogroup) + ansible.builtin.group: + name: loki + system: true + +- name: Rattacher l'utilisateur loki a son groupe + ansible.builtin.user: + name: loki + group: loki + - name: Assurer le repertoire de donnees Loki ansible.builtin.file: path: "{{ serveur_loki_chemin }}"