icingaweb2 : habilitation par groupe d'annuaire, plus par liste d'uid
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 <noreply@anthropic.com>
This commit is contained in:
parent
1b16e67cdc
commit
df8ffb68d6
7 changed files with 71 additions and 7 deletions
20
CHANGELOG.md
20
CHANGELOG.md
|
|
@ -2,6 +2,26 @@
|
||||||
|
|
||||||
## 2026-08-06 — le chemin nord-sud devient dérivable
|
## 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`
|
### Administrer le realm par appartenance — le dernier `porte_par: aucun`
|
||||||
|
|
||||||
`realm-admin` (rôle du client `realm-management`) est attaché au **groupe** `sysadmin`.
|
`realm-admin` (rôle du client `realm-management`) est attaché au **groupe** `sysadmin`.
|
||||||
|
|
|
||||||
|
|
@ -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 :
|
# 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
|
# `testmail` était codé en dur et n'existe dans aucune instance — le seul
|
||||||
# administrateur déclaré était donc un utilisateur inexistant (2026-08-07).
|
# 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
|
# 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.
|
# passerelle SSO devant, ex. oauth2-proxy → Keycloak). En "external", nginx doit poser REMOTE_USER.
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,15 @@
|
||||||
acces:
|
acces:
|
||||||
- groupe: sysadmin
|
- groupe: sysadmin
|
||||||
accorde: Administrateur
|
accorde: Administrateur
|
||||||
# /!\ `liste-uid` NOMME DES PERSONNES (`serveur_icingaweb2_admins`), ce que
|
# Backend de GROUPES LDAP (`groups.ini`) + `groups =` dans roles.ini.
|
||||||
# D-66 interdit : revoquer quelqu'un demande alors un deploiement, et le
|
#
|
||||||
# service porte une liste qui vieillit sans que rien ne le signale.
|
# En mode SSO (`auth: external`) le nom d'utilisateur vient de REMOTE_USER,
|
||||||
# Icinga Web 2 sait lire un groupe d'annuaire (backend LDAP de type `group`) :
|
# alors que les membres d'un `groupOfNames` sont des DN : un backend LDAP
|
||||||
# c'est vers cela qu'il faut aller. Constate le 2026-08-07.
|
# supplementaire est declare — jamais utilise pour authentifier — uniquement
|
||||||
porte_par: liste-uid
|
# 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: >-
|
raison: >-
|
||||||
Acces complet a la supervision : hotes, services, commandes.
|
Acces complet a la supervision : hotes, services, commandes.
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@
|
||||||
- { s: config.ini.j2, d: config.ini }
|
- { s: config.ini.j2, d: config.ini }
|
||||||
- { s: resources.ini.j2, d: resources.ini, secret: true }
|
- { s: resources.ini.j2, d: resources.ini, secret: true }
|
||||||
- { s: authentication.ini.j2, d: authentication.ini }
|
- { s: authentication.ini.j2, d: authentication.ini }
|
||||||
|
- { s: groups.ini.j2, d: groups.ini }
|
||||||
- { s: roles.ini.j2, d: roles.ini }
|
- { s: roles.ini.j2, d: roles.ini }
|
||||||
- { s: icingadb-config.ini.j2, d: modules/icingadb/config.ini }
|
- { s: icingadb-config.ini.j2, d: modules/icingadb/config.ini }
|
||||||
- { s: icingadb-redis.ini.j2, d: modules/icingadb/redis.ini }
|
- { s: icingadb-redis.ini.j2, d: modules/icingadb/redis.ini }
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,18 @@
|
||||||
; SSO : l'utilisateur est fourni par la passerelle (oauth2-proxy → Keycloak) via REMOTE_USER.
|
; SSO : l'utilisateur est fourni par la passerelle (oauth2-proxy → Keycloak) via REMOTE_USER.
|
||||||
[icingaweb2]
|
[icingaweb2]
|
||||||
backend = "external"
|
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 %}
|
{% else %}
|
||||||
[icingaweb2]
|
[icingaweb2]
|
||||||
backend = "ldap"
|
backend = "ldap"
|
||||||
|
|
|
||||||
12
roles/serveur_icingaweb2/templates/groups.ini.j2
Normal file
12
roles/serveur_icingaweb2/templates/groups.ini.j2
Normal file
|
|
@ -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 }}"
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main.
|
; Géré par Set-OPS (rôle serveur_icingaweb2). Ne pas éditer à la main.
|
||||||
[Administrators]
|
[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 }}"
|
users = "{{ serveur_icingaweb2_admins }}"
|
||||||
|
{% endif %}
|
||||||
permissions = "*"
|
permissions = "*"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue