Icinga Web 2 gagne un troisieme mode, locale : nginx authentifie en HTTP Basic
et pose REMOTE_USER, l application le croit. Un SITE n a ni annuaire ni Keycloak
— ce sont des services d ecosysteme. Ni backend LDAP ni backend de groupes : un
backend qui vise une ressource inexistante fait echouer chaque ouverture de
session. L habilitation nomme alors une personne, entorse a D-66 ecrite plutot
que contournee.
Deux pieges en chemin : resoudre_annuaire etait appele sans condition et tombait
sur NoneType has no len (default sans son second argument ne remplace pas None),
et le flux du role ne nommait que l edge — le site n en a pas, donc personne ne
pouvait entrer. serveur_grafana portait deja la reponse.
LE DEFAUT DU DEVIS : une sortie vers un role ABSENT de l ecosysteme retombait
sur !SETOPS_INTERNES, la forme de vers l Internet. La frontiere aurait autorise
la console a parler LDAPS a n importe quelle machine du monde, pour joindre un
annuaire qui n existe pas. C est une source vide ouvre le port, cote
destination. Trois regles du meme defaut etaient DEJA posees pour postfix.
La frontiere n est pas ecrite : elle porte la production, et le devis attend un
mot.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
La supervision du SITE etait morte depuis 11:10 et rien ne le disait. icingadb
refuse par pg_hba — hostssl impose cote serveur, connexion en clair cote client.
icinga2 tournait, redis tournait, les sondes poussaient, et rien n atteignait la
base : les verdicts se calculaient dans le vide.
La cause est une seconde liste tenue a la main. tls_force allume hostssl ; chaque
consommateur avait SON interrupteur a allumer dans les group_vars. Chezlepro
avait les trois, le site avait le premier. serveur_forgejo disait pire que rien :
sslmode disable ecrit en dur, le contraire de ce que le serveur imposait.
resoudre_base expose resoudre_base_db_tls_force, lu dans les hostvars de la
machine qui PORTE la base. Les trois interrupteurs en derivent. Un serveur qui
ne declare rien ne force rien : on ne casse pas un ecosysteme qui n a pas
bascule.
P78 refuse une valeur ecrite chez un consommateur, et nomme les deux roles sans
reglage TLS plutot que de rendre un vert muet sur eux.
Apres : icingadb active, TLSv1.3 vu par PostgreSQL, 16 hotes et 88 services en
base. Les cinq sondes des marqueurs du site, INCONNU faute de deploiement,
rapportent leur phrase.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Le plan du site expose observatoire.genese.internal ; serveur_grafana devinait
grafana.<domaine>. Grafana fabriquait son root_url, ses liens d alerte et son
URL de retour OIDC avec un nom que rien ne sert.
C est mot pour mot le defaut du 2026-09-10, quatre jours plus tard, de l autre
cote : instancier derive <groupe>_hostname depuis ce jour-la et P67 le garde,
mais tous deux ne connaissent que l instance montee — donc un locataire.
L inventaire du site n en derivait aucun. Quatre devinettes sur cinq tombaient
juste par convention, et c est ce qui rendait le defaut invisible.
site_inventaire.py derive les cinq noms du plan. P67 lit maintenant les deux
inventaires — celui du site est dynamique, donc elle l EXECUTE au lieu de lire
sa source. Eprouvee dans les deux sens : 10 services sur 2 inventaires.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Le gabarit de voute reclamait cette cle pour serveur_postgresql ; la voute reelle
du site ne l avait pas. Le gabarit disait quoi mettre, personne ne l avait mis.
40 caracteres alphanumeriques : le mot de passe entre dans une URI de connexion
PostgreSQL, et un @ ou un / y couperait l URI en deux — l echec dirait mauvais
mot de passe au lieu d URI mal formee.
Gardes passees : copie de surete, dechiffrement vers un FICHIER jamais vers un
tube, relecture du YAML, en-tete verifie apres, empreinte comparee, 15 cles
relues, clair passe au shred. Le premier rechiffrement produisait du 1.2
etiquete la ou la voute portait du 1.1 — refait sans etiquette, parce que le
runner du site ouvre avec un unique fichier-cle.
Compte setops_metriques : ni superuser, ni createdb, ni createrole, membre de
pg_monitor et rien d autre.
Les huit panneaux des deux tableaux derives repondent, mesures sur le site.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Le tableau des panneaux vivait DANS la condition de l exportateur. Le premier
role a declarer des panneaux sans exportateur — client_metrique, dont le job
node est universel — affichait « aucun exportateur declare » et cachait ses
quatre panneaux.
Une fiche qui tait ce qu un role declare est pire qu une fiche absente : elle
affirme que rien n existe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
La moitie qui manquait. Les roles declaraient leurs panneaux, Prometheus en
derivait ses cibles, les expressions repondaient, et rien ne les assemblait.
serveur_grafana lit les memes meta/metriques.yml que serveur_prometheus et en
assemble un tableau par role — la raison du panneau devient sa description dans
Grafana. Moisson des tableaux orphelins, prefixe setops-role- pour ne jamais
toucher un tableau ecrit a la main, JSON valide avant d etre pose (Grafana ne
tombe pas sur un tableau illisible : il le saute en silence).
client_metrique declare quatre panneaux sans exportateur — le cas symetrique.
Celui qui compte : la memoire disponible, depuis que le ballon est actif.
Eprouve sur le site : les deux tableaux charges dans le stockage unifie, un
temoin orphelin retire, les quatre panneaux de flotte a 10 series chacun.
Un panneau etait faux — /var/lib/lxcfs rapporte toujours zero octet libre et un
min() en meurt. Corrige en liste blanche : un montage inconnu manque au graphe,
ce qui se voit, au lieu de l ecraser.
P77 garde la table des unites : une unite inventee retombe sur short, lisible et
fausse. 76 OK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
La cible lisait $$remote — une variable de shell que rien ne definit — au lieu
de $(WIKI_REMOTE). L echappatoire que le message d erreur proposait lui-meme
n existait pas.
WIKI_BRANCHE, deux cibles plus bas, etait ecrit correctement depuis le debut.
Une option qui se lit autrement que sa voisine est l endroit ou regarder.
Wiki publie sur eregion : 95 pages, les huit fiches neuves portent leur sonde —
verifie en clonant la forge, pas en lisant le temoin.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Les 33 roles serveur_* declarent maintenant une sonde. Les huit qui manquaient
sont ceux dont la verite ne ressemble pas a « ce service repond-il ».
Quatre marqueurs du site : ce que tasks/main.yml verifie UNE FOIS au deploiement
cesse d etre vrai sans que rien ne tombe. La racine du cache se retrouve chainee,
la forge du genome repond en n ayant plus rien dedans, un locataire n est plus
admis a resoudre, l isolation d un depot glisse.
serveur_ops_site ne sert rien : il detient un pouvoir. La sonde verifie que la
carte est la, que la voute du site est chiffree et que sa cle est en 0600 — sans
lire le contenu d aucun des trois.
serveur_icingaweb2 surveille la vitrine de la supervision elle-meme : si la
console meurt, tout reste vert et l exploitant est aveugle.
DEFAUT 1 — quatre gabarits qu Ansible aurait refuse de rendre. Jinja lit le
{# de ${#tableau[@]} comme un debut de commentaire. Le depot connaissait le
remede et l appliquait la ou quelqu un s etait fait prendre, nulle part ailleurs.
P76 rend desormais chaque gabarit de role, avec les delimiteurs qu Ansible en
tirerait — pas une recherche de motif.
DEFAUT 2 — la doctrine promettait 54 greffons et citait check_pgsql. La flotte a
monitoring-plugins-basic : 53, sans check_pgsql ni check_dns ni check_ldap. Le
paquet qui les porte traine samba et snmp sur chaque machine. Un greffon absent
sort en 127, qui n est pas un code Nagios.
21 controles negatifs sur les machines reelles du site. ansible-lint production
0/91, harnais 75 OK.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Trois plans de locataire et cinq modeles perdent leur forge ou leur cache
d artefacts. Une machine de moins par ecosysteme neuf : origine passe de cinq
a quatre, et tout ecosysteme neuf en descend.
Retirer un service, ce sont cinq points d attache — le service, sa machine, sa
base, son client SSO, sa configuration de role. En oublier un laisse un
inventaire qui se genere et un deploiement qui echoue plus tard.
Preuve statique apres coup : 74 OK, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
J allais centraliser — un controleur poussant vers N forges, un temoin portant
une liste. Ca aurait demande un acces sur chaque forge depuis un seul poste, et
fait du temoin un fait global que personne ne detient.
Le modele suit la ligne du reste : chacun sert les siens. Sans WIKI_REMOTE,
l adresse se derive du nom que le plan monte expose pour serveur_forgejo.
Deux notions a ne pas confondre : la forge AMONT ou l on LIT le genome, et MA
forge ou l on SERT les siens. Le runner d un locataire lit chez son hebergeur et
sert chez lui.
WIKI_REMOTE l emporte toujours : le poste du mainteneur n est le runner d aucun
ecosysteme et publie vers le domicile public du projet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
make wiki-publier a refuse : le wiki vise par le temoin — la forge du SITE —
n a aucun commit. Le wiki vivant est sur eregion, 26 pages, branche main. Le
temoin affirmait depuis le 12 avoir publie sur une forge dont le depot wiki n a
pas survecu a sa reconstruction.
C est ce que P60 annonce d elle-meme : un temoin dit ce qui est PARTI, jamais ce
qui est ARRIVE. La preuve etait verte et la documentation n existait nulle part
a l adresse qu elle nommait.
Le garde-fou a tenu : publier sur un wiki vide aurait invente un nom de branche.
95 pages en ligne, dont les 68 fiches et leur index.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Generees depuis ce que chaque role declare, avec un schema mermaid et la raison
de chaque ligne. Une section vide est une information : l index recompte ce que
la flotte ne declare pas — 36 sans flux, 40 sans sonde, 67 sans metrique.
La charte du wiki disait de ne pas recopier le depot, pour eviter la derive. Le
motif ne vaut pas pour une page qui relit sa source ; l exception est nommee
plutot que prise en silence.
La navigation exigeait une citation DIRECTE alors que son motif parle
d atteignabilite. L exigence litterale interdisait toute page d index — la garde
forcait a degrader ce qu elle protegeait. Elle suit maintenant les liens de
proche en proche, et son motif reconnait le souligne : un motif trop etroit ne
rend pas une garde prudente, il la rend aveugle.
Et le compte du wiki serait passe de 27 a 96 : une fiche generee n est pas une
unite d apprentissage.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Une preuve a mordu : un script qu aucune cible n appelle est du code mort. Elle
avait raison.
68 fiches generees. Le vide y est une information — la carte de ce qui reste a
faire, tenue a jour toute seule.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
68 roles. Autant de pages faites a la main seraient perimees avant la fin du
mois — c est le defaut que ce depot traque partout sous le nom une liste qui
suit une autre prend du retard.
La fiche lit meta/flux, supervision, metriques, empreinte, authentification. Un
schema mermaid au centre, puis les tableaux, et chaque ligne porte la RAISON que
le role a declaree.
Une section vide est une information, pas un defaut de la fiche : elle devient
la carte de ce qui reste a faire, tenue a jour toute seule.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
supervision-conception disait deja qu une metrique a seuil appartient a
Prometheus et Grafana. Ce document est l autre moitie.
Il porte le critere des panneaux — une serie a sa place si elle PRECEDE un
verdict ou si elle n en aura JAMAIS — le compte de service au moindre droit, la
chaine de connexion hors ligne de commande, et la dette du chiffrement ecrite
plutot que tue.
La carte nomme desormais les deux ensemble : deux questions, deux fichiers meta,
un meme patron.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Aucune metrique de SERVICE n etait collectee — seulement du systeme. Le crochet
serveur_prometheus_cibles_supplementaires existait, documente, et personne ne le
remplissait.
Le pendant de meta/supervision.yml et son contraire : une sonde rend un verdict
avec un TTL, un exportateur expose une serie. Est-ce casse, contre depuis quand
et vers ou.
Le critere des panneaux : une serie a sa place si elle PRECEDE un verdict ou si
elle n en aura JAMAIS. Le taux de succes du cache n en aura jamais — quand les
donnees depassent shared_buffers, rien ne casse et tout devient lent.
Compte en lecture seule (pg_monitor), et flux en clair avec sa dette inscrite.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
playbooks/site.yml ordonne les couches pour n importe quelle instance. Mais
deployer-tout ne vise que l inventaire d un locataire, et le site n avait que
site-appliquer GROUPE=<un seul>.
Un hebergeur qu on ne peut remonter qu en enchainant onze groupes de memoire
n est pas reconstructible : il est reparable par quelqu un qui se souvient.
Et quatre gardes que --check rendait folles, toutes de la meme famille : une
garde qui compare contre ce qu une tache du meme play vient de produire n a rien
a dire tant que rien n a ete ecrit. Sept machines en echec sur un site sain, en
suivant le conseil du Makefile lui-meme.
Apres correction : 7/7, 0 echec, de 174 a 309 taches par machine.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Les instantanes sont chiffres cote client : ce serveur heberge des octets qu il
ne peut pas ouvrir, donc pas juger. La verification suit la cle, et
client_backup la fait deja depuis chaque noeud.
Ce que la sonde ajoute : elle voit TOUT DE SUITE, et depuis la cause, ce que les
clients ne decouvriront qu a leur prochaine execution. Lecture seule apres une
erreur disque, volume plein, droits derives — le depot refuse alors tout le
monde, et neuf rouges epars ne designent pas une cause commune.
Elle ECRIT vraiment, sous l identite qui depose. Un test -w ment sur un montage
en lecture seule et sur un quota atteint.
Corrige aussi l en-tete de setops-sauvegardes.conf.j2, qui nommait encore
backup-01 comme pousseur — retire le 2026-09-02, et c est tout le sujet. Le code
avait suivi la decision, l en-tete non.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
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
Redis est le premier des treize roles serveur_* sans supervision declaree.
Une seule sonde, parce qu il n y a qu une cause d action : le cache ne sert
plus. Elle s atteint par deux chemins — il ne repond pas, ou il repond et n a
rien a dire. Le second est le couteux : borne a maxmemory avec allkeys-lru, un
Redis plein n echoue JAMAIS, il evicte. Les sessions disparaissent, les gens
sont deconnectes au hasard, et le service reste vert. La panne se presente
comme un defaut d application.
Le compteur d evictions est cumulatif : la sonde en fait un DEBIT, sinon une
seule mauvaise journee laisserait le voyant rouge pour toujours.
Pas d occupation memoire ni de taux de succes ici — ce sont des series, elles
appartiennent a Prometheus. Icinga repond a une seule question.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
L entree du 2026-09-13 affirmait aucun maxmemory configure. Faux : le grep
visait /etc/redis/redis.conf alors que le role ecrit setops.conf. Interroge la
ou la verite vit, redis repond maxmemory 268435456 et allkeys-lru.
La conclusion ne change pas — redis reste hors de la table des planchers — mais
sa raison change : il est borne a 256 Mo, il ne peut pas prendre la machine.
Un fichier de configuration n est pas la configuration ; c est une de ses
sources.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
Ansible declenche les handlers dans l ordre ou ils sont DEFINIS, jamais dans
celui ou les taches les notifient. Recharger etait ecrit en premier.
Sur un premier deploiement, main.cf passe inet_protocols de all a ipv4 et
notifie un redemarrage ; les cartes LDAP notifient un rechargement. Le
rechargement partait d abord, sur un maitre portant encore l ancienne valeur :
to change inet_protocols, stop and start Postfix — puis fatal sur :::submission.
Le role documentait le piege depuis le 2026-08-30 et notifiait correctement.
Seul l ordre des handlers le rendait inoperant.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q