supervision : le lot check_http, et les greffons qui manquaient a la flotte

La doctrine dit qu un greffon Nagios EST une sonde valide et compte sur les 54
de monitoring-plugins. Mesure : aucun n etait installe. Le document decrivait
une possibilite qui n existait pas, et chaque role ayant besoin d un controle
HTTP n avait d autre choix que d ecrire du shell.

Le PORTEUR les installe desormais — c est son affaire de pouvoir executer des
sondes, et les poser role par role en ferait autant de copies de la decision.

Trois sondes, trois enveloppes qui delegue a check_http et rendent son code tel
quel :

  collabora    edition     /hosting/discovery — l adresse que Nextcloud interroge
                           lui-meme ; sans elle le bouton ouvrir meurt et
                           Nextcloud reste vert
  rspamd       filtrage    un filtre muet ne bloque pas le courrier, il le laisse
                           passer
  oauth2_proxy passerelle  ce qui tombe avec elle n est pas elle : les services
                           derriere restent debout et deviennent injoignables

Chacune exige une CHAINE que seul le bon service produit — un 200 peut venir
d une page d erreur. Cette chaine est aussi la mise en defaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
This commit is contained in:
Daniel Allaire 2026-09-14 09:34:31 -04:00
parent af93a4129e
commit f815b069f7
15 changed files with 236 additions and 3 deletions

View file

@ -76,7 +76,7 @@
| P61 | Schema du plan : il decrit tout ce que les plans contiennent | AFF-033 | ✅ OK | Le schema decrit 47 champ(s) sur 6 registres ; il couvre tout ce que les plans reels contiennent, et la FORME de chaque champ (scalaire / objet / table) corresp |
| P62 | Schema du plan : il decrit tout ce que le MOTEUR accepte | AFF-033 | ✅ OK | Les 4 validateurs n'acceptent aucun champ que le schema ignore (applications:8, bases_donnees:4, domaines_publics:5, serveurs:3 champ(s) lus par validateur). |
| P63 | cloud-init nait avec la VM et ne lui survit pas | — | ✅ OK | cloud-init est au gabarit (la premiere seconde), absent du socle (pas de va-et-vient), et retire par le durcissement — avec la garde qui verifie que le reseau s |
| P64 | Sondes de supervision : declarees ET deposees | — | ✅ OK | 27 sonde(s) declaree(s) ET deposee(s), chacune avec sa raison et son `ttl` : client_journal/journaux, client_metrique/metriques, client_pki/certificat, serveur_ |
| P64 | Sondes de supervision : declarees ET deposees | — | ✅ OK | 30 sonde(s) declaree(s) ET deposee(s), chacune avec sa raison et son `ttl` : client_journal/journaux, client_metrique/metriques, client_pki/certificat, serveur_ |
| P65 | Depots tiers : demandes au cache, jamais en HTTPS direct | — | ✅ OK | 4 depot(s) tiers relaye(s) par le cache, aucun role ne les vise en https:// ecrit en dur. |
| P66 | Clients OIDC : chaque URI vise un nom que le plan expose | — | ✅ OK | 4 client(s) OIDC, toutes leurs URI visent un FQDN que le plan expose (6 exposition(s)). |
| P67 | Nom public : le service porte celui du plan, pas celui du role | — | ✅ OK | 6 service(s) expose(s) portent le nom du plan (6 groupe(s) derive(s)). |

View file

@ -55,3 +55,11 @@ client_sante_ttl_sondes: 5400
# Delai de garde de CHAQUE sonde. Une sonde est cense repondre vite ; celle qui depasse
# n'a pas de verdict, et on le dit (INCONNU) plutot que de figer tout le rapport.
client_sante_delai_sonde: 20
# CE QUE LE PORTEUR INSTALLE. `curl` pousse le resultat vers l'API d'Icinga ;
# `monitoring-plugins-basic` apporte les greffons standard que les roles reutilisent au
# lieu d'ecrire du shell (voir docs/supervision-conception.md). Ils vivent dans
# `/usr/lib/nagios/plugins/`.
client_sante_paquets:
- curl
- monitoring-plugins-basic

View file

@ -67,9 +67,25 @@
group: root
mode: "0644"
- name: Installer curl pour le rapport passif
# LES GREFFONS STANDARD, POSES PAR LE PORTEUR ET PAS PAR CHAQUE ROLE (2026-09-14).
#
# `docs/supervision-conception.md` dit qu'un greffon Nagios EST une sonde valide, « sans
# la moindre colle », et compte sur les 54 que fournit `monitoring-plugins`. Mesure du
# 2026-09-14 sur la flotte : **aucun n'etait installe**. Le document decrivait une
# possibilite qui n'existait pas — et chaque role qui avait besoin d'un controle HTTP
# n'avait d'autre choix que d'ecrire du shell, exactement ce que la doctrine refuse.
#
# ICI, ET PAS DANS CHAQUE ROLE. C'est l'affaire du PORTEUR de pouvoir executer des
# sondes ; les poser role par role en installerait autant de copies de la decision, et
# laisserait sans greffon les machines dont aucun role n'en reclame — alors qu'elles en
# ont tout autant besoin le jour ou on leur en ajoute un.
#
# 1,2 Mo par machine, pour `check_http`, `check_tcp`, `check_disk`, `check_procs`,
# `check_ntp_time`, `check_file_age`… et vingt ans de cas limites deja rencontres par
# d'autres.
- name: Installer les outils du rapport passif et les greffons standard
ansible.builtin.apt:
name: curl
name: "{{ client_sante_paquets }}"
state: present
# --- UN ROLE QU'ON RETIRE DOIT POUVOIR DEFAIRE CE QU'IL A FAIT (2026-09-10) -----------

View file

@ -91,3 +91,14 @@ serveur_collabora_admin_mot_de_passe: ""
# le chemin, `https` sinon. Voir `serveur_artefacts_remaps` pour la moitie qui relaie.
serveur_collabora_depot_schema: >-
{{ 'http' if (artefacts_amorcage | default('') | string | length > 0) else 'https' }}
# --- SONDE DE SUPERVISION -------------------------------------------------------------
#
# CE QUE LA REPONSE DOIT CONTENIR. Un code 200 ne suffit pas : un serveur peut rendre 200
# sur une page d'erreur, une redirection de courtoisie ou un cache perime. On exige donc
# une chaine que SEUL le bon service produit.
#
# C'EST AUSSI LA MISE EN DEFAUT DE LA SONDE : y mettre une chaine introuvable la rend
# CRITIQUE sans rien casser, ce qui rend la seconde preuve REJOUABLE. Une sonde se prouve
# deux fois — verte sur le sain, rouge sur le casse.
serveur_collabora_sonde_attendu: "wopi-discovery"

View file

@ -0,0 +1,21 @@
---
# Supervision derivee du role. Voir docs/supervision-conception.md.
#
# UNE SEULE SONDE, une seule CAUSE D'ACTION : aller voir collabora.
#
# `/hosting/discovery` n'est pas une page de complaisance : c'est l'adresse que Nextcloud
# interroge LUI-MEME pour savoir quels documents Collabora sait ouvrir. Si elle ne repond
# plus, le bouton « ouvrir » cesse de fonctionner pour tout le monde — et Nextcloud, lui,
# reste parfaitement vert.
#
# LA SONDE EST UN GREFFON STANDARD (`check_http`), pas du shell : la verite a mesurer
# n'a rien de propre a Set-OPS — c'est « ce service HTTP repond-il ce qu'il doit ».
#
# TTL de 5400 s pour un porteur qui passe aux 15 min : trois passages manques avant la
# peremption. Le silence alerte autant que l'echec.
sondes:
- nom: edition
ttl: 5400
raison: 'L''edition en ligne repond-elle ? `/hosting/discovery` est l''adresse que Nextcloud
interroge lui-meme pour savoir quels documents Collabora sait ouvrir. Sans elle, le
bouton « ouvrir » cesse de fonctionner pour tout le monde — et Nextcloud reste vert.'

View file

@ -202,3 +202,21 @@
retries: 12
delay: 5
until: serveur_collabora_capacites is succeeded
# LE ROLE QUI POSSEDE LA VERITE DEPOSE SA PROPRE SONDE. `client_sante` la fait tourner et
# pousse le resultat ; les greffons standard, eux, sont poses par le porteur.
- name: Assurer le repertoire des sondes de supervision
ansible.builtin.file:
path: /usr/local/lib/setops/sondes
state: directory
owner: root
group: root
mode: "0755"
- name: Deposer la sonde « edition »
ansible.builtin.template:
src: sonde-edition.sh.j2
dest: /usr/local/lib/setops/sondes/edition.sh
owner: root
group: root
mode: "0750"

View file

@ -0,0 +1,21 @@
#!/bin/bash
# GENERE par Set-OPS (role serveur_collabora). Ne pas editer a la main.
#
# SONDE « edition » — L'edition en ligne repond-elle ?
#
# UNE ENVELOPPE, PAS UNE SONDE ECRITE A LA MAIN. `check_http` vient de
# `monitoring-plugins` : il parle deja l'API des greffons Nagios, gere les delais, les
# redirections et vingt ans de cas limites. On lui passe l'adresse et ce qu'on attend, et
# on rend SON code de sortie tel quel. Ecrire du shell ici serait se donner du code a
# maintenir et se priver de tout ca — voir docs/supervision-conception.md.
#
# `/hosting/discovery` n'est pas une page de complaisance : c'est l'adresse que Nextcloud
# interroge LUI-MEME pour savoir quels documents Collabora sait ouvrir. Si elle ne repond
# plus, le bouton « ouvrir » cesse de fonctionner pour tout le monde — et Nextcloud, lui,
# reste parfaitement vert.
#
# Mise en defaut PAR PARAMETRE : `serveur_collabora_sonde_attendu` (chaine introuvable).
exec /usr/lib/nagios/plugins/check_http \
-H 127.0.0.1 -p {{ serveur_collabora_port }} -u '/hosting/discovery' \
-s '{{ serveur_collabora_sonde_attendu }}' \
-t 8

View file

@ -58,3 +58,14 @@ serveur_oauth2_proxy_ca_bundle: "/etc/ssl/certs/ca-certificates.crt"
# puis pousse par SSH : aucun flux nouveau, et l'artefact devient deployable hors ligne.
# Surchargeable par `setops_cache_artefacts` pour partager un cache commun.
serveur_oauth2_proxy_cache_local: "{{ setops_cache_artefacts | default(lookup('env', 'HOME') + '/.cache/setops') }}"
# --- SONDE DE SUPERVISION -------------------------------------------------------------
#
# CE QUE LA REPONSE DOIT CONTENIR. Un code 200 ne suffit pas : un serveur peut rendre 200
# sur une page d'erreur, une redirection de courtoisie ou un cache perime. On exige donc
# une chaine que SEUL le bon service produit.
#
# C'EST AUSSI LA MISE EN DEFAUT DE LA SONDE : y mettre une chaine introuvable la rend
# CRITIQUE sans rien casser, ce qui rend la seconde preuve REJOUABLE. Une sonde se prouve
# deux fois — verte sur le sain, rouge sur le casse.
serveur_oauth2_proxy_sonde_attendu: "OK"

View file

@ -0,0 +1,20 @@
---
# Supervision derivee du role. Voir docs/supervision-conception.md.
#
# UNE SEULE SONDE, une seule CAUSE D'ACTION : aller voir oauth2_proxy.
#
# CE QUI TOMBE AVEC ELLE N'EST PAS ELLE. Cette passerelle porte l'acces aux applications
# qui n'ont pas de SSO natif — la supervision la premiere. Quand elle meurt, les services
# derriere restent debout et deviennent injoignables : on cherche la panne du mauvais cote.
#
# LA SONDE EST UN GREFFON STANDARD (`check_http`), pas du shell : la verite a mesurer
# n'a rien de propre a Set-OPS — c'est « ce service HTTP repond-il ce qu'il doit ».
#
# TTL de 5400 s pour un porteur qui passe aux 15 min : trois passages manques avant la
# peremption. Le silence alerte autant que l'echec.
sondes:
- nom: passerelle
ttl: 5400
raison: 'La passerelle d''authentification repond-elle ? Elle porte l''acces aux applications sans
SSO natif — la supervision la premiere. Quand elle meurt, les services derriere restent
debout et deviennent injoignables : on cherche la panne du mauvais cote.'

View file

@ -171,3 +171,21 @@
enabled: true
state: started
daemon_reload: true
# LE ROLE QUI POSSEDE LA VERITE DEPOSE SA PROPRE SONDE. `client_sante` la fait tourner et
# pousse le resultat ; les greffons standard, eux, sont poses par le porteur.
- name: Assurer le repertoire des sondes de supervision
ansible.builtin.file:
path: /usr/local/lib/setops/sondes
state: directory
owner: root
group: root
mode: "0755"
- name: Deposer la sonde « passerelle »
ansible.builtin.template:
src: sonde-passerelle.sh.j2
dest: /usr/local/lib/setops/sondes/passerelle.sh
owner: root
group: root
mode: "0750"

View file

@ -0,0 +1,20 @@
#!/bin/bash
# GENERE par Set-OPS (role serveur_oauth2_proxy). Ne pas editer a la main.
#
# SONDE « passerelle » — La passerelle d'authentification repond-elle ?
#
# UNE ENVELOPPE, PAS UNE SONDE ECRITE A LA MAIN. `check_http` vient de
# `monitoring-plugins` : il parle deja l'API des greffons Nagios, gere les delais, les
# redirections et vingt ans de cas limites. On lui passe l'adresse et ce qu'on attend, et
# on rend SON code de sortie tel quel. Ecrire du shell ici serait se donner du code a
# maintenir et se priver de tout ca — voir docs/supervision-conception.md.
#
# CE QUI TOMBE AVEC ELLE N'EST PAS ELLE. Cette passerelle porte l'acces aux applications
# qui n'ont pas de SSO natif — la supervision la premiere. Quand elle meurt, les services
# derriere restent debout et deviennent injoignables : on cherche la panne du mauvais cote.
#
# Mise en defaut PAR PARAMETRE : `serveur_oauth2_proxy_sonde_attendu` (chaine introuvable).
exec /usr/lib/nagios/plugins/check_http \
-H 127.0.0.1 -p 4180 -u '/ping' \
-s '{{ serveur_oauth2_proxy_sonde_attendu }}' \
-t 8

View file

@ -21,3 +21,14 @@ serveur_rspamd_dkim_actif: true
serveur_rspamd_dkim_domaine: "{{ domaine_interne }}"
serveur_rspamd_dkim_selecteur: "setops"
serveur_rspamd_dkim_repertoire: "/var/lib/rspamd/dkim"
# --- SONDE DE SUPERVISION -------------------------------------------------------------
#
# CE QUE LA REPONSE DOIT CONTENIR. Un code 200 ne suffit pas : un serveur peut rendre 200
# sur une page d'erreur, une redirection de courtoisie ou un cache perime. On exige donc
# une chaine que SEUL le bon service produit.
#
# C'EST AUSSI LA MISE EN DEFAUT DE LA SONDE : y mettre une chaine introuvable la rend
# CRITIQUE sans rien casser, ce qui rend la seconde preuve REJOUABLE. Une sonde se prouve
# deux fois — verte sur le sain, rouge sur le casse.
serveur_rspamd_sonde_attendu: "pong"

View file

@ -0,0 +1,20 @@
---
# Supervision derivee du role. Voir docs/supervision-conception.md.
#
# UNE SEULE SONDE, une seule CAUSE D'ACTION : aller voir rspamd.
#
# UN FILTRE MUET NE BLOQUE PAS LE COURRIER — IL LE LAISSE PASSER. Postfix qui n'obtient
# pas de verdict de rspamd delivre sans filtrer, ou differe : dans les deux cas le service
# de courriel a l'air sain pendant que le pourriel entre ou que la file grossit.
#
# LA SONDE EST UN GREFFON STANDARD (`check_http`), pas du shell : la verite a mesurer
# n'a rien de propre a Set-OPS — c'est « ce service HTTP repond-il ce qu'il doit ».
#
# TTL de 5400 s pour un porteur qui passe aux 15 min : trois passages manques avant la
# peremption. Le silence alerte autant que l'echec.
sondes:
- nom: filtrage
ttl: 5400
raison: 'Le filtrage du courrier repond-il ? Un filtre muet ne bloque pas le courrier, il le
laisse passer : Postfix sans verdict delivre sans filtrer ou differe, et le service de
courriel a l''air sain pendant que le pourriel entre.'

View file

@ -80,3 +80,21 @@
name: "{{ serveur_rspamd_service }}"
enabled: true
state: started
# LE ROLE QUI POSSEDE LA VERITE DEPOSE SA PROPRE SONDE. `client_sante` la fait tourner et
# pousse le resultat ; les greffons standard, eux, sont poses par le porteur.
- name: Assurer le repertoire des sondes de supervision
ansible.builtin.file:
path: /usr/local/lib/setops/sondes
state: directory
owner: root
group: root
mode: "0755"
- name: Deposer la sonde « filtrage »
ansible.builtin.template:
src: sonde-filtrage.sh.j2
dest: /usr/local/lib/setops/sondes/filtrage.sh
owner: root
group: root
mode: "0750"

View file

@ -0,0 +1,20 @@
#!/bin/bash
# GENERE par Set-OPS (role serveur_rspamd). Ne pas editer a la main.
#
# SONDE « filtrage » — Le filtrage du courrier repond-il ?
#
# UNE ENVELOPPE, PAS UNE SONDE ECRITE A LA MAIN. `check_http` vient de
# `monitoring-plugins` : il parle deja l'API des greffons Nagios, gere les delais, les
# redirections et vingt ans de cas limites. On lui passe l'adresse et ce qu'on attend, et
# on rend SON code de sortie tel quel. Ecrire du shell ici serait se donner du code a
# maintenir et se priver de tout ca — voir docs/supervision-conception.md.
#
# UN FILTRE MUET NE BLOQUE PAS LE COURRIER — IL LE LAISSE PASSER. Postfix qui n'obtient
# pas de verdict de rspamd delivre sans filtrer, ou differe : dans les deux cas le service
# de courriel a l'air sain pendant que le pourriel entre ou que la file grossit.
#
# Mise en defaut PAR PARAMETRE : `serveur_rspamd_sonde_attendu` (chaine introuvable).
exec /usr/lib/nagios/plugins/check_http \
-H 127.0.0.1 -p 11334 -u '/ping' \
-s '{{ serveur_rspamd_sonde_attendu }}' \
-t 8