icinga : l hote de supervision saturait par sa propre demonstration

« mon-01 tape dans l fond. » Il tapait : load 5,10 sur 4 coeurs, 8
processus check_disk a 70-99 % de CPU chacun, jusqu a 28 minutes de vie.

check_disk 2.4.0-3+deb13u1 ne rend jamais la main sur cet hote (etat R).
Icinga en relancait un a chaque intervalle pour le service `disk` de son
hote de DEMONSTRATION, et aucun ne mourait.

RETIRE : conf.d/hosts.conf, l hote NodeName livre par le paquet. Les apply
Service s y accrochaient — disk, http, swap, apt, load, procs, users — et
trois etaient rouges en permanence (swap sur une VM sans swap, http sur un
port ou rien n ecoute, apt pour un paquet). On retire l HOTE et non les
services : sans lui les apply ne s accrochent a rien, et on ne touche pas
a un fichier que le paquet remplacera. Ca garde ping4, qui vise nos hotes
et sert vraiment.

  avant : load 5,10 — 8 check_disk — 3 alarmes rouges permanentes
  apres : load 0,77 — 0 check_disk — certificat 14/14, sante 14/14, ping4 14/14

TROUVE EN VERIFIANT : l Icinga du SITE tenait 6 de ses 7 machines pour
MORTES (1/7 UP, contre 14/14 au tenant). hostalive est un ping, le site
est decoupe en zones, et l ICMP inter-zones n etait declare nulle part —
100 % de perte, mesure. Or Icinga SUPPRIME les notifications des services
d un hote DOWN : une supervision qui croit tout mort n alerte plus de
rien, tout en ayant l air de fonctionner.

Le flux est declare des DEUX cotes, et le registre a refuse la premiere
moitie seule — exactement sa raison d etre. CODES_ICMP apprend
echo-request. Regles d hote posees sur les 21 machines.

RESTE OUVERT : le generateur de la frontiere ne sait pas traduire un TYPE
ICMP pour un pair INTERNE — il le note et n emet rien. Le site reste a
1/7. Corriger devis_opnsense.py est le prochain geste.

make prouver : CONFORME, 64 OK, 0 echec, 0 saute.

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-09 22:34:32 -04:00
parent 988d35745e
commit a070c339ee
7 changed files with 134 additions and 3 deletions

View file

@ -1,5 +1,59 @@
# CHANGELOG — Set-OPS
## 2026-09-09 (8) — L'hote de supervision saturait par sa propre demonstration
« mon-01 tape dans l'fond. » Il tapait, en effet.
load average: 5,10 sur 4 coeurs
8 processus check_disk, 70 a 99 % de CPU chacun, jusqu'a 28 minutes de vie
`check_disk` 2.4.0-3+deb13u1 ne rend jamais la main sur cet hote (etat `R`, il boucle).
Icinga en relancait un a CHAQUE intervalle pour le service `disk` de son hote de
DEMONSTRATION, et aucun ne mourait. **L'hote de supervision etait sature par la
configuration d'exemple livree avec le paquet.**
### Ce qui a ete retire, et pourquoi l'hote plutot que les services
`conf.d/hosts.conf` definit `object Host NodeName` — un `localhost` de demonstration avec
`vars.disks`, `vars.http_vhosts`, `vars.os`. Les `apply Service` s'y accrochent : `disk`,
`http`, `swap`, `apt`, `load`, `procs`, `users`, `ssh`, `icinga`. Aucun ne decrit cet
ecosysteme, et trois etaient **rouges en permanence** — `swap` sur une VM sans swap, `http`
sur un port ou rien n'ecoute, `apt` pour un paquet a mettre a jour.
On retire l'HOTE, pas les services : sans lui les `apply` ne s'accrochent a rien, et on ne
touche pas a un fichier que le paquet remplacera a la prochaine mise a jour.
**Et ca garde ce qui servait** : `apply Service "ping4"` vise tout hote ayant une adresse,
donc les notres. Il est vert 14/14 au tenant. Retirer `services.conf` l'aurait emporte
avec le reste.
avant : load 5,10 — 8 check_disk — 3 alarmes rouges permanentes
apres : load 0,77 — 0 check_disk — certificat 14/14, sante 14/14, ping4 14/14
### Trouve en verifiant : la supervision du SITE croyait tout mort
hotes UP : 1/7 (site) 14/14 (tenant)
Nos `object Host` sont verifies par `hostalive`, c'est-a-dire un ping. Le site est decoupe
en zones separees ; l'ICMP inter-zones n'etait declare nulle part, donc la frontiere
l'avalait — 100 % de perte, mesure. Et **Icinga SUPPRIME les notifications des services
d'un hote DOWN** : une supervision qui croit tout mort n'alerte plus de rien, tout en ayant
l'air de fonctionner.
Le flux est desormais declare des DEUX cotes (`serveur_icinga` en egress, `serveur_debian`
en ingress) — et le registre a refuse la premiere moitie seule, ce qui est exactement sa
raison d'etre. `CODES_ICMP` apprend `echo-request` (un TYPE, pas un code de
destination-unreachable). Les regles d'hote sont posees sur les 21 machines.
**Ce qui reste ouvert, et je le dis parce que le probleme n'est pas resolu :** le
generateur de la frontiere ne sait pas traduire un TYPE ICMP pour un pair INTERNE. Il le
note et n'emet rien :
note : serveur_icinga declare un port `echo-request` que le plan du site ne resout pas
Le site reste donc a 1/7. Corriger `devis_opnsense.py` pour l'ICMP interne est le prochain
geste — et c'est un geste sur le generateur de la frontiere, pas une retouche.
## 2026-09-09 (7) — Le contrat des sondes ETAIT celui de Nagios, sans le savoir
Question posee : « tu connais le paquet `monitoring-plugins` ? »

View file

@ -21,7 +21,7 @@
| P06 | Validateurs de registres (serveurs/apps/bases/domaines) | AFF-003 | ✅ OK | Registre des domaines valide. |
| P07 | GUI (node --check) | AFF-033 | ✅ OK | JS du GUI : syntaxe valide (node --check), 1 nom(s) surveille(s) sans reference orpheline. |
| P08 | Orchestration (couches + graphe) | AFF-070 | ✅ OK | Orchestration coherente : 41 groupes classes, aucun cycle, aucune arete en arriere. |
| P09 | Flux reseau (schema + matrice) | AFF-071 | ✅ OK | Flux coherents : 39 rôles, 101 flux, schéma + matrice OK. |
| P09 | Flux reseau (schema + matrice) | AFF-071 | ✅ OK | Flux coherents : 39 rôles, 103 flux, schéma + matrice OK. |
| P10 | Handlers <-> notify | AFF-034, AFF-035 | ✅ OK | Tout notify pointe vers un handler du meme role (49 roles). |
| P11 | Syntaxe des playbooks (--syntax-check) | AFF-083 | ✅ OK | serveur_resolveur_site |
| P12 | Existence des runbooks cites | AFF-010, AFF-011, AFF-012, AFF-083 | ✅ OK | 17/17 runbooks/registres cites presents. |
@ -61,7 +61,7 @@
| P46 | Plancher /etc/hosts : un seul role en decide | — | ✅ OK | Un seul maitre du plancher — roles/hosts_statiques/tasks/main.yml : manage_etc_hosts: false ; et le gabarit maitre est pose (roles/hosts_statiques/templates/hos |
| P47 | Zones inverses : couvrir l'occupe, et rien de plus | — | ✅ OK | Les zones inverses couvrent l'occupe et rien de plus (5 cas evalues, dont un site a quatre zones et un tenant a une). |
| P48 | La carte d'orientation designe ce qui existe, et compte juste | — | ✅ OK | La carte designe 89 chemin(s) qui existent, et ses 7 chiffres correspondent a la mesure. |
| P49 | Registre des flux : la matrice d'audit est a jour | — | ✅ OK | Le registre des flux reproduit exactement ce que les `meta/flux.yml` declarent (119 lignes). |
| P49 | Registre des flux : la matrice d'audit est a jour | — | ✅ OK | Le registre des flux reproduit exactement ce que les `meta/flux.yml` declarent (121 lignes). |
| P50 | Silences : un refus muet est declare, place en dernier, et motive | — | ✅ OK | 2 silence(s) declare(s), tous en sequence > 1 (la plus haute des 175 regles `pass`), tous non consignes et tous motives. |
| P51 | Collections : toutes declarees, toutes epinglees | — | ✅ OK | 3 collection(s) et 2 bibliotheque(s) Python declarees et epinglees : ansible.posix==1.6.2, community.general==10.3.0, community.postgresql==3.10.2 |
| P52 | Materialiser n'exige pas d'entrer dans le tenant | — | ✅ OK | `creer-vm` confirme par l'agent invite (API des hyperviseurs, deja utilisee pour creer), sans exiger d'entrer dans le tenant. |

View file

@ -27,6 +27,7 @@
| `serveur_collabora` | ingress | 9980 | tcp | edge | clair | Éditeur servi au navigateur via l'edge (WebSocket WOPI ; TLS terminé à l'edge). |
| `serveur_collabora` | ingress | 9980 | tcp | localhost | clair | Vérifications WOPI serveur→Collabora depuis Nextcloud co-localisé. |
| `serveur_debian` | ingress | 22 | tcp | flotte, externe | ssh | Plan de gestion : administration et déploiement Ansible par SSH (inter-nœud ; l'accès depuis l'extérieur est filtré à l'OPNsense). |
| `serveur_debian` | ingress | echo-request | icmp | serveur_icinga | n-a | La supervision verifie que ce noeud repond (hostalive). Sans lui, elle le tient pour mort et supprime ses notifications. |
| `serveur_debian` | ingress | frag-needed | icmp | externe | n-a | ICMP « fragmentation nécessaire » entrant : sans lui, un distant ne peut pas nous demander de réduire nos paquets — les transferts se figent. |
| `serveur_debian` | egress | 80 | tcp | externe | clair | Dépôts apt en clair et redirections HTTP des miroirs (l'intégrité vient de la signature des paquets, pas du transport). |
| `serveur_debian` | egress | 123 | udp | externe | n-a | Synchronisation d'horloge (NTP). Une dérive fait échouer la validation des certificats step-ca et l'authentification SSO. |
@ -49,6 +50,7 @@
| `serveur_icinga` | ingress | 5665 | tcp | serveur_backup | tls-requis | Le depot de sauvegarde depose ses resultats passifs (portee : process-check-result sur « sauvegarde: * »). |
| `serveur_icinga` | ingress | 5665 | tcp | serveur_debian | tls-requis | Rapport passif de sante de chaque noeud (unites systemd en echec). |
| `serveur_icinga` | egress | 5432 | tcp | serveur_postgresql | tls-requis | Base relationnelle du moteur Icinga (verify-full). |
| `serveur_icinga` | egress | echo-request | icmp | serveur_debian | n-a | La supervision verifie que ses hotes repondent (hostalive) : sans ce flux, elle les tient tous pour morts et supprime leurs notifications. |
| `serveur_icingaweb2` | ingress | 8080 | tcp | edge | clair | Interface web servie via l'edge (TLS terminé à l'edge ; SSO possible via oauth2-proxy). |
| `serveur_icingaweb2` | egress | 636 | tcp | serveur_openldap | tls-requis | Authentification des utilisateurs sur l'annuaire (LDAPS). |
| `serveur_icingaweb2` | egress | 5432 | tcp | serveur_postgresql | tls-requis | Lecture d'IcingaDB (base relationnelle, verify-full). |
@ -111,7 +113,7 @@
## Synthèse chiffrement
- **clair** : 37 flux
- **n-a** : 3 flux
- **n-a** : 5 flux
- **ssh** : 8 flux
- **starttls** : 6 flux
- **tls** : 10 flux

View file

@ -42,6 +42,19 @@ flux:
chiffrement: n-a
raison: "ICMP « fragmentation nécessaire » sortant : c'est ainsi que nos hôtes signalent l'overlay à 1450 aux correspondants distants."
# LA FACE RECEPTRICE DU PING DE SUPERVISION.
#
# `serveur_icinga` declare l'egress ; le registre REFUSE un egress sans son ingress en
# face, et il a bien fait : c'est precisement l'oubli qui a coute cinq `TimeoutError`
# sur le rapport de sante quelques heures plus tot. Ici la garde l'a dit tout de suite.
- sens: ingress
port: echo-request
protocole: icmp
pair: serveur_icinga
chiffrement: n-a
partage: true
raison: "La supervision verifie que ce noeud repond (hostalive). Sans lui, elle le tient pour mort et supprime ses notifications."
- sens: egress
port: 123
protocole: udp

View file

@ -64,6 +64,32 @@ flux:
chiffrement: tls-requis
partage: true
raison: "Rapport passif de sante de chaque noeud (unites systemd en echec)."
# LA SUPERVISION DOIT POUVOIR JOINDRE CE QU'ELLE SUPERVISE (mesure du 2026-09-09).
#
# Nos `object Host` sont verifies par `hostalive`, c'est-a-dire un ping. Sans ce flux,
# l'Icinga du SITE tenait 6 de ses 7 machines pour MORTES — et Icinga SUPPRIME les
# notifications des services d'un hote DOWN. Une supervision qui croit tout mort
# n'alerte plus de rien : c'est pire que pas de supervision, parce qu'elle a l'air de
# fonctionner.
#
# Les hotes acceptent deja tout l'ICMP localement (`serveur_debian`) ; c'est la
# FRONTIERE qui filtre l'inter-zones, et elle ne connait que ce qui est declare. Le
# tenant ne le voyait pas : ses zones se parlent deja. Le site, decoupe en pattes
# separees, non.
#
# Le pair est `serveur_debian` — tout noeud — pour la meme raison que le rapport de
# sante : une integration universelle n'est pas un role porte au plan, et la frontiere
# ne resout que les roles portes.
#
# CE QUE CE PING APPORTE, malgre le `ttl` qui fait deja parler le silence : un signal
# INDEPENDANT du chemin de rapport. Si le rapport passif casse, le ping le distingue
# d'une machine reellement tombee.
- sens: egress
port: echo-request
protocole: icmp
pair: serveur_debian
chiffrement: n-a
raison: "La supervision verifie que ses hotes repondent (hostalive) : sans ce flux, elle les tient tous pour morts et supprime leurs notifications."
- sens: egress
port: 5432
protocole: tcp

View file

@ -219,6 +219,36 @@
# LES HOTES D'ABORD : les fichiers de service s'y attachent, et Icinga refuse un service
# dont l'hote n'existe pas. L'ordre dans `conf.d` n'est pas garanti par le nom, mais
# Icinga charge tout le repertoire avant de resoudre — l'ordre de deploiement suffit.
# L'HOTE D'EXEMPLE LIVRE PAR ICINGA : RETIRE (mesure du 2026-09-09).
#
# `conf.d/hosts.conf` definit `object Host NodeName` — un `localhost` de demonstration
# avec `vars.disks`, `vars.http_vhosts`, `vars.os`. Les `apply Service` de
# `conf.d/services.conf` s'y accrochent : `disk`, `http`, `swap`, `apt`, `load`, `procs`,
# `users`. Aucun ne decrit cet ecosysteme, et trois etaient ROUGES EN PERMANENCE :
#
# swap : SWAP CRITICAL - 0% free (une VM sans swap)
# http : connect to 127.0.0.1:80 (rien n'ecoute la)
# apt : 1 package upgradable
#
# Trois alarmes qui ne peuvent que rester rouges, dans le seul endroit qui doit rester
# lisible. C'est deja une raison suffisante — une supervision creuse est pire qu'aucune.
#
# MAIS LE QUATRIEME NE FAISAIT PAS QUE MENTIR, IL NUISAIT. `check_disk`
# 2.4.0-3+deb13u1 ne rend jamais la main sur cet hote (etat `R`, boucle, quels que soient
# ses arguments). Icinga en relancait un a CHAQUE intervalle, et aucun ne mourait :
#
# 8 processus check_disk, 70 a 99 % de CPU chacun, jusqu'a 28 minutes de vie
# charge 5,10 sur 4 coeurs — l'hote de supervision sature par sa propre demonstration
#
# On retire l'HOTE plutot que les services : sans lui, les `apply` ne s'accrochent a rien,
# et on ne touche pas a un fichier que le paquet remplacera a la prochaine mise a jour.
# Les hotes de cet ecosysteme sont declares par `setops-hotes.conf`.
- name: Retirer l'hote de demonstration livre par Icinga
ansible.builtin.file:
path: /etc/icinga2/conf.d/hosts.conf
state: absent
notify: Redemarrer icinga2
# LES SONDES DECLAREES PAR LES ROLES (docs/supervision-conception.md).
#
# On lit les `meta/supervision.yml` sur le CONTROLEUR, pas sur la cible : c'est le depot

View file

@ -332,6 +332,12 @@ def _supernets_voisins() -> list[str]:
# au lieu d'en gagner une. Constate le 2026-08-06 sur les 14 hotes a la fois.
CODES_ICMP = {
"frag-needed": "icmp type destination-unreachable icmp code frag-needed",
# `echo-request` est un TYPE, pas un code de destination-unreachable — d'ou l'absence
# de `icmp code` ici. La supervision s'en sert pour `hostalive` : sans ce flux,
# l'Icinga du site tenait 6 de ses 7 machines pour mortes, et Icinga SUPPRIME les
# notifications des services d'un hote DOWN. Une supervision qui croit tout mort
# n'alerte plus de rien (2026-09-09).
"echo-request": "icmp type echo-request",
}