From df8ffb68d63f52a946f589f299115f1ca9dc3473 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Fri, 7 Aug 2026 19:54:41 -0400 Subject: [PATCH] icingaweb2 : habilitation par groupe d'annuaire, plus par liste d'uid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le dernier `porte_par: liste-uid` du catalogue. `roles.ini` porte desormais `groups = "sysadmin"` ; `serveur_icingaweb2_admins` devient un repli de depannage, VIDE par defaut. Le mode SSO complique le montage : les membres d'un `groupOfNames` sont des DN, alors que `REMOTE_USER` est une chaine. Un backend LDAP supplementaire est declare — jamais utilise pour authentifier — uniquement pour que `groups.ini` resolve le nom vers son DN. Sans ce pont, l'habilitation par groupe est impossible en SSO. NON PROUVE : la resolution REMOTE_USER -> DN -> appartenance est interne a Icinga Web 2 ; seule une connexion reelle par le SSO la confirmera. Co-Authored-By: Claude Opus 5 --- CHANGELOG.md | 20 +++++++++++++++++++ roles/serveur_icingaweb2/defaults/main.yml | 12 ++++++++++- roles/serveur_icingaweb2/meta/acces.yml | 16 +++++++++------ roles/serveur_icingaweb2/tasks/main.yml | 1 + .../templates/authentication.ini.j2 | 12 +++++++++++ .../templates/groups.ini.j2 | 12 +++++++++++ .../serveur_icingaweb2/templates/roles.ini.j2 | 5 +++++ 7 files changed, 71 insertions(+), 7 deletions(-) create mode 100644 roles/serveur_icingaweb2/templates/groups.ini.j2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 248cb75..c7017c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,26 @@ ## 2026-08-06 — le chemin nord-sud devient dérivable +### Icinga Web 2 cesse de nommer des personnes + +Le dernier `porte_par: liste-uid` du catalogue. `serveur_icingaweb2_admins` valait un `uid` +en dur ; `roles.ini` porte désormais `groups = "sysadmin"`, et `serveur_icingaweb2_admins` +devient un repli de dépannage, **vide par défaut**. + +**Le mode SSO complique le montage, et il faut le dire.** Les membres d'un `groupOfNames` +sont des **DN** ; en `auth: external`, le nom d'utilisateur vient de `REMOTE_USER` — une +chaîne, pas un DN. Un backend LDAP supplémentaire est donc déclaré dans +`authentication.ini` : **jamais utilisé pour authentifier** (l'externe répond en premier), +uniquement pour que `groups.ini` résolve le nom vers son DN. + +Sans ce pont, l'habilitation par groupe est impossible en SSO — et il faudrait continuer à +nommer des personnes. + +**Ce que je n'ai pas pu vérifier.** La configuration est déployée et cohérente, mais la +résolution `REMOTE_USER → DN → appartenance` est interne à Icinga Web 2 : seule une connexion +réelle par le SSO la prouve. Je ne la déclare donc pas prouvée. + + ### Administrer le realm par appartenance — le dernier `porte_par: aucun` `realm-admin` (rôle du client `realm-management`) est attaché au **groupe** `sysadmin`. diff --git a/roles/serveur_icingaweb2/defaults/main.yml b/roles/serveur_icingaweb2/defaults/main.yml index bc64cce..2b8f811 100644 --- a/roles/serveur_icingaweb2/defaults/main.yml +++ b/roles/serveur_icingaweb2/defaults/main.yml @@ -49,7 +49,17 @@ serveur_icingaweb2_ldap_user_attr: "uid" # En attendant, le défaut suit l'`uid` d'amorçage plutôt qu'un compte de test : # `testmail` était codé en dur et n'existe dans aucune instance — le seul # administrateur déclaré était donc un utilisateur inexistant (2026-08-07). -serveur_icingaweb2_admins: "{{ amorcage_acces_uid | default('sysadmin') }}" +# Repli seulement, et VIDE par defaut : l'habilitation passe par le GROUPE +# (`serveur_icingaweb2_groupe_admin`). Le renseigner nomme des personnes, ce que +# D-66 interdit — a n'utiliser que pour un depannage. +serveur_icingaweb2_admins: "" + +# Habilitation par groupe d'annuaire. Le schema est celui que `amorcage_acces` pose : +# des `groupOfNames` dont les membres sont des DN. +serveur_icingaweb2_groupe_admin: "{{ amorcage_acces_groupe | default('sysadmin') }}" +serveur_icingaweb2_groupe_class: "groupOfNames" +serveur_icingaweb2_groupe_membre_attr: "member" +serveur_icingaweb2_groupes_dn: "ou=groups,{{ resoudre_annuaire_base_dn | default('') }}" # Backend d'authentification : "ldap" (direct) ou "external" (utilisateur fourni par une # passerelle SSO devant, ex. oauth2-proxy → Keycloak). En "external", nginx doit poser REMOTE_USER. diff --git a/roles/serveur_icingaweb2/meta/acces.yml b/roles/serveur_icingaweb2/meta/acces.yml index eaa589d..c84565a 100644 --- a/roles/serveur_icingaweb2/meta/acces.yml +++ b/roles/serveur_icingaweb2/meta/acces.yml @@ -3,11 +3,15 @@ acces: - groupe: sysadmin accorde: Administrateur - # /!\ `liste-uid` NOMME DES PERSONNES (`serveur_icingaweb2_admins`), ce que - # D-66 interdit : revoquer quelqu'un demande alors un deploiement, et le - # service porte une liste qui vieillit sans que rien ne le signale. - # Icinga Web 2 sait lire un groupe d'annuaire (backend LDAP de type `group`) : - # c'est vers cela qu'il faut aller. Constate le 2026-08-07. - porte_par: liste-uid + # Backend de GROUPES LDAP (`groups.ini`) + `groups =` dans roles.ini. + # + # En mode SSO (`auth: external`) le nom d'utilisateur vient de REMOTE_USER, + # alors que les membres d'un `groupOfNames` sont des DN : un backend LDAP + # supplementaire est declare — jamais utilise pour authentifier — uniquement + # pour resoudre le nom vers son DN. Sans lui, l'habilitation par groupe est + # impossible en SSO et il faudrait nommer des personnes. + # + # `serveur_icingaweb2_admins` reste comme repli de depannage, VIDE par defaut. + porte_par: groupe-annuaire raison: >- Acces complet a la supervision : hotes, services, commandes. diff --git a/roles/serveur_icingaweb2/tasks/main.yml b/roles/serveur_icingaweb2/tasks/main.yml index 3cb1e75..dee0687 100644 --- a/roles/serveur_icingaweb2/tasks/main.yml +++ b/roles/serveur_icingaweb2/tasks/main.yml @@ -52,6 +52,7 @@ - { s: config.ini.j2, d: config.ini } - { s: resources.ini.j2, d: resources.ini, secret: true } - { s: authentication.ini.j2, d: authentication.ini } + - { s: groups.ini.j2, d: groups.ini } - { s: roles.ini.j2, d: roles.ini } - { s: icingadb-config.ini.j2, d: modules/icingadb/config.ini } - { s: icingadb-redis.ini.j2, d: modules/icingadb/redis.ini } diff --git a/roles/serveur_icingaweb2/templates/authentication.ini.j2 b/roles/serveur_icingaweb2/templates/authentication.ini.j2 index 2684af9..82f472a 100644 --- a/roles/serveur_icingaweb2/templates/authentication.ini.j2 +++ b/roles/serveur_icingaweb2/templates/authentication.ini.j2 @@ -3,6 +3,18 @@ ; SSO : l'utilisateur est fourni par la passerelle (oauth2-proxy → Keycloak) via REMOTE_USER. [icingaweb2] backend = "external" + +; Backend LDAP declare mais JAMAIS utilise pour authentifier : l'externe repond en +; premier. Il sert au backend de GROUPES, qui doit resoudre un nom d'utilisateur vers +; son DN — les membres d'un `groupOfNames` sont des DN, pas des uid. +; Sans lui, l'habilitation par groupe est impossible en mode SSO, et il faudrait +; nommer des personnes (ce que D-66 interdit). +[ldap-annuaire] +backend = "ldap" +resource = "icingaweb_ldap" +user_class = "{{ serveur_icingaweb2_ldap_user_class }}" +user_name_attribute = "{{ serveur_icingaweb2_ldap_user_attr }}" +base_dn = "{{ serveur_icingaweb2_ldap_users_dn }}" {% else %} [icingaweb2] backend = "ldap" diff --git a/roles/serveur_icingaweb2/templates/groups.ini.j2 b/roles/serveur_icingaweb2/templates/groups.ini.j2 new file mode 100644 index 0000000..2ade2b9 --- /dev/null +++ b/roles/serveur_icingaweb2/templates/groups.ini.j2 @@ -0,0 +1,12 @@ +; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main. +; Habilitation par GROUPE d'annuaire (D-66) : ajouter quelqu'un a +; `{{ serveur_icingaweb2_groupe_admin }}` dans LDAP lui ouvre la supervision, sans +; deploiement et sans que personne ne soit nomme ici. +[annuaire] +backend = "ldap" +resource = "icingaweb_ldap" +user_backend = "{{ 'ldap-annuaire' if serveur_icingaweb2_auth == 'external' else 'icingaweb2' }}" +group_class = "{{ serveur_icingaweb2_groupe_class }}" +group_name_attribute = "cn" +group_member_attribute = "{{ serveur_icingaweb2_groupe_membre_attr }}" +base_dn = "{{ serveur_icingaweb2_groupes_dn }}" diff --git a/roles/serveur_icingaweb2/templates/roles.ini.j2 b/roles/serveur_icingaweb2/templates/roles.ini.j2 index a4f99e4..1d02365 100644 --- a/roles/serveur_icingaweb2/templates/roles.ini.j2 +++ b/roles/serveur_icingaweb2/templates/roles.ini.j2 @@ -1,4 +1,9 @@ ; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main. [Administrators] +; Le GROUPE, jamais des personnes (D-66) : revoquer quelqu'un ne demande alors +; aucun deploiement. `serveur_icingaweb2_admins` reste un repli, vide par defaut. +groups = "{{ serveur_icingaweb2_groupe_admin }}" +{% if serveur_icingaweb2_admins | length > 0 %} users = "{{ serveur_icingaweb2_admins }}" +{% endif %} permissions = "*"