Doc à jour : unité wiki Autorisation & RBAC + leçon renouvellement + runbooks
Fermeture des dettes de doc : - nouvelle unité wiki « Autorisation & RBAC » (authZ, exemple Grafana) ; - section « le renouvellement est un système » dans l'unité PKI ; - docs/runbooks-exploitation.md (cert expiré, RBAC Grafana, branding). 15 unités wiki. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
94c9277c3d
commit
b6952759f5
5 changed files with 180 additions and 2 deletions
|
|
@ -14,6 +14,11 @@
|
|||
l'incident : `systemctl reload nginx` sur l'edge.
|
||||
|
||||
### Ajouté
|
||||
- **Doc à jour : unité wiki « Autorisation & RBAC », leçon renouvellement, runbooks.** Fermeture
|
||||
des dettes de doc : nouvelle **unité wiki authZ/RBAC** (pendant d'*Identité & SSO*, avec l'exemple
|
||||
Grafana), **section « le renouvellement est un système »** versée dans l'unité *PKI* (comparer cert
|
||||
servi vs fichier ; recharger le consommateur), et **`docs/runbooks-exploitation.md`** (cert expiré,
|
||||
RBAC Grafana, branding Forgejo). 15 unités wiki désormais.
|
||||
- **UI des logs Loki : dashboard Grafana provisionné.** Loki n'a pas d'UI ; son UI est Grafana.
|
||||
Ajout d'un **dashboard « Journaux de la flotte »** (dossier Set-OPS) : sélecteur d'hôte multi +
|
||||
filtre regex insensible à la casse + panneau logs + débit par hôte. Référence Loki par une
|
||||
|
|
|
|||
66
docs/runbooks-exploitation.md
Normal file
66
docs/runbooks-exploitation.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Runbooks d'exploitation — Set-OPS
|
||||
|
||||
Procédures courtes et concrètes pour les situations d'exploitation. Complète les *docs/* de
|
||||
conception (le *pourquoi*) par le *comment faire*. Le wiki de formation en donne la version
|
||||
pédagogique.
|
||||
|
||||
---
|
||||
|
||||
## 1. Un certificat a expiré / le login SSO est cassé
|
||||
|
||||
**Symptôme** : connexion à une app via le SSO échoue *après* le login ; log Grafana/app :
|
||||
`tls: failed to verify certificate: x509: certificate has expired`.
|
||||
|
||||
**Cause fréquente** : le cert step-ca a été **renouvelé sur disque** mais le service (nginx sur
|
||||
l'edge) **n'a pas été rechargé** → il sert l'ancien cert en mémoire.
|
||||
|
||||
**Diagnostic-réflexe** — comparer le cert *servi* au cert *fichier* :
|
||||
```bash
|
||||
# SERVI (en mémoire par nginx)
|
||||
echo | openssl s_client -connect infra-edge-01…:443 -servername keycloak.lab… 2>/dev/null \
|
||||
| openssl x509 -noout -enddate
|
||||
# FICHIER (sur disque)
|
||||
openssl x509 -in /etc/step/certs/infra-edge-01….crt -noout -enddate
|
||||
```
|
||||
Dates différentes (servi < fichier) ⇒ nginx sert un cert périmé.
|
||||
|
||||
**Fix immédiat** : `systemctl reload nginx` sur l'edge (idem `postfix`/`dovecot`/`slapd` selon le
|
||||
service touché).
|
||||
|
||||
**Fix permanent (déjà en place)** : `client_pki_reload_services` recharge les vrais consommateurs
|
||||
après chaque renouvellement — edge→nginx, mail→postfix/dovecot, annuaire→slapd. Vérifier :
|
||||
`systemctl cat cert-renewer@$(hostname -f).service | grep ExecStartPost`.
|
||||
Voir aussi l'unité wiki *PKI & confiance* (⑤ le renouvellement).
|
||||
|
||||
---
|
||||
|
||||
## 2. Donner Explore/Editor à un opérateur dans Grafana (RBAC)
|
||||
|
||||
Par défaut, un utilisateur SSO est **Viewer** (dashboards seulement, pas Explore). Pour l'élever :
|
||||
|
||||
1. Déclarer l'assignation dans l'inventaire de l'instance (group_vars `serveur_keycloak`) :
|
||||
```yaml
|
||||
serveur_keycloak_role_assignments:
|
||||
- { user: <uid>, role: grafana-editor } # ou grafana-admin
|
||||
```
|
||||
2. Redéployer Keycloak (`make deployer` sur le nœud SSO) — kcadm **à chaud, sans coupure**.
|
||||
3. L'utilisateur doit **se déconnecter/reconnecter** (Grafana applique le rôle à la connexion).
|
||||
|
||||
Mapping (défaut du rôle grafana) : `grafana-admin`→Admin, `grafana-editor`→Editor, sinon Viewer
|
||||
(`serveur_grafana_oidc_role_path`). Idéal souverain : piloter par un **groupe d'annuaire** plutôt
|
||||
qu'un utilisateur explicite. Voir l'unité wiki *Autorisation & RBAC*.
|
||||
|
||||
---
|
||||
|
||||
## 3. Brander une instance Forgejo (identité visuelle)
|
||||
|
||||
Activer dans l'inventaire (group_vars `serveur_forgejo`) :
|
||||
```yaml
|
||||
serveur_forgejo_branding: true
|
||||
serveur_forgejo_app_name: "Forge Chezlepro"
|
||||
serveur_forgejo_theme: "forgejo-dark"
|
||||
serveur_forgejo_meta_description: "…"
|
||||
```
|
||||
Puis redéployer. Le rôle déploie le dossier `custom/` officiel (logo/favicon aurore, accent CSS par
|
||||
variables, page d'accueil brandée) — léger, résistant aux MAJ (aucune classe interne touchée).
|
||||
Note : ne s'applique qu'aux Forgejo **gérées par Set-OPS**.
|
||||
81
wiki/Autorisation-et-RBAC.md
Normal file
81
wiki/Autorisation-et-RBAC.md
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
# Autorisation & RBAC
|
||||
|
||||
> **Unité d'apprentissage.** Moule : ① concept → ② Set-OPS → ③ transférable → ④ à toi de jouer.
|
||||
> Le pendant naturel de **[Identité & SSO](Identité-et-SSO)** : celle-là dit *qui tu es*, celle-ci dit *ce que tu as le droit de faire*.
|
||||
|
||||
---
|
||||
|
||||
## ① Le concept *(générique)*
|
||||
|
||||
**Authentification (authN)** : *qui es-tu ?* — **Autorisation (authZ)** : *as-tu le droit ?* Deux
|
||||
questions distinctes. Se connecter ne dit **rien** sur ce qu'on peut faire.
|
||||
|
||||
**RBAC** (*Role-Based Access Control*) : on n'attribue pas des droits à chaque personne, mais des
|
||||
**rôles** (Viewer, Editor, Admin…), et chaque rôle porte un ensemble de **permissions**. La personne
|
||||
reçoit un rôle → hérite des droits. Simple, auditable, évolutif.
|
||||
|
||||
**Où décider ?** Deux écoles :
|
||||
- *local à l'app* : chaque service gère ses propres comptes/rôles (silos, à maintenir partout) ;
|
||||
- *centralisé (piloté par le SSO/annuaire)* : le rôle voyage **dans le jeton** ; l'app le lit et
|
||||
l'applique. Une seule source, cohérente partout. **Moindre privilège** par défaut.
|
||||
|
||||
Mécanique OIDC : le fournisseur d'identité met un **claim** (ex. `roles`) dans le jeton ; l'app
|
||||
**mappe** ce claim vers son niveau de droit interne.
|
||||
|
||||
---
|
||||
|
||||
## ② Comment Set-OPS le fait — l'exemple Grafana
|
||||
|
||||
Par défaut, un utilisateur SSO arrive en **Viewer** dans Grafana → il voit les tableaux de bord,
|
||||
mais **pas Explore** (requêtes ad-hoc). Pour donner Explore aux opérateurs, sans l'ouvrir à tous :
|
||||
|
||||
```
|
||||
Keycloak : rôle de realm 'grafana-editor' ──(assigné à testmail)
|
||||
+ mapper de rôles ──> claim "roles":["grafana-editor"] dans le jeton
|
||||
Grafana : role_attribute_path ──> "grafana-editor" ⇒ Editor (⇒ Explore)
|
||||
"grafana-admin" ⇒ Admin ; sinon Viewer
|
||||
```
|
||||
|
||||
Déclaratif dans Set-OPS : `serveur_keycloak_realm_roles`, `_role_mapper_clients`,
|
||||
`_role_assignments` (côté IdP) + `serveur_grafana_oidc_role_path` (côté app). kcadm **à chaud** :
|
||||
**zéro coupure SSO**. Une identité (`testmail`), et c'est **le rôle** — pas la connexion — qui décide
|
||||
d'Explore.
|
||||
|
||||
> **Raffinement souverain** : ici le rôle est assigné *explicitement* à testmail. L'idéal est de le
|
||||
> piloter par un **groupe d'annuaire** (LDAP → Keycloak → claim), pour que *l'appartenance* gouverne
|
||||
> l'autorisation. C'est le vrai « l'annuaire gouverne l'accès ».
|
||||
|
||||
---
|
||||
|
||||
## ③ Pourquoi c'est transférable
|
||||
|
||||
| Set-OPS | Équivalents ailleurs |
|
||||
|---|---|
|
||||
| rôles de realm Keycloak → claim | claims/scopes OIDC de tout IdP (Okta, Entra…) |
|
||||
| `role_attribute_path` Grafana | *role mapping* de n'importe quelle app OIDC |
|
||||
| RBAC (rôles → permissions) | **Kubernetes RBAC** · IAM cloud (AWS/GCP) · SGBD (rôles SQL) |
|
||||
| moindre privilège | principe **universel** de sécurité |
|
||||
|
||||
Tu as appris **authZ vs authN, le RBAC, l'autorisation par claim, le moindre privilège** — pas
|
||||
« Grafana ».
|
||||
|
||||
---
|
||||
|
||||
## ④ À toi de jouer
|
||||
|
||||
1. **Sens le défaut.** Avant tout rôle, un nouvel utilisateur SSO est **Viewer** dans Grafana : il
|
||||
voit le dashboard *Journaux de la flotte*, mais **pas** l'icône Explore.
|
||||
2. **Donne Editor.** `testmail` a le rôle `grafana-editor` → **déconnecte/reconnecte-le** (Grafana
|
||||
applique le rôle *à la connexion*) → **Explore apparaît**.
|
||||
3. **Observe le claim.** Dans Keycloak (console admin) → Clients → grafana → *Client scopes* →
|
||||
*Evaluate* pour `testmail` : le jeton contient `"roles": ["grafana-editor"]`. C'est ② en vrai.
|
||||
4. **Casse & répare.** Retire `grafana-editor` de testmail (ou renomme-le en `grafana-viewer`),
|
||||
reconnecte : **Explore disparaît**. Remets-le : il revient. Tu *sens* que c'est **le rôle**, pas
|
||||
l'identité, qui ouvre la porte.
|
||||
|
||||
---
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- IdP : `roles/serveur_keycloak/tasks/rbac-oidc.yml` (rôles + mapper + assignations).
|
||||
- App : `roles/serveur_grafana` (`serveur_grafana_oidc_role_path`).
|
||||
- Le pendant *authentification* : unité **[Identité & SSO](Identité-et-SSO)**.
|
||||
|
|
@ -78,7 +78,32 @@ Encrypt, Vault, une AC d'entreprise : le schéma est **identique**.
|
|||
|
||||
---
|
||||
|
||||
## ⑤ Le renouvellement : un système à part entière *(leçon d'exploitation vécue)*
|
||||
|
||||
Un certificat **expire**. Les certs internes de Set-OPS (step-ca) sont **courts** (~24 h) — c'est
|
||||
plus sûr (une clé volée ne vaut pas longtemps), mais ça **exige un renouvellement automatique**
|
||||
fiable. Et attention à un piège vécu en vrai :
|
||||
|
||||
> **Renouveler le fichier ne suffit pas — il faut recharger le consommateur.** Un service (nginx,
|
||||
> postfix, dovecot, slapd) charge son cert **en mémoire au démarrage**. Si le renouvellement
|
||||
> réécrit le fichier mais **ne recharge pas** le service, celui-ci sert l'**ancien cert périmé**
|
||||
> alors que le fichier sur disque est frais. Symptôme trompeur : `openssl x509 -in fichier` dit
|
||||
> « valide », mais le service sert un cert **expiré**.
|
||||
|
||||
Diagnostic-réflexe : **comparer le cert servi au cert fichier**.
|
||||
```bash
|
||||
echo | openssl s_client -connect EDGE:443 -servername keycloak.lab… 2>/dev/null | openssl x509 -noout -enddate # SERVI
|
||||
openssl x509 -in /etc/step/certs/EDGE.crt -noout -enddate # FICHIER
|
||||
```
|
||||
Dans Set-OPS, `client_pki_reload_services` (par nœud) fait recharger les **vrais** consommateurs
|
||||
après chaque renouvellement — edge→nginx, mail→postfix/dovecot, annuaire→slapd. Fix d'urgence si
|
||||
ça arrive : `systemctl reload nginx` sur l'edge.
|
||||
|
||||
**Casse & répare** : sur l'edge, arrête le timer `cert-renewer@…`, laisse le cert expirer (ou
|
||||
force une horloge), observe le login SSO casser (échec TLS de l'échange OIDC), puis recharge nginx
|
||||
→ tout revient. Tu *sens* que la PKI ne vit que si le renouvellement **et** le rechargement tournent.
|
||||
|
||||
## Pour aller plus loin *(dépôt)*
|
||||
- Rôles : `roles/serveur_step_ca`, `roles/client_pki`.
|
||||
- Rôles : `roles/serveur_step_ca`, `roles/client_pki` (`client_pki_reload_services`).
|
||||
- Le motif « pont de certificat » (renouvellement automatique) : voir les tâches `*-cert-sync` des rôles (Dovecot, Postfix, nginx…).
|
||||
- Tier 0 des sauvegardes (`/etc/step-ca`) : unité **Sauvegardes**.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
*Fondations*
|
||||
- [Identité & SSO](Identité-et-SSO)
|
||||
- [Autorisation & RBAC](Autorisation-et-RBAC)
|
||||
- [PKI & confiance](PKI-et-confiance)
|
||||
- [DNS & résolution de noms](DNS-et-résolution)
|
||||
|
||||
|
|
@ -28,7 +29,7 @@
|
|||
- [Liaisons (bindings)](Liaisons-bindings)
|
||||
|
||||
**Opérations**
|
||||
- Runbooks *(à venir)*
|
||||
- Runbooks → dépôt `docs/runbooks-exploitation.md`
|
||||
|
||||
**Repères**
|
||||
- Glossaire *(à venir)*
|
||||
|
|
|
|||
Loading…
Reference in a new issue