170 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 5abf20102d |
le site surveille enfin sa fabric
La supervision du site voyait ses sept VM et rien d autre. Au depart, depuis site-mon-01, les trois hyperviseurs, les neuf pattes de la frontiere et sa PROPRE passerelle par defaut rendaient tous 100 pourcent de perte au ping. 16 hotes UP sur 16 dont 9 pattes de frontiere en controle ACTIF 11 cibles Prometheus dont 3 hyperviseurs, job fabric separe LE PARTAGE. Les hyperviseurs portent node_exporter - D-48 l autorise - et exposent 1005 unites systemd avec leur etat, soit ce que la sonde sante mesurait, plus la charge et le disque. Ils n entrent PAS dans le socle : leur appliquer serveur_durci reecrirait le pare-feu, le SSH et les sysctl de la machine qui tient tout le reste. La frontiere, elle, n accueille aucun agent : controle actif, une entree par PATTE, parce qu une interface eteinte coupe une zone pendant que les autres vont bien. ON TIRE, ON NE POUSSE PAS. J avais propose du passif et il avait ete valide ; la mesure a dit non. Un hyperviseur envoie vers un routeur qui ne connait pas les reseaux du site, et sa route par defaut est GELEE (D-57). Le porteur de sante y expirait en 20 s. LE VRAI DEFAUT ETAIT UNE LISTE QUI N A PAS SUIVI. Le mecanisme de routage existait deja sur vmbr0, avec un commentaire du 2026-08-26 tenant exactement le raisonnement qu on venait de refaire. Sa liste s arretait a 10.0.34.0/24 quand le site en declare six : les zones sauvegarde et supervision sont nees, les routes n ont pas suivi. Le symptome ne ressemblait pas a une route manquante - il ressemblait a un pare-feu, puis a un probleme de reseau chez l exploitant. make routes-fabric-etat compare desormais TROIS choses : zones declarees, routes declarees dans /etc/network/interfaces, routes vivantes dans le noyau. Le cas le plus traitre est vivante mais non declaree : tout fonctionne, la supervision est verte, et la panne attend la prochaine maintenance. Eprouvee dans les deux sens. Deux defauts trouves en construisant. bifrost-2 est un nom RESERVE, pas un boitier - l underlay le disait en prose, illisible par le moteur ; il porte desormais etat: reserve. Et un service passif n existe que pour un hote qui peut POUSSER : l appartenance a un groupe sert deux choses qui ne coincident pas toujours, a qui l on deploie et de qui l on attend un rapport. Les commutateurs restent dehors, choix de l exploitant, coherent avec D-48. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| a60b69f072 |
un fichier vide existe, et une sonde pour les correctifs
LA GARDE FICHIER ENTIER, en deux corrections. Un telechargement interrompu laisse un fichier de zero octet QUI EXISTE, et toutes les gardes demandaient seulement s il etait la. infra-mail-01 a garde une cle smallstep de 0 octet apres l epreuve hors ligne. La premiere correction n a pas suffi. Ajouter le controle de taille faisait bien s executer la tache - et le fichier faisait toujours 0 octet au passage suivant. get_url sur une destination existante emet une requete CONDITIONNELLE : l amont repond non modifie, le module rend ok, la ruine reste. Le play etait vert et ne reparait rien. Il faut effacer avant de redemander. Controle negatif : 0 -> 1022 octets, 0 erreur apt. Cinq roles. LA SONDE CORRECTIFS, 23e. Set-OPS desarme unattended-upgrades et applique les correctifs au deploiement - choix defendable, le verrou dpkg a fait decrocher une machine d une reconstruction entiere le matin meme. Mais rien ne disait QUAND le geste etait du : une flotte pouvait deriver des mois en restant verte. Elle mesure les paquets de securite en attente ET depuis quand. Elle ne lance pas apt-get update - une sonde qui rafraichit l index toutes les quinze minutes deviendrait la cause de la panne qu elle surveille. Et le seuil de 72 h est un choix d exploitation, pas une derivation : le mecanisme qui applique les correctifs est un geste humain. P64 REFUSAIT UNE DECLARATION CORRECTE. serveur_debian et serveur_durci sont des roles de declaration pure, sans une tache ; le travail est fait par les roles que leur playbook applique. La preuve exigeait declaration et depot dans le meme role - vrai des vingt-deux premieres sondes, faux des qu une sonde appartient au socle. Une garde qui force a contourner ce qu elle protege est un defaut. Elle suit desormais le playbook du groupe. Mesure : 21/21 machines vertes, 65 preuves, 23 sondes, 0 echec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| c6a7150c60 |
les depots tiers passent par le cache, et le tenant n a plus le sien
Deux mouvements d une seule doctrine : le site fournit tout ce dont un
tenant a besoin pour venir au monde.
1. LES DEPOTS TIERS. Grafana, Icinga, Smallstep et Collabora ne publient
qu en HTTPS ; apt-cacher-ng ne relaie pas un tunnel, et le socle pose donc
Acquire::https::Proxy DIRECT. Chaque machine sortait elle-meme sur
Internet. Le cache declare desormais un Remap par fournisseur, et chaque
role demande en {{ ..._depot_schema }}:// - http des qu un cache est
declare, https sinon. Le TLS n est rompu nulle part : il est TERMINE au
cache, qui est notre machine, et l integrite vient des signatures.
avant : 4 fournisseurs en HTTPS direct, 14 machines sortant seules
apres : 0 source en HTTPS direct, 0 erreur apt sur 14 machines
Trois lecons. Le remap appartient au cache qui SORT : pose sur un cache
chaine, il tente le HTTPS a travers son amont et rend 503. apt_repository
AJOUTE au lieu de remplacer, donc l ancienne ligne https sortait toujours.
Et la liste des fournisseurs ne se devine pas - j en avais trois, l audit
en a revele un quatrieme.
2. LE CACHE DU TENANT. Sa ligne portait son propre retrait depuis toujours
- service MUTUALISABLE, un ecosysteme au premier age peut pointer sur celui
de son hote. Retiree. Ce qu on perd, dit franchement : plus de trafic
inter-zone et plus de charge sur site-cache-01, contre un service de moins
a poser, superviser et reproduire.
3. UN ROLE QU ON RETIRE DOIT DEFAIRE CE QU IL A FAIT. Le retrait a montre
que rien ne nettoie derriere. Le fichier apt visait un cache eteint en
ecrasant le plancher qui fonctionnait - le defaut deja paye a quinze
machines. Et les sondes du cache restaient, le porteur poussant pour des
services qu Icinga ne definit plus (404). Le socle retire le premier,
client_sante derive les sondes attendues et retire les orphelines.
P65 refuse tout role visant un depot relaye en https ecrit en dur. Sa
limite est dite : elle empeche une regression sur ce qui est connu, elle ne
decouvre pas l inconnu.
Mesure : Icinga 87 OK sur 96, prouver 65 OK, lint 0 defaut.
Reste, et c est dit : apt-cacher-ng tourne toujours sur forge-01 que plus
aucun plan ne declare.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
|
|||
| 4ef3a1d553 |
D-86 mis a l epreuve : Chezlepro rasee et refaite depuis zero
Quatorze machines detruites, quatorze refaites. 1 h 08, 0 injoignable. D-86 TIENT, et la mesure le dit : 30 resultats de controle recus a 12:20:41 alors que la reconstruction ne s est terminee qu a 12:35:29. Trente services rapportaient leur etat pendant que Keycloak, Forgejo et Nextcloud montaient encore. Sa limite, dite franchement : D-86 affirme que le DNS peut rester en couche 6 grace au plancher /etc/hosts. Or _amorcer-socle monte infra-dns-01 EN ENTIER d abord. Le DNS etait debout, le plancher n a rien eu a porter, et la partie la plus audacieuse de la decision reste non testee. LE PLACEMENT DES VM N ETAIT DECLARE NULLE PART. Les quatorze vivaient sur asgard depuis toujours, mais SETOPS_NOEUD valait le vide : ce placement n existait que dans l etat d execution de Proxmox. Sans cible, le clone reste sur le noeud du gabarit - vishnu, qui a 14 Go libres et heberge eregion et site-forge-01. Le defaut avait survecu a la reconstruction du 2026-09-02 parce que les VM existaient deja et que le clone les sautait. Il faut un from-zero VRAI pour voir ce genre de chose. LE CLONAGE ETAIT 45 FOIS TROP LENT, et pas a cause du reseau : source et destination etaient sur le meme stockage. C est le LVM epais qui interdit a Proxmox tout clone autre que complet. Gabarit deplace sur CephNVMe, mesure 480 s -> 8 s. On garde les clones complets : le clone lie descend a 1 s mais enchaine chaque VM a l image de base pour toujours. Un champ stockage: entre au gabarit, branche en quatre points - declare, expose, consomme par le Makefile, garde par gabarit_etat. Declarer sans consommer, c est decorer. ICINGA NE POUVAIT PAS FAIRE SES PROPRES CONTROLES : icinga2 n apporte aucun greffon, et la supervision etant passive, le manque etait masque. Quatorze ping4 muets d une seule cause. monitoring-plugins-basic entre au role. Le site l avait deja - pose A LA MAIN, jamais declare : troisieme occurrence du jour d un etat qui ne survivrait pas a une reconstruction. Trois defauts laisses ouverts : le cache apt attendu pendant l amorcage, la regression D-85 sur /etc/cloud - qui a fait decrocher deux hotes de la tache deposant icinga-ca.crt, rendant leurs sondes muettes en silence - et auditd sans regles dans le gabarit. Mesure finale : Icinga 93 OK sur 98, site 51/51, Prometheus 15/15, prouver 64 OK, lint 0 defaut. Les quatre non-OK restants sont des sauvegarde dont le minuteur nocturne n a pas encore visite une flotte nee il y a deux heures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| f2c580235d |
observabilite : le site cesse de ne rien voir de lui-meme
D-87 disait que l hebergeur n a pas le droit de voir les journaux de ses
locataires. La decision avait une face cachee : a force de refuser de voir
ceux des autres, le site s etait prive des siens. Ses sept machines
n expediaient nulle part.
Il prend donc sa propre pile : prometheus, loki et grafana sur site-mon-01,
sans aucun lien avec ceux d un tenant. L exemption qui bloquait portait sa
propre condition de levee, ecrite cinq jours plus tot dans le plan.
Grafana au site n a pas de SSO, et le role l ignorait : il reclamait l IdP
avant de regarder s il en voulait un. L interrupteur existait, il n etait
pas honore. Le role refuse desormais SSO eteint ET formulaire local eteint
- la combinaison deploie un Grafana en sante ou personne ne peut entrer -
et le reglage du formulaire sort du if du SSO, ou il disparaissait en
laissant le defaut amont decider en silence.
Deux manques se cachaient l un l autre dans le devis de la frontiere, et
Prometheus voyait 1 cible sur 7 :
- le devis derivait les groupes d une machine du site de applications.yml
seul, et ne voyait donc aucune integration universelle - alors que
client_metrique ouvre un port d ecoute ;
- une sortie vers un role du site visait !SETOPS_INTERNES, qui exclut
precisement la machine nommee. Le devis autorisait a expedier les
journaux du site a n importe quel Loki du monde, et a nul autre endroit
qu a celui-la. Neuf flux dans ce cas.
Et deux declarations justes ne font qu une regle : appliquer_opnsense pose
tout en direction: in (D-61).
Les deux agents se supervisent enfin eux-memes. La sonde des journaux ne
demande pas si Alloy tourne, elle lit ce qu il a du JETER. Elle a fait ses
preuves le jour meme : Alloy actif, /-/ready a 200, et cinquante lignes
perdues sur six machines.
Mesure : metriques 7/7 vert, journaux 1/7 - les six autres attendent la
regle de frontiere, et le disent. prouver 64 OK, ansible-lint 0 defaut.
Reste a la main de l exploitant : make frontiere-appliquer CONFIRMER=true,
et le secret vault_grafana_admin a deposer dans underlay.vault.yml.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
|
|||
| 6e46ace4de |
sondes : les cinq qui manquaient le plus (autorite, base, annuaire, zones, edge)
CORRECTION DE COMPTE D ABORD. J avais annonce cinq groupes sans sonde. La mesure en donne VINGT-SEPT : j avais compte ceux que j avais en tete, pas ceux que le depot contient. Il en reste vingt-deux. LES CINQ, PAR ORDRE DE DEGAT SILENCIEUX. autorite (step_ca) — la plus urgente : nos certificats vivent 24 h, une AC muette ne casse rien aujourd hui et casse TOUT demain, d un coup, sur les 21 machines. Elle surveille aussi l expiration de la RACINE, que personne ne regarde parce qu elle vit des annees (relevee a 3642 jours). base (postgresql) — une VRAIE requete, pas pg_isready : celui-ci dit que le port repond, pas que la base sert. Plus le compte des connexions : a saturation, chaque application tombe sans que la base ait l air morte. annuaire (openldap) — elle COMPTE les entrees. Un annuaire vide repond success a tout : le mensonge des sauvegardes vides, vert et sans contenu. zones (powerdns) — un autoritatif sans zone repond NXDOMAIN a tout, ce qui se lit comme « ce nom n existe pas ». edge (nginx) — elle valide la configuration SUR DISQUE : nginx sert la derniere valide, et une configuration cassee ne se voit qu au prochain demarrage, souvent des mois plus tard. Les cinq eprouvees vertes sur le sain puis rouges PAR PARAMETRE, sans toucher a un service. Etat : 20 sondes sur 19 roles, 23 services distincts, 70 instances, 67 au vert. Les trois autres sont connues : deux sauvegardes sans donnee a emporter, et Loki en delai de stabilisation apres redeploiement. 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 |
|||
| a5d9040a11 |
cache-apt scindee — et la scission a revele que moteur aurait alarme a tort
LA SCISSION. cache-apt fondait deux causes aux DELAIS differents : « ne repond pas » arrete tout apt de l ecosysteme, on agit dans la minute ; « volume a 90 % » est un billet pour demain. Les fondre obligeait soit a reveiller quelqu un pour un disque, soit a traiter une panne comme un billet. Deux sondes, chacune avec son etat, son historique, son acquittement — et prouvees INDEPENDANTES : port ferme -> cache-apt CRITIQUE, cache-apt-volume OK seuil impossible -> cache-apt OK, cache-apt-volume AVERTISSEMENT CE QUE LA VERIFICATION A REVELE. Un resultat pousse et accepte (code 200) n apparaissait pas en base. Hypothese testee et confirmee : IcingaDB n ECRIT service_state QUE SUR CHANGEMENT D ETAT. Un OK identique repete ne produit aucune ecriture ; un AVERTISSEMENT pousse ensuite est ecrit en 13 s. Or la sonde moteur, ecrite quelques heures plus tot, lisait exactement max(last_update) de service_state pour juger de la fraicheur. Elle mesurait le CHANGEMENT. Sur un ecosysteme parfaitement STABLE — celui qu on veut — plus rien ne change, last_update vieillit, et elle serait passee en avertissement a 15 min puis en critique a 90. Une alarme qui se declenche PARCE QUE tout va bien, avec un delai qui l aurait rendue difficile a rattacher a sa cause. La bonne source existait : icingadb_instance porte le battement du synchroniseur, ecrit en continu. Releve a 1 s sur un systeme sain. Seuils ramenes de 15/90 min a 1/5 min. Controle negatif rejoue. Dix-huit services, tous verts sauf sauvegarde 7/9 (deja connu). 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 |
|||
| 6120e6f006 |
sondes : quatorze, une par role, derivees en objets Icinga
boites (dovecot) · cache-apt (artefacts) · certificat (client_pki, 14/14)
collaboration (nextcloud) · collecte (prometheus) · file-courriel (postfix)
forge (forgejo) · identite (keycloak) · ingestion (loki) · moteur (icinga)
resolution (resolveur) · runner (serveur_ops) · tableaux (grafana)
voute (ops_tenant) — toutes vertes, sans une ligne ecrite dans Icinga.
DEUX PRINCIPES QUE LA PREMIERE SONDE A IMPOSES.
Une sonde doit pouvoir etre mise en defaut PAR PARAMETRE : cible et seuils
sont des variables du role, on prouve le rouge avec un port ferme ou un
seuil impossible, sans rien casser. Et la sonde vit LA OU VIT LA VERITE :
« ce noeud est-il collecte ? » appartient a prometheus, pas au client —
une seule y voit les N noeuds, et surtout elle voit le cas SILENCIEUX.
ON DEMANDE AU SERVICE CE QU IL PENSE DE LUI-MEME quand il sait le dire
(healthz, /ready, status.php, decouverte OIDC). Quand il ne sait pas, on
va chercher la verite de terrain : « moteur » ne regarde ni le service ni
le port, il demande a la base depuis combien de temps elle n a pas ete
rafraichie — la lecon des sauvegardes appliquee a la supervision.
QUATRE FOIS J AI ECRIT LA SONDE AVANT DE MESURER, QUATRE FOIS ELLE A EU
TORT. La forge : port et chemin des depots inventes, elle ecoute en 3000
derriere l edge et n a legitimement aucun depot. Loki : « panne
persistante » conclue sur deux lectures a quelques secondes d intervalle
juste apres un redemarrage — deux mesures rapprochees ne distinguent pas
un etat d un instant. Keycloak : vise en 8443, il ecoute en 8080. Le
runner : git en root refuse un depot d un autre proprietaire. A chaque
fois le remede est le meme — lire la verite du role, ne pas la supposer.
Et le meme piege Jinja qu avec client_sante : ${#tableau[@]} contient {#.
Le remede etait deja au depot ; je l ai reecrit au lieu de le chercher.
RESTE : client_smtp, client_artefacts, client_journal, icingaweb2 et
ops_site. Ce sont des chemins de report, dont la panne se voit deja par le
silence des sondes qu ils portent.
make prouver : CONFORME, 64 OK, 0 echec, 0 saute (P64 : 14 sondes).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
|
|||
| 1832530f29 |
sondes : les six premieres, et le patron qui les rend eprouvables
Ajout de meta/supervision.yml a six roles, chacun deposant sa propre sonde selon le contrat des greffons Nagios. DEUX PRINCIPES POSES AU DOCUMENT DE CONCEPTION, parce que la premiere sonde les a imposes : 1. UNE SONDE DOIT POUVOIR ETRE MISE EN DEFAUT PAR PARAMETRE. Cible et seuils sont des variables du role : on la prouve rouge avec un port ferme ou un seuil impossible, sur une machine reelle, sans rien casser, et aussi souvent qu on veut. Une sonde qu on ne peut prouver qu en cassant un service ne sera prouvee qu une fois. 2. LA SONDE VIT LA OU VIT LA VERITE. « Ce noeud est-il collecte ? » est une sonde de serveur_prometheus, pas de client_metrique : une seule y voit les N noeuds, et surtout elle voit le cas SILENCIEUX — celui qui a cesse d etre collecte ne peut pas s en plaindre. LES SIX : cache-apt (artefacts, repond + place), resolution (resolveur, zone interne ET Internet — deux chemins distincts), forge (forgejo, son propre /api/healthz), collecte (prometheus, 15/15 cibles), tableaux (grafana, base ok), ingestion (loki, PRET a ingerer, pas seulement en ecoute). TROIS FOIS J AI ECRIT LA SONDE AVANT DE MESURER, ET TROIS FOIS ELLE A EU TORT. La forge : port 443 et chemin des depots INVENTES — elle ecoute en 3000 derriere l edge et n a legitimement aucun depot. Loki : j ai conclu « panne persistante » sur deux lectures prises a quelques secondes d intervalle, juste apres un redemarrage ; l anneau etait ACTIVE et la reponse est passee a ready moins d une minute plus tard. Le delai de stabilisation est desormais un AVERTISSEMENT nomme, pas une panne. On demande au service ce qu il pense de lui-meme quand il sait le dire (healthz, /ready, /api/health) plutot que d inventer un critere de l exterieur. make prouver : CONFORME. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 843d39e7aa |
frontiere : un type ICMP n est pas un port symbolique
LA CAUSE EXACTE. devis_opnsense traitait tout `port` non numerique comme SYMBOLIQUE, a resoudre par le plan. Vrai pour `derive`, le port d un service que seul le plan connait. FAUX pour l ICMP : echo-request et frag-needed sont des litteraux. Ils tombaient dans la branche « le plan ne resout pas » et aucune regle n etait emise. Une ligne de condition, et le silence de toute une flotte. CE QUE LA CORRECTION A REVELE EN PLUS. Huit regles a creer, zero a retirer — et SIX sont du PMTUD entre zones du site, absent pour la meme raison. Le depot dit de ces messages : bloques, la connexion s etablit, les petites requetes passent et les grosses reponses restent suspendues — la panne la plus couteuse a diagnostiquer. Elle etait la, silencieuse. CE QUE LA REGLE AUTORISE, EXACTEMENT. appliquer_opnsense n envoie destination_port que pour TCP et UDP : une regle ICMP ouvre le PROTOCOLE entre deux pairs, pas le seul type. Le type reste porte par la regle d HOTE, que resoudre_flux emet precisement. La frontiere dit qui peut parler a qui, l hote dit ce qu il accepte d entendre. Emettre un icmptype a la frontiere aurait demande de traduire frag-needed dans le vocabulaire de pf, au risque de casser le PMTUD pour gagner de la precision sur une barriere qui n est pas la derniere. MESURE APRES APPLICATION : ping site-mon-01 -> les six autres zones : 6/6 repondent hotes UP : 1/7 -> 7/7 | ping4 : 1/7 -> 7/7 | certificat 7/7 | sante 7/7 tenant inchange : 14/14 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 |
|||
| a070c339ee |
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 |
|||
| 90228cb55e |
supervision : la sonde se declare dans le role, comme le flux
LE CONSTAT. 39 roles declarent leurs flux, 32 leur empreinte, 32 leur authentification — tous derives. Et 19 groupes sur 19 declaraient une surveillance en prose que RIEN n executait ; Icinga en surveillait deux. La carte disait ce qui etait surveille, et personne ne surveillait. LE MECANISME. Un role declare ses sondes dans meta/supervision.yml et depose lui-meme son script dans /usr/local/lib/setops/sondes/. Le porteur client_sante les fait toutes tourner et pousse un resultat passif par sonde, sans savoir ce qu elles mesurent. serveur_icinga derive les objets Service ET le filtre de permission d API des memes declarations. Ajouter une sonde ne demande de toucher ni au porteur ni a Icinga. PREMIERE SONDE : client_pki/certificat. Heures restantes sur le certificat reellement pose, chaine verifiee, et empreinte SERVIE comparee au disque quand un service le consomme. 14/14 au tenant, 7/7 au site. QUATRE OBSTACLES, ET TROIS SONT LA MEME LECON. La sonde a rendu 14/14 en CRITIQUE sur une PKI saine : openssl verify -CAfile racine ne trouve pas l intermediaire qui signe nos certificats. step certificate verify, lui, repond VALIDE. Deployee au site, elle a rendu 5/7 : le seuil d avertissement (12 h) etait AU-DESSUS du point de renouvellement (8 h, le tiers restant). Elle criait avant que le mecanisme ne soit cense agir. Seuils ramenes a 6 h et 3 h. Un seuil se DERIVE du moment ou le mecanisme surveille agit. Une alarme toujours allumee ne vaut pas mieux qu une alarme jamais allumee : elle apprend a ne plus regarder. Une sonde se prouve DEUX FOIS, verte sur le sain et rouge sur le casse. Le filtre d API etait ecrit avant la lecture des declarations : les services auraient existe et Icinga aurait refuse leurs resultats. Et mon controle negatif a casse un service reel : substituer le certificat d hote a fait propager un cert sans sa clef vers node_exporter. Un controle negatif se fait sur une COPIE. P64 tient les deux bouts : declaree sans etre deposee, ou deposee sans etre declaree. Trois controles negatifs rejoues. 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 |
|||
| 69b84f4e2c |
client_sante : retrait d une garde qui ne pouvait pas se declencher
Le role portait une branche « aucun serveur_icinga : rien a poser » et un when sur tout son bloc. Ni l une ni l autre ne pouvait s executer. Eprouve sur le modele public, dans une copie jetable : instancier ne pose une integration UNIVERSELLE que si son serveur existe dans l ecosysteme. Sans Icinga au plan, le groupe client_sante est ABSENT de l inventaire genere — comme client_metrique et client_journal le sont deja. Le role n est donc jamais appele sans destinataire. Une garde qui ne peut pas se declencher n est pas une garde : elle rassure sans rien tenir, et elle coute le jour ou l on cherche pourquoi rien n a alerte. Ce qui la remplace se declenche vraiment, et les deux cotes sont eprouves : hote vide -> FAILED, secret vide -> FAILED, et l echec dit lequel des deux manque. Le bloc, prive de sa condition, est aplati : douze taches a plat. Rejoue sur les deux flottes : zero changement sur zero hote. make prouver : CONFORME, 63 OK, 0 echec, 0 saute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 018d55ec6c |
supervision : le site rapporte aussi — et deux corrections pour que ca MARCHE
7 machines du site deployees, 0 echec au playbook — et CINQ rapports sur sept en TimeoutError. Un playbook vert ne prouve pas qu une chose fonctionne ; seul l essai de bout en bout l a dit. 1. LE PAIR DE LA FRONTIERE. Le role client declarait son egress 5665, la politique de sortie etait accept, la regle d entree de l hote autorisait la source — et les paquets mouraient ENTRE les deux. La frontiere filtre l inter-zones du site et ne resout que les roles que les machines PORTENT AU PLAN ; une integration universelle n y figure pas, elle est derivee. pair: client_sante produisait donc une regle est-ouest correcte et AUCUNE regle a la frontiere. Le pair devient serveur_debian — le vocabulaire du depot pour « tout noeud », que le generateur traite deja comme tel, et exact au sens strict. Six regles creees, zero retiree, une par patte de zone. 2. LE RAPPORTEUR S ACCUSAIT LUI-MEME. Pendant l heure de blocage, setops-sante.service a echoue ; une fois debloque, cinq machines ont rapporte CRITIQUE en citant leur propre rapporteur, et systemd garde l etat failed jusqu a un reset-failed. Sa propre unite est desormais exclue du compte — non par complaisance : sa sante est deja mesuree, et mieux, par la FRAICHEUR de ses envois. S il ne peut plus parler, le ttl perime le service, ce qui se voit precisement quand il ne peut PAS ecrire. ETAT FINAL : 7/7 au site, 14/14 au tenant, tous OK. Controle negatif rejoue sur les deux flottes. make prouver : CONFORME, 63 OK, 0 echec, 0 saute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 6d23121dc2 |
supervision : systemctl --failed entre dans Icinga (role client_sante)
CE QU IL FERME. openipmi.service echouait a chaque demarrage sur les
quatorze machines depuis le 2026-09-02, et systemctl --failed rendait ZERO
partout : non parce qu elles allaient bien, mais parce qu aucune n avait
redemarre depuis. Il a fallu qu un humain redemarre une machine pour que
le defaut existe aux yeux de quelqu un. Un controle qui ne peut echouer
qu au demarrage ne mesure rien tant que rien ne demarre.
PASSIF, ET A DUREE DE VIE. Un controle actif ne voit pas la machine MUETTE.
Ici c est le noeud qui parle, et le ttl de son envoi fait la fraicheur :
sans nouvelle, Icinga perime le service tout seul. Le silence alerte autant
que l echec. Le minuteur declenche AU DEMARRAGE autant que toutes les 15
min : les echecs de cette famille naissent au boot.
CRITIQUE DES LA PREMIERE UNITE, jamais un seuil — une unite en echec est
soit un vrai probleme soit du bruit a retirer, et un seuil ferait vivre le
bruit. Les tolerances se nomment une par une, vide par defaut.
CONTROLE NEGATIF. Unite factice sur obs-01, etat relu dans IcingaDB :
CRITICAL, et le verdict NOMME l unite. Les treize autres OK. Apres
nettoyage : 14/14 OK.
UN CONFLIT EVITE. setops-sauvegardes.conf definissait les object Host ; un
second fichier de controle aurait redefini les memes, et Icinga refuse un
objet en double — la configuration entiere aurait ete rejetee, donc AUCUNE
supervision, en voulant en ajouter. Les hotes vivent maintenant dans
setops-hotes.conf, definis une fois.
TROIS OBSTACLES. ${#tableau[@]} contient {# que Jinja lit comme un debut de
commentaire (remede : comment_start_string en tete du gabarit). Ma premiere
sonde a traduit un 403 « Missing permission: objects/query/service » en
« 0 service » — encore un echec qui ecrasait permission ; l etat se lit
dans IcingaDB. Et un echec apt transitoire sur mon-01, local et disparu au
second essai : mesure avant conclusion.
NON FAIT : le SITE n a pas recu client_sante.
make prouver : CONFORME, 63 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
|
|||
| 36aba37200 |
wiki : les deux forges servent le meme wiki (origin rattrape)
CE QUE JE DISAIS ETAIT FAUX. « Il n y a rien sur origin » — le DEPOT y est, et a jour, exactement notre HEAD. C est le WIKI qui etait vide. Je l avais recopie d une session precedente sans le remesurer. LA GARDE AVAIT RAISON DE REFUSER, ET TORT DE S ARRETER LA. wiki-publier refuse un wiki vide parce que publier y inventerait un nom de branche. Son message renvoyait a l interface Forgejo — injoignable depuis ce poste, et ce n est pas une panne : la forge du site n accepte le 443 que des machines qui declarent le flux. Forgejo DECLARE pourtant la reponse : wiki_branch, dans son API. Interroge depuis ops-01 — machine qui a le flux — il repond main. On ne devinait pas : on ne demandait pas. WIKI_BRANCHE= ajoute a la recette, le refus reste le defaut. Les deux cotes eprouves. Resultat : 26 pages sur les deux forges, contenu identique au fichier pres. LECON D INSTRUMENT. Trois sondes fausses avant la bonne : connect() direct rend TimeoutError (politique, pas route manquante) ; un tunnel par la frontiere ne repondait pas ; et git ls-remote fonctionnait tres bien, parce que ~/.ssh/config passe par un ProxyJump que la sonde ignorait. make prouver : CONFORME, 62 OK, 0 echec, 1 saute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 0b0d9ca708 |
wiki : publie (ce que le retrait de cloud-init ne ferme pas)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| a6457a161b |
wiki : publie (cloud-init retire au durcissement)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 53d7b4c4c2 |
durcissement : cloud-init nait avec la VM et ne lui survit pas
cloud-init n est pas un logiciel d installation : c est une SOURCE DE VERITE EXTERNE. Il se reveille a chaque demarrage et relit le lecteur attache par l hyperviseur, qui peut redefinir comptes, cles SSH, mots de passe et reseau. Sur une machine que le plan possede, c est un second maitre — que le plan ne decrit pas, que make valider ne mesure pas, et qui parle en premier. Sa tache est finie a la premiere seconde : c est parce qu il a REUSSI a poser l adresse et les cles qu Ansible a pu entrer. TROIS MOITIES, ET ELLES SE DEFONT SEPAREMENT. - le GABARIT le garde : sans lui un clone n a ni adresse ni nom ; - le SOCLE ne l installe plus : le garder produisait un va-et-vient a chaque deploiement, deux changed par passage, idempotence perdue ; - le DURCISSEMENT le retire (roles/cloud_init_retrait, en dernier). P63 garde les trois, plus le CONTENU du role : une coquille vide passerait les trois premiers controles sans rien fermer. Quatre controles negatifs rejoues. CE QUI REND LE RETRAIT SUR EST MESURE, PAS SUPPOSE (obs-01, 2026-09-09) : /etc/network/interfaces.d/50-cloud-init n appartient a aucun paquet — dpkg -S ne le trouve pas — et le postrm ne le nomme jamais, meme en purge. L adresse survit. Le role le verifie quand meme, avant et apres, et n accuse que si le retrait l a emporte : une VM qui perd ce fichier ne se plaint pas, elle repart sans adresse et plus personne ne peut entrer. DEUX CHOIX DITS FRANCHEMENT. cloud-guest-utils reste (growpart : ni service, ni port, ni source de donnees). Les ~29 paquets orphelins ne sont pas retires par defaut : autoremove deciderait a partir des drapeaux dpkg, et un durcissement ne doit pas pouvoir surprendre. NON DEPLOYE : le code est ecrit, valide et prouve ; il n a pas ete applique a la flotte. Essai a blanc sur obs-01 : cloud-init a retirer, configuration reseau intacte. make prouver : CONFORME, 62 OK, 0 echec, 1 saute (63 preuves). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 765d97b5c9 |
wiki : publie (les six registres generes)
Some checks are pending
verifier / verifier (push) Waiting to run
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 2887b57f0c |
GUI : les six registres ont un formulaire genere, et la sauvegarde aussi
CHAMPS_ECRITS_A_LA_MAIN est vide. Serveurs et applications, les deux plus gros, sont passes au generateur — chargement, rendu et sauvegarde. L EPREUVE QUI COMPTE. Ouvrir chaque vue et enregistrer sans rien toucher doit renvoyer exactement le plan qu on vient de lire : 14 serveurs, 25 applications, 2 domaines, 4 bases, IDENTIQUE partout. C est ce qui separe un formulaire genere d un formulaire qui en a l air — un champ visible a l ecran et perdu en silence a l enregistrement serait le pire des deux mondes. test_rendu_gui.py le mesure a chaque make prouver. TROIS DEFAUTS TROUVES EN CHEMIN. Le formulaire annoncait des defauts INVENTES : 2048 Mo, 2 coeurs, 16G. Il n existe aucun defaut fixe — deriver_ressources calcule depuis les roles portes (1024 et 1 pour infra-pki-01, 5632 et 4 pour collab-01). Un repere faux fait croire qu on connait la valeur. Le schema nomme le champ derive, et l ecran montre la valeur reelle de cet hote. L option vide d un select dit desormais ce qu elle produira : « (defaut : asgard) ». Une SECONDE occurrence du defaut d hier dormait dans sourceDeValeurs : elle lisait encore data.nomenclature. Elle n avait jamais leve parce que la vue Serveurs, seule a emprunter cette source, avait un formulaire ecrit a la main. Elle a leve a la seconde ou le generateur l a prise. Le banc ne voit que les chemins vivants : verifier_gui.py fait donc aussi une verification STATIQUE, qui voit ce qui dort. La validation client s accrochait a data-v, pose a la main sur trois champs. Le formulaire genere l aurait perdu et la validation serait passee au vert sur ZERO champ. Le generateur marque chaque controle, et la sauvegarde refuse si elle n en inspecte aucun. DEUX CHAMPS GARDENT LEUR EDITEUR, et le schema le dit (x-editeur) : la matrice des integrations montre les universelles et les exemptions, et l editeur de liens contraint le role a meta/liens.yml. Le generateur s efface plutot que de remplacer un editeur qui en sait plus que lui. LIMITE : je n ai toujours pas ouvert ces pages dans un navigateur. make prouver : CONFORME, 61 OK, 0 echec, 1 saute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| c0ea0c8e71 |
wiki : publie (formulaires generes, ecritures preservantes)
Some checks are pending
verifier / verifier (push) Waiting to run
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 935a64a1bf |
plan : sauvegarder n emportait plus quarante lignes de commentaire
En voulant generer deux formulaires de plus, j ai trouve pire que ce que
je cherchais.
CE QUI ETAIT DEJA LA. Les quatre ecrivains de registre ecrasaient le
fichier au safe_dump. Mesure sur les fichiers reels : domaines.yml 6->3,
applications.yml 27->5, serveurs.yml 18->3. Quarante lignes, detruites
par n importe quel clic sur Sauvegarder dans les vues Serveurs,
Applications ou Domaines. Parmi elles, celle qui explique pourquoi
backup-01 a ete retire, et celle qui dit dans quel ordre les deux roles
du runner s appliquent. C etait l incident du 2026-08-18, jamais corrige
pour les registres du plan. Les quatre passent par _ecrire_registre :
aller-retour a vide identique a l octet, sur les quatre fichiers.
TROIS ECARTS DE SCHEMA, trouves en confrontant le schema aux VALIDATEURS
et non aux seuls plans :
- edge designe un GROUPE, pas un hote. Le schema disait serveurs : un
formulaire genere aurait offert une valeur qu aucun hote ne reconnait,
donc aucun SAN, donc la panne du 2026-08-25 reintroduite ;
- exposition, entierement valide par le moteur, manquait au schema ;
- liens etait items: {type: object} — une liste d objets sans forme.
Et mail, offert par la vue Domaines depuis sa creation, decrit ici comme
un booleen, saisi la-bas comme du texte, lu par rien : retire.
P62 garde tout ca. Elle separe l entite du reste mecaniquement : un
validateur lit son entite par des variables LOCALES, les autres registres
par ses PARAMETRES. Controle negatif rejoue.
LES FORMULAIRES. Serveurs de BD et Domaines sont generes, chargement et
sauvegarde compris. Quatre registres sur six. Le generateur a appris la
liste d objets.
LIMITE : restent serveurs et applications, les deux plus gros ; et je n ai
toujours pas ouvert ces pages dans un navigateur.
make prouver : CONFORME, 61 OK, 0 echec, 1 saute (62 preuves).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
|
|||
| 00a8dc5283 |
wiki : publie, avec la vue Nomenclature
Some checks are pending
verifier / verifier (push) Waiting to run
Temoin de publication mis a jour ; P60 repasse au vert. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 88033f37b8 |
GUI : la vue Nomenclature, et deux fautes que mes bancs ne voyaient pas
Some checks are pending
verifier / verifier (push) Waiting to run
LA VUE. La nomenclature etait le seul registre que le GUI ne savait pas ecrire du tout : ajouter une fonction exigeait d ouvrir le YAML. Elle a sa vue, et son formulaire est GENERE depuis le schema. Deuxieme registre sur six. couverture_gui verifier passe : les 28 champs des plans reels sont editables. Elle n est pas un registre comme les autres : elle decrit la REGLE dont VMID, VLAN, adresse et passerelle se derivent. Chaque fonction montre ce qu elle derive et les VM qui la portent ; l index est montre mais pas editable, parce qu il est alloue par le site ; valider_nomenclature refuse de retirer une fonction encore portee, ou de designer une zone non declaree. DEUX FAUTES, ET POURQUOI MES BANCS NE LES VOYAIENT PAS. Le formulaire des bases, livre la veille, etait casse dans un navigateur. Il lisait data.schema, or il n existe aucun data global : c est une const locale de charger(). ReferenceError a l ouverture, et zone morte dans sauvegarderBases. Je l avais eprouve sous node EN LUI PASSANT data : le banc reproduisait la fonction, pas sa portee. D ou test_rendu_gui.py, qui charge le JS entier dans un DOM simule et dessine les douze vues, avec son controle negatif. Le schema decrivait reservations comme une table de zones ; le fichier reel est un bloc plat. P61 comparait des NOMS aplatis, donc ne voyait rien. Elle compare desormais aussi la FORME. ECRIRE SANS DEPLACER UN COMMENTAIRE. _fusion_chirurgicale remplace le bloc entier des qu une valeur change : quinze entrees compactes devenaient 42 lignes, et le commentaire du poste d exploitation se retrouvait en tete du bloc, ou il affirmait que collab etait le poste d exploitation. Un commentaire deplace n est pas laid, il est faux. _fusion_table edite les tables ligne a ligne ; le diff fait trois lignes. Au passage : sort_keys triait le schema, donc l ordre des cases a l ecran (reserve_max avant reserve_min) ; et _ecrire_index_nomenclature ecrivait encore par write_text, oubliee au passage des ecritures atomiques. LIMITE : deux registres sur six sont generes, et je n ai toujours pas ouvert cette page dans un navigateur. make prouver : CONFORME, 60 OK, 0 echec, 1 saute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 03c628d5e1 |
GUI : le formulaire des bases est GENERE depuis le schema
Etape 3, sur un seul registre — `bases_donnees`, le plus simple et le seul ou observe et editable coincidaient deja. Les cinq autres gardent leurs formulaires ecrits a la main : on ne bascule pas six vues d un coup. CE QUI DISPARAIT DU JAVASCRIPT Huit `<label>` en dur, trois constructions de `<option>`, et la regle qui choisissait la source du consommateur selon la portee. Cette derniere ne vivait que dans le JS ; elle est desormais DECLAREE au schema (`x-source-selon`), donc lisible et gardee. Le formulaire rend exactement les memes huit champs qu avant — verifie en EXECUTANT le moteur sous node avec le schema et des donnees reelles, pas seulement en passant `node --check`. LA BOUCLE EST FERMEE DES DEUX COTES Le chemin de SAUVEGARDE enumerait lui aussi les sept champs en dur. Un champ ajoute au registre serait apparu au formulaire genere et aurait disparu SILENCIEUSEMENT a l enregistrement — le pire des deux mondes. Il derive maintenant du schema, valeurs par defaut comprises (`default`). LA SEPARATION FORME / COHERENCE, MONTREE portee=groupe + consommateur APPLICATION -> REFUSE par valider_bases portee=application + consommateur app -> ACCEPTE secret absent -> REFUSE Le schema a rempli la FORME (les defauts `groupe` et `principale` se sont poses), le validateur a attrape l INCOHERENCE. Aucune de ces trois regles ne s exprime en JSON Schema, et vouloir l y mettre creerait la seconde source de verite que ce depot refuse. CHAMPS_ECRITS_PAR_GUI COMMENCE A DISPARAITRE Renomme CHAMPS_ECRITS_A_LA_MAIN, et `bases_donnees` en est SORTIE : sa couverture se derive du schema. P19 lit desormais `champs_ecrits_par_gui()`, qui reunit les deux. Le jour ou la table sera vide, elle gardera un mecanisme au lieu d une liste. UNE GARDE A CORRIGER AU PASSAGE `declaration_derive()` verifiait que chaque champ declare apparait dans le SOURCE du GUI. Pour un registre genere il n y apparait plus — c est le but. Elle aurait crie sur precisement le progres qu elle devait constater. Les registres generes en sont exemptes : c est P61 qui tient la promesse pour eux. make prouver : CONFORME, 60 OK, 0 echec, 1 saute. P07 (node --check), P19 (couverture), P61 (schema) : verts. Reste : les cinq autres vues, et le trou de la nomenclature — que le passage au generateur fermera par construction, puisque le schema decrit deja `categorie` et `service`. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 0eaceb1048 |
schema du plan : la forme des registres devient derivee, et gardee
Etape 2 du chantier « l UI reflete fidelement la structure ». Le GUI porte CHAMPS_ECRITS_PAR_GUI, une liste tenue A LA MAIN de ce qu il sait ecrire, que P19 confronte au reel. C est une copie — gardee, donc honnete, mais une copie : quelqu un doit penser a l allonger. `make schema` produit docs/audit/schema-plan.json : six registres, 42 champs, leurs types, leurs enumerations et ce qui est requis. CE QUE LE SCHEMA EST, ET CE QU IL N EST PAS schema -> la FORME -> generera les champs du formulaire validateurs -> la COHERENCE -> refusent une saisie incoherente Un JSON Schema ne sait pas dire qu un `consommateur` designe une application inexistante, ni qu une integration universelle recopiee au plan est un defaut. Vouloir l y mettre creerait la seconde source de verite que tout ce depot refuse. Les valider_* restent l autorite. LES ENUMERATIONS SONT IMPORTEES, JAMAIS RECOPIEES ETATS_SERVEUR, PORTEES_BD et AUTORITES_DNS viennent des constantes que les validateurs appliquent. Une enumeration recopiee diverge — c est la lecon des neuf resolutions d instance que P41 garde depuis. CE QUE L ETAPE 1 AVAIT TROUVE, ET QUE P61 A CONFIRME Le recensement montrait `categorie` et `service` presents dans TOUS les plans et absents de CHAMPS_ECRITS_PAR_GUI, dont la ligne `nomenclature` est vide : le GUI ne sait pas les editer, l operateur doit ouvrir le YAML. P61 a refuse le premier schema pour cette raison exacte. Les trois tables imbriquees de la nomenclature sont donc DECRITES et non resumees en « object ». 31 champs observes dans l instance courante, 42 decrits par le schema. La difference n est pas du bavardage : observer une instance n est pas un schema. `noeud`, `stockage` et `coeurs` sont legitimes et simplement inutilises ici — un schema derive de l observation les INTERDIRAIT. P61, EPROUVEE DANS LES DEUX SENS fichier genere perime -> REFUSE champ du plan absent du schema -> REFUSE champ decrit mais inutilise au plan -> COMPTE, pas refuse Le troisieme point est delibere : refuser obligerait a retirer du schema un champ valide des que plus personne ne s en sert. Meme mesure que les lacunes nommees de P29. UN DEFAUT DE MON INSTRUMENT, PAYE EN ROUTE P61 comparait des noms a plat quand couverture_gui aplatit les tables imbriquees : elle criait sur un schema correct. L instrument mesurait autre chose que la cible. On aplatit desormais des deux cotes. make prouver : CONFORME, 60 OK, 0 echec, 1 saute. Prochaine etape : generer les formulaires depuis ce schema, et retirer CHAMPS_ECRITS_PAR_GUI. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| 6077b179af |
plan : l ecriture des registres devient atomique — tout, ou rien
Some checks are pending
verifier / verifier (push) Waiting to run
`path.open("w")` TRONQUE avant d ecrire : entre les deux, le fichier est vide.
Une exception dans yaml.safe_dump, un disque plein, un Ctrl-C, et
instance/plan/serveurs.yml reste mutile.
L asymetrie fait la gravite : hosts.yml se regenere d un
make instancier-appliquer, le PLAN ne se regenere de rien. C est la source
unique de verite. Git est le filet, mais encore faut-il savoir qu on est tombe.
TREIZE SITES, UNE SEULE FONCTION
Le defaut n etait pas dans le GUI seul : douze sites dans sept fichiers, dont
les miroirs CLI des MEMES registres. Corriger le GUI seul aurait recree la
divergence que P41 garde depuis les neuf resolutions d instance. La fonction
vit donc dans inventory_rules.py, que les sept importaient deja. Une source,
pas douze.
TROIS DETAILS QUI FONT LA DIFFERENCE ENTRE « CA MARCHE » ET « CA TIENT »
temporaire dans le MEME dossier os.replace n est atomique qu au sein d un
meme systeme de fichiers ; un /tmp sur une
autre partition casserait la garantie sans
rien dire
fsync AVANT le rename sinon le renommage peut atteindre le disque
avant le contenu : au retour d une coupure
brutale, un fichier neuf et VIDE — le defaut
qu on ferme, deplace d un cran
report des droits mkstemp cree en 0600, le plan est en 0664 et
doit rester lisible par le groupe sur les
runners
LE TEST PORTE SON PROPRE CONTROLE NEGATIF
scripts/tests/test_ecriture_atomique.py rejoue D ABORD l ancienne forme et
verifie qu elle DETRUIT. Sans ce controle, « le fichier est intact » ne
prouverait rien — il pourrait l etre parce que rien n a ete ecrit du tout. Une
garantie qu on n a jamais vue echouer n est pas une garantie, c est une
habitude.
Branche sur P02, dont le titre annoncait « inventory_host » alors qu il lance
maintenant trois tests. Corrige au passage.
LA VOUTE DU GUI : VERIFIEE, PAS DE DEFAUT
Le soupcon etait qu executer_flux pose ANSIBLE_VAULT_PASSWORD_FILE (un seul mot
de passe) alors que creer une VM ouvre DEUX voutes depuis « une voute, une cle ».
Eprouve contre deux voutes JETABLES a mots de passe distincts — jamais les
vraies. Les deux variables se CUMULENT : Ansible essaie tous les secrets, et un
PASSWORD_FILE errone n empeche rien. Confirme en sondant l environnement qu une
recette make recoit reellement : le mot de passe saisi ET les cinq cles
calculees par voutes.py.
Ce qui sauve ce chemin n est donc pas le mot de passe saisi, c est
l IDENTITY_LIST que make pose par-dessus. Chacun couvre ce que l autre ne
couvre pas — le PASSWORD_FILE sert le runner qui n a que sa cle, l IDENTITY_LIST
le poste qui les a toutes. Ecrit au-dessus du code, pour que personne ne
« simplifie » en retirant l un des deux.
make prouver : CONFORME, 59 OK, 0 echec, 1 saute.
make instancier : DIFF VIDE, quatre registres relus, droits 664 preserves.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
|
|||
| 6da1032ceb |
positionnement : le gel tient, c est la carte des seuils qui etait fausse
La question « et si on retirait le gel du perimetre ? » a mis les cinq seuils a l epreuve. Deux ne tenaient pas — et les garder etait plus dangereux que le gel lui-meme : une carte des seuils fausse ne fait pas perdre du temps, elle fait FRANCHIR UN SEUIL QUI NE L EST PAS. RBAC — couvert, et par un mecanisme plus fort Trois classes d acteurs aux pouvoirs disjoints existent depuis les runners : le poste de l exploitant, le runner de SITE (materialiser, n entre jamais chez un tenant) et les runners de TENANT (configurer). La separation est CRYPTOGRAPHIQUE — une voute, une cle, 2026-08-28 — pas applicative : c est la presence des fichiers qui borne le pouvoir, jamais une table de permissions qu une faille de l application contournerait. Adopter AWX pour ce besoin serait REGRESSER. Le tableau avait ete ecrit avant que les runners existent. IPAM — sans objet par construction Un IPAM sert a ALLOUER. Ici rien ne s alloue : tout derive du seed. Et cinq preuves tiennent deja ce qu il verifierait — P20 (aucun adressage stocke), P21 (collisions d index), P23 (chevauchement d underlay), P28 (pools), P33 (ports). L adopter remplacerait une propriete PAR CONSTRUCTION par un controle a posteriori. LE SEUIL QUI MANQUAIT : L EMANCIPATION Le GUI ecoute sur 127.0.0.1 avec un jeton de session — un modele mono-utilisateur, juste tant que l exploitant est une personne a son poste. La trajectoire de filiation-emancipation.md mene a plusieurs HUMAINS, aux portees disjointes, sur des machines qui ne sont pas les notres. Ce seuil n appelle pas AWX : les runners portent deja la separation des pouvoirs. Il appelle une decision sur la facon dont le GUI s ouvre a quelqu un d autre, et elle n est pas prise. Un seuil qu on ne nomme pas est un seuil qu on franchit sans le voir. CE QUE LE GEL N INTERDIT PAS Il porte sur les FONCTIONS de type NetBox/AWX, jamais sur les VUES. Montrer a l ecran ce que le moteur sait deja — l ecart des dix devis, l etat du diff entre Sauvegarder et Appliquer, le perimetre sur lequel un check vert a porte, les temoins du genome et lequel a decroche — ne franchit aucun seuil : rien de tout cela n existe dans NetBox ou AWX, parce que rien de tout cela n existe hors de ce modele. Le gel n est pas leve. D-84 le consigne, AGENTS.md suit. make prouver : CONFORME, 59 OK, 0 echec, 1 saute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| cbdc6c523d |
wiki-publier : un wiki vide se clone tres bien, et le garde-fou ne le voyait pas
Some checks are pending
verifier / verifier (push) Waiting to run
En rattrapant origin, sa forge s est revelee porter un wiki VIDE — jamais publie. Avant de viser la forge, la manoeuvre a ete eprouvee contre un depot bare local, comme la premiere fois. LE DEFAUT Le garde-fou ne testait que l ECHEC du clone, alors que son message parle du cas vide : « le wiki doit exister (creer une 1re page dans Forgejo) ». Or un depot vide se clone parfaitement. La recette allait donc au bout et creait une branche `master` — parce que init.defaultBranch vaut master sur ce poste — alors que le wiki deja en service vit sur `main`. Le nom de branche etait DEVINE, et il divergeait d une forge a l autre. Un wiki publie sur la mauvaise branche est un wiki que Forgejo peut ne pas afficher : la publication reussit, la page reste introuvable, et rien ne l explique. LE CORRECTIF Refuser un wiki sans commit, plutot que de choisir a la place de Forgejo. Creer une premiere page dans son interface initialise le wiki avec LA branche qu il attend — il n y a plus rien a deviner. EPROUVE DANS LES DEUX SENS depot bare vide -> REFUSE, avec le geste a faire depot bare non vide -> publie forge eregion reelle -> « deja a jour », temoin depose Le troisieme essai compte autant que le premier : remplacer un defaut par un blocage aurait ete un autre defaut. CE QUE CA LAISSE OUVERT Le wiki d origin reste vide : l initialiser demande une action humaine dans l interface de la forge, que cette cible refuse desormais de contourner. Et le temoin ne nomme qu UNE forge. P60 prouve que le depot n a pas bouge depuis la derniere publication — pas que toutes les forges sont a jour. Tant qu il n y en a qu une de publiee, la distinction ne coute rien ; a deux, il faudra que le temoin porte une liste. make prouver : CONFORME, 59 OK, 0 echec, 1 saute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| e2935edd3d |
wiki : publie, et le temoin le prouve — P60 passe au vert
Some checks are pending
verifier / verifier (push) Waiting to run
La forge servait le wiki du 2026-08-10 : deux unites jamais publiees, vingt et
une differentes. Toute la revision de documentation n existait pas pour qui lit
la forge plutot que le depot.
Publie. Verifie en reclonant : 26 pages sur 26, aucune differente, aucune en
trop, 8 figures. La forge porte 4da68c7, source
|
|||
| c9d31e9a60 |
preuves : trois gardes pour ce que ma lecture ne tiendra pas
Une revision de documentation vieillit comme le reste. Ce qui tient, c est ce
qu une machine verifie — et trois lacunes etaient nommees sans etre gardees.
P58 HABILITATIONS. autorisation.md posait la regle (un service nomme un
GROUPE, jamais une personne, D-66) et meta/acces.yml la portait ; rien ne
la verifiait. P29 gardait les POSITIONS d authentification, personne ne
gardait les DROITS.
Le controle qui porte la preuve est un croisement : une entree
porte_par: role-realm affirme que l habilitation voyage par un role de
realm projete depuis un groupe LDAP. P58 le confronte a serveur_keycloak.
Sans ca, un service annonce une habilitation que rien ne transporte, et l
ecran reste vide sans que personne sache pourquoi.
CE QU ELLE N EXIGE PAS, et c est le point le plus important : que les
groupes nommes existent dans l annuaire. Ce serait contredire le regime du
paragraphe 2 — le depot AMORCE un acces et se retire, les appartenances
appartiennent a une personne. dev et personnel n existent dans aucun code,
et ce n est pas un defaut.
P59 ENUMERATIONS ANNONCEES. Les deux ecarts trouves a la main pendant la
tournee — cinq portes annoncees devant une table de six, huit lignes
renvoyees vers une fiche qui en compte dix — etaient d une forme que P57
ne voit pas.
Ma premiere version a signale CINQ ecarts, et les cinq etaient du bruit :
dans « reprise dans les deux devis : », le nombre qualifie autre chose que
la liste. Cent pour cent de faux positifs — la preuve qui crie sur un cas
sain et qu on apprend a ignorer. Resserree aux deux formes ou le nombre ne
peut compter rien d autre. Etroite et vraie plutot que large et devineuse.
P60 WIKI PUBLIE. Le wiki est publie DEPUIS le depot ; rien ne mesurait l ecart,
et il s est creuse de VINGT-SEPT JOURS en silence. Deux unites jamais
publiees, vingt et une differentes : pour qui lit la forge plutot que le
depot, toute la revision n existait pas.
Le harnais est STATIQUE, zero appel reseau — cloner la forge romprait la
seule propriete qui fasse qu une preuve vaille hors de ce poste. La mesure
passe donc par un TEMOIN que make wiki-publier depose. Amorce avec la
valeur MESUREE : le wiki d eregion porte b6167f2, dont le message dit
source:
|
|||
| 5bc3bceac1 |
documentation : la tournee des 74 documents, parce qu un balayage ne lit pas
Some checks failed
verifier / verifier (push) Has been cancelled
La revision a commence par un balayage par motifs — chemins morts, cibles make absentes, comptes derives. Il a trouve une trentaine d ecarts et rate presque tout le reste : un motif ne voit que ce qui s exprime en motif. make hote-planifier en est l exemple. La cible EXISTE, donc le controle passait au vert. C est une cible depreciee qui refuse et sort en 2, recommandee par AGENTS.md, et qui contredit la REGLE D OR du meme fichier trois ecrans plus haut. Il fallait lire pour la voir. 74 documents lus un par un. 66 corriges, 8 exacts. CE QUI ETAIT FRANCHEMENT FAUX AGENTS.md, la source d autorite, annoncait la flotte pas encore executee contre des VM reelles. Elle a ete rasee et remontee depuis zero trois fois. ecosysteme-chezlepro.md, le document montre a un client, portait la meme phrase : il se sous-vendait gravement. courriel-conception.md s ouvrait sur aucun role n est encore ecrit, au-dessus de son propre paragraphe 1 qui les nomme. autorisation.md se terminait sur rien n est construit alors qu il rapporte des mesures datees du role en fonctionnement. hebergeur-exploitation.md disait rien n est fait d un depot qui existe. filiation-emancipation.md se contredisait a deux ecrans de distance. DES MODELES DECRITS D APRES UN MONDE ANTERIEUR Le resolveur : cinq documents decrivaient un Unbound par VM en opt-in, trois le donnaient en exemple d integration FACULTATIVE — il est universel depuis le 2026-08-24. L adressage de nomenclature-vm.md : reseau unique, VLAN 11-15, VMID a cinq chiffres. Le nommage SDN de sdn-evpn.md contre le code : c est le wiki qui avait raison. CE QUI CASSE AU PREMIER ESSAI Le nom du gabarit dore etait faux a quatre endroits, dont la procedure qui le FABRIQUE et le critere R2 de l epreuve d operateur independant. preparer-un-site-hebergeur.md avertissait qu une VM faite a la main serait detruite : raser derive du plan, il ne la detruira jamais — le risque est l inverse. Un mot de passe d essai en clair dans un depot public. DEUX PREUVES ETENDUES, ET UNE QUI SE TROMPAIT ELLE-MEME P57 couvre les groupes : elle a signale aussitot 29 groupes annonces au-dessus d un tableau qui en cite 40. P29 confronte le tableau de authentification.md aux declarations reelles : 12 annonces, 21 reels. Et P57 imposait un chiffre faux — 56 preuves alors que le depot en porte 57, la conditionnelle vivant hors de tout comptage. Un garde-fou qui fait respecter une erreur ajoute l assurance a l erreur. CE QUI RESTE, ET QU AUCUNE PREUVE NE TIENT Deux comptes trouves a la main. Et une lacune reelle : rien ne garde les meta/acces.yml — ni qu un service web-sso en porte un, ni que le groupe qu il nomme existe. P29 tient les positions d authentification, personne ne tient les habilitations. make prouver : CONFORME, 56 OK, 0 echec, 1 saute. 0 lien mort. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q |
|||
| bebdb84212 |
cles : sortir du poste ce qui n existe qu au poste
Some checks are pending
verifier / verifier (push) Waiting to run
Le code est replique trois fois (eregion, forge du site, patient 0) et les voutes chiffrees y sont aussi — le coffre est solide. Les CLES qui l ouvrent vivaient dans neuf fichiers, 1644 octets, sans copie ailleurs. Poste seul : les mots de passe restic restent lisibles sur les machines vivantes, donc recuperable mais douloureux. Poste + une machine : l etat de cette machine devient illisible. Poste + site : terminal. make cles-recenser montre ce qui sortirait sans rien ecrire — nom, taille, empreinte, JAMAIS le contenu. make cles-exporter chiffre en AES256 puis REDECHIFFRE ce qu il vient d ecrire et compare les empreintes une a une : une sauvegarde de cles qu on n a pas rouverte n est pas une sauvegarde. A lancer par l exploitant lui-meme : gpg demande une phrase de passe, elle ne doit passer ni par un journal ni par le contexte d un assistant. Trois refus, eprouves en les faisant echouer : destination dans l infrastructure (un coffre dont la cle est dedans), archive existante (elle est peut-etre la seule), archive illisible (supprimee). Le premier essai du premier refus etait faux — le shell developpait HOME avant que je le remplace, l instrument mesurait ailleurs que la cible. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on |
|||
| 42becd0c02 |
paquets tiers : passer par le cache du controleur, plus par Internet
Some checks are pending
verifier / verifier (push) Waiting to run
Trois depots tiers etaient en HTTPS, et client_artefacts pose Acquire::https::Proxy DIRECT — sans quoi le cache du site refuse les tunnels et aucun depot tiers n est joignable. La ligne est juste ; sa consequence ne l avait pas ete vue : ces trois depots CONTOURNENT le cache, et chaque VM neuve allait les chercher sur Internet a sa naissance. step-cli et alloy sont poses par des integrations UNIVERSELLES. Sans lien, une machine neuve n obtenait ni son client d autorite ni ses metriques — elle n entrait dans aucun flux chiffre. Dernier obstacle a une reconstruction hors ligne, et il tenait dans un mot. make cacher-paquets tire les 21 deb aux versions epinglees, empreinte SHA256 verifiee depuis l index du depot. Le role partage paquets_tiers les depose et les installe EN UN SEUL appel a apt — il sait resoudre un ensemble de fichiers locaux qui se dependent, la ou paquet par paquet echouerait sur l ordre (Icinga en apporte dix-sept). Six roles branches ; chacun retombe sur le depot distant pour ce que le cache n a PAS fourni, et rien d autre. Eprouve pour de vrai : packages.smallstep.com renvoye vers 127.0.0.1, step-cli desinstalle, cache local efface. Le role rejoue installe 0.30.6-1 depuis le cache et la machine obtient ses certificats. Zero echec. Deux defauts de mon propre outil, trouves en le construisant : Smallstep sert son index NON COMPRESSE (404 sur .gz) donc step-cli n etait jamais mis en cache ; et un depot injoignable faisait continue AVANT d incrementer le total, si bien que le script rapportait 20 sur 20 alors qu il en manquait un. Une garde qui ne peut pas echouer ne garde rien — troisieme fois cette semaine. Corrige puis eprouve en le faisant echouer. Reste hors ligne : NTP externe, et l expedition des alertes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on |
|||
| 4e12c3a802 |
supervision du site, et la panne qui dormait dans un mot
Some checks are pending
verifier / verifier (push) Waiting to run
Le site a son temoin : site-mon-01 (VLAN 36) porte PostgreSQL, Icinga et un relais. Le depot lui rapporte, et son premier verdict fut un vrai defaut — site-mon-01 n avait jamais depose son propre etat. Les trois sont au vert. serveur_backup_verification_locale repasse a true sur le depot : le drapeau ne dit plus on renonce mais verifie ce que tu peux ouvrir . La liste des noeuds attendus derive de l inventaire ou tourne le role, donc du site seul. serveur_postfix gagne un mode relais : un site n heberge aucune boite, il expedie. Directement par sa frontiere — emprunter le MTA d un locataire ferait dependre l hebergeur d un ecosysteme qu il peut outvivre. LA PANNE DE FOND : le modele de routes OPNsense lit enabled ; on lui envoyait disabled=0, un champ ignore. enabled restait a son defaut, ETEINT. Chaque route creee par Set-OPS depuis l origine l etait desactivee — invisible, parce qu une route eteinte EXISTE dans le modele et compte posee . Le rechargement lance pour activer la nouvelle patte a fait reprendre au noyau sa table depuis le modele : 14 routes sur 15 disparues, 11 machines de Chezlepro injoignables le lendemain de sa reconstruction, et le devis toujours vert. Trois corrections empilees : la cause (enabled), la cecite (le plan lit la table du NOYAU et signale absent ou eteint), l inaction (la reconfiguration ne se declenchait que sur un changement du modele). Aussi : un role du site peut enfin en appeler un autre a travers la frontiere — le devis traitait tout pair nomme comme l exterieur . Et nftables_admin_ssh se DERIVE de la carte : recopie a la main, il retardait d une zone, et m a verrouille dehors de la machine que je venais de creer. Reste ouvert : le destinataire des alertes est encore root@localhost. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on |
|||
| cf9abe74b6 |
sauvegarde : le site protege enfin son propre etat
Some checks are pending
verifier / verifier (push) Waiting to run
L hebergeur protegeait l etat de tous ses locataires et pas le sien. Deux choses qu il detient et que personne ne peut regenerer : la racine de son AC, et la forge du genome. Le reste est reconstructible par le code. Preuve faite, pas annoncee : sauvegarde reelle puis restic check et restitution. 13 fichiers pour l AC (root_ca_key et intermediate_ca_key compris), 835 pour la forge. Le site depose avec SON identite, sur le compte restic que serveur_backup lui cree, separe des comptes des locataires par les memes permissions. La cible est derivee du expose de l application qui porte serveur_backup_site : le nom du service, pas une adresse — client_backup_repo la grave dans le chemin de chaque instantane. P36 ne lisait que le plan de l instance montee, donc jamais celui du site — qui detient pourtant le plus. Elle lit desormais les deux. Verifiee en la faisant echouer : integration retiree, la preuve tire. Reste ouvert : personne ne verifie les sauvegardes du site. Le depot tourne avec verification_locale a false (pose pour les locataires, dont il ne peut pas ouvrir les depots) et le site n a pas de supervision. La sauvegarde existe et se restaure ; c est son SILENCE qui n alerte pas encore. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on |
|||
| 0854b2a93c |
reconstruction : quatre defauts que seule une flotte rasee pouvait montrer
Some checks are pending
verifier / verifier (push) Waiting to run
Chezlepro detruite (15 VM, disques compris) et refaite depuis le gabarit minimal. 15/15 hotes, 0 echec ; make valider passe, test de restitution compris. Aucun defaut ne venait de la flotte ni du gabarit. 1. Un avertissement n est pas un echec. Proxmox rend WARNINGS: n pour une tache ABOUTIE ; la garde n acceptait que OK et declarait perdues cinq VM clonees a 100 pourcent. Le message parlait d etat stopped — celui de la TACHE, pas de la VM. 2. client_artefacts se contredisait : son commentaire disait de degrader, son code arretait. L autorite monte en premier, donc avant le cache du locataire : aucun ordre ne pouvait satisfaire la garde. 3. harden-below-nxdomain etendait le NXDOMAIN signe de la racine pour le TLD internal a toute la zone du site, sans jamais interroger l autoritatif. Declencheur : toute question sur un nom absent sous internal, y compris la zone d un autre locataire. Le cache contenait la bonne reponse ET un message negatif ; c est le negatif qui etait servi. aggressive-nsec: no avait semble marcher — c est le redemarrage qui vidait le cache, pas le reglage. 4. Un locataire doit savoir a qui demander la zone de son hebergeur, sans quoi il ne peut plus nommer son depot de sauvegarde. La derivation prenait dns_amorcage pour le resolveur du site : faux chez Technolibre, dont l amorcage est 9.9.9.9. P03 l a attrape avant tout deploiement. Au passage : instancier tentait encore le mot de passe unique d avant la separation des voutes ; comparer echouait en exit 4. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on |
|||
| 3ea0c95492 |
sauvegarde : l etat d un locataire quitte enfin sa propre flotte
Some checks are pending
verifier / verifier (push) Waiting to run
Chezlepro rangeait ses instantanes sur une VM DE SA PROPRE FLOTTE. Raser l ecosysteme pour le reconstruire, c etait raser le filet avec. Le site a son depot ; les neuf detenteurs d etat y deposent ; une restitution est sortie (annuaire LDAP lisible, hors flotte). Isolation par compte Unix, pas par convention : home 0700, cle exclusive, racine partagee a root en 0711 (traversable, non listable). Les deux refus constates. Le site heberge du chiffre : il ne peut ni lire ni ouvrir, d ou la verification deplacee chez le locataire qui detient la cle. Quatre defauts reveles par ce deuxieme usage : - la racine des depots ne peut etre le home de personne (StrictModes rendait Permission denied publickey pour un refus de CHEMIN) - la racine nie le TLD internal, et harden-below-nxdomain etendait ce non a toute la zone sans jamais interroger l autoritatif : aucun locataire ne pouvait nommer un service du site - le gabarit transporte des fichiers de durcissement perimes, et les machines du site ne recoivent jamais ssh_hardening - MaxStartups compte les connexions non authentifiees : un depot de site en voit la somme de ses locataires Constat non corrige : les machines du site ne sont pas durcies. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on |
|||
| 4abf875e5f |
gabarit : q35 n est pas un reglage, c est la raison de la procedure manuelle
Some checks are pending
verifier / verifier (push) Waiting to run
CONSTAT DE L EXPLOITANT, PAYE EN ANOMALIES : convertir une machine deja installee d `i440fx` a `q35` produit une serie de pannes dont chacune ressemble a autre chose qu a sa cause. Ce n est pas une correction, c est une transplantation. LE MECANISME, ECRIT POUR QU ON NE LE REDECOUVRE PAS : `i440fx` est un chipset PCI, `q35` est PCIe. La topologie des bus change, donc les NOMS D INTERFACES PREDICTIBLES changent avec le chemin PCI (enp0s3 -> enp1s0) et la machine perd le reseau ; les chemins de disques bougent ; l ordre d enumeration suit. C EST AUSSI POURQUOI SET-OPS N UTILISE PAS L IMAGE CLOUD OFFICIELLE DE DEBIAN : `genericcloud` est livree configuree pour `i440fx`. Une machine nait `q35`, ou elle ne le sera jamais proprement — et c est ce que l installation depuis l ISO garantit. Ces deux lignes de la procedure n etaient qu une ligne de tableau. Elles portent maintenant leur pourquoi, et le SITE les declare comme DONNEES (cle `gabarit`), plus seulement comme prose. `make gabarit-etat` compare le gabarit reel a ce que le site declare de lui. ON VERIFIE LA SOURCE, PAS CHAQUE COPIE. Ma premiere version gardait le CLONAGE : la propriete s herite, donc verifier chaque clone coute a chaque creation sans rien dire de plus que verifier le gabarit une fois. Retiree. TROIS FOIS J AI DEVINE LA FORME DE LA REPONSE AU LIEU DE LA REGARDER — regex_search a groupe qui rend None, proxmox_vm_info sans `config: current` qui ne rend que l etat. La garde a declare « ? » sur une VM parfaitement conforme : une garde qui crie toujours est pire qu aucune, on apprend a l ignorer. A la demande et non dans `make prouver` : ce controle exige le cluster, que le harnais ne suppose pas joignable. Meme nature que genome-etat et underlay-plan. Controle negatif verifie : declarer i440fx fait echouer, rc=1. make verifier : vert. make prouver : CONFORME, 56 OK, 0 echec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on |
|||
| 9aef3614ab |
gabarit : refabrique, minimal, et puise aux ressources du SITE
Some checks are pending
verifier / verifier (push) Waiting to run
REFABRIQUE (VMID 9006, modeleSetOPS-minimal). Quatre roles au lieu de dix-sept :
qemu_guest_agent, cloud_init, sudo_ansible, ssh_baseline — des conditions
d existence, pas des choix d efficacite. Tout le reste vient du socle, et P56 refuse
qu un role retire ne soit repris par personne.
FABRIQUE CHEZ LE SITE, ET C EST LA DECISION QUI COMPTE. « Les ressources du SITE
font autorite pour tous ses artefacts ; elles servent les tenants jusqu a ce qu ils
s emancipent. »
Il se fabriquait DEHORS : `-i "<ip>,"` ne porte aucun group_vars, donc ni mandataire
ni resolveur. L ancien gabarit allait chercher ses paquets chez Debian et resolvait
chez l ancien LAN — 192.168.10.10, lu sur la VM 99998. Le site avait son cache et
son resolveur, et son propre artefact les ignorait.
Desormais la fabrication DERIVE ses ressources du plan du site (underlay --adresses)
et tourne sur le reseau du genome. PROUVE : dix requetes de 10.0.33.31 servies par
site-cache-01, resolveur pose a 10.0.34.11.
L IDENTITE DU GABARIT VIENT DU SITE, PLUS DU TENANT. `proxmox_clone_vmid_modele`
vivait dans les group_vars de l ecosysteme : deux tenants pouvaient cloner deux
gabarits differents sans que rien ne le dise, et un tenant decidait d un objet dont
descend chaque VM de chaque ecosysteme. Meme mouvement que l INDEX (2026-08-25) : le
site ALLOUE, le tenant RECOIT. Cle `gabarit` du plan du site, lue par
underlay --gabarit.
PIEGE FERME EN CHEMIN : creer-vm passait VMID_MODELE="$SETOPS_VMID_MODELE" a
cloner-vm, or inventory_host.py n emet PAS cette variable. Elle valait donc le VIDE,
et ce vide ECRASAIT la valeur derivee — le gabarit du tenant reprenait la main sans
bruit.
ET UN PIEGE DEJA DOCUMENTE, PAYE UNE TROISIEME FOIS : le chemin du controleur
contient une espace, et `lookup('pipe', ...)` le decoupait. Guillemets.
EPROUVE DE BOUT EN BOUT : VM clonee du gabarit minimal — nom, adresse, machine-id
neuf, cle d hote regeneree, agent invite actif ; puis socle applique dessus,
changed=5, 0 echec, auditd compris. VM d essai retiree.
make verifier : vert. make prouver : CONFORME, 56 OK, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
|
|||
| 2f2323bd3e |
gabarit : minimal — il etait un cache du socle, et il perimait sans le dire
Some checks are pending
verifier / verifier (push) Waiting to run
Il portait DIX-SEPT roles : exactement ceux du socle et du durcissement, que le
deploiement rejoue a l identique. C etait donc un CACHE — et comme tout cache, il
perimait sans le dire.
MESURE : derniere recapture le 2026-08-09, et SIX de ses roles avaient change depuis
— common_packages, cloud_init, ssh_baseline, ssh_hardening, auditd,
nftables_baseline. Rien ne le signalait : le deploiement masquait la derive en
reappliquant tout, donc personne ne pouvait la voir. Aucune preuve du harnais ne
regardait sa fraicheur.
IL NE GARDE QUE CE QUI DOIT EXISTER AVANT QU ANSIBLE PUISSE AGIR :
qemu_guest_agent l agent repond AVANT SSH — P52 s en sert
cloud_init le seul chemin vers la premiere seconde
sudo_ansible la porte par ou tout entre
ssh_baseline le serveur SSH
Ce ne sont pas des choix d efficacite, ce sont des conditions d existence.
CE QUE CA COUTE, ET QUI EST COUVERT : une VM neuve n est plus durcie a la naissance.
Elle nait cependant DERRIERE LE PARE-FEU DE L HYPERVISEUR, policy_in=REJECT arme au
clonage — verifie sur obs-01. La fenetre d exposition est fermee par la fabric, pas
par le gabarit. Mon objection initiale tombait devant la mesure.
P56 GARDE LES DEUX MOITIES. Qu il ne REGROSSISSE pas : un role ajoute recree le
cache, donc la peremption invisible. Et que rien de retire ne soit PERDU : un role
absent du gabarit ET du socle disparaitrait de toutes les machines neuves, sans
erreur ni trace, et la panne arriverait des mois plus tard sur une machine qu on
croyait durcie. Verifie : 14 retires, 14 repris, zero orphelin. Deux controles
negatifs.
make verifier : vert. make prouver : CONFORME, 56 OK, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
|
|||
| 0b653170fa |
emancipation : l instrument de la quatrieme ligne — couper, pas sonder
Some checks are pending
verifier / verifier (push) Waiting to run
docs/filiation-emancipation.md decrit quatre temps et n en outillait que trois. Le
quatrieme est celui qu on oublie : « une emancipation non prouvee est une
emancipation non faite ».
SONDER NE PROUVE RIEN. Verifier que le service local repond ne dit pas si l amont
sert encore — le depot le disait deja du cache : « tant qu internet repond, un apt
update qui reussit ne dit pas d ou vient l octet ». L instrument COUPE donc l amont
et refait marcher la chose.
LE MEME ESSAI REND LES DEUX VERDICTS, et c est ce qui le rend honnete :
coupe, la fonction marche -> EMANCIPE, et c est prouve
coupe, la fonction casse -> PAS EMANCIPE, dependance prouvee REELLE
Le second n est pas un echec de l outil, c est son CONTROLE NEGATIF rendu par la
meme commande. Une preuve d emancipation incapable de montrer la dependance qu elle
mesure ne prouverait rien le jour ou elle passerait au vert.
UN TEMOIN PRECEDE LA COUPURE : la fonction marchait-elle seulement avant ? Sans lui,
une panne preexistante se lirait comme une dependance.
LA COUPURE EST GARANTIE REVERSIBLE : une TABLE nftables dediee, jamais une regle
glissee dans une table existante — elle se retire d un geste et ne peut pas laisser
d etat partiel. Le bloc `always` la retire meme si la mesure echoue ou si le play
est interrompu, et une tache verifie ensuite qu elle a bien disparu.
MESURE LE JOUR DE SA NAISSANCE, les deux verdicts sur du vrai materiel :
obs-01 / resolveur PAS EMANCIPE — plus aucune resolution des la coupure
forge-01 / artefacts EMANCIPE — apt installe, cache du site coupe
Ce second verdict a ete DOUTE puis verifie : apt aurait pu reussir en rejouant des
listes fraiches. Refait avec un dossier de listes NEUF, amont coupe : reussit
quand meme. Le cache sert vraiment son contenu.
make verifier : vert. make prouver : CONFORME, 55 OK, 0 echec.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
|
|||
| e2bc235132 |
audit + timers : deux services en echec sur les quinze machines, muets depuis toujours
`make prouver` disait 15/15 a failed=0. Les machines, elles, portaient chacune trois
unites systemd en echec. Le rapport d Ansible n est pas l etat d une machine.
AUDITD : ONZE REGLES ARMEES, PERSONNE POUR COLLECTER.
Deux fichiers de regles identiques cohabitaient — 99-chezlepro.rules et
99-setops.rules, vestige du renommage du role. augenrules CONCATENE rules.d/ :
Error sending add rule data request (Rule exists)
There was an error in line 16 of /etc/audit/audit.rules
audit-rules echoue, et auditd ne demarre pas — c est sa dependance. Resultat :
auditctl -l affiche onze regles, ce qui donne toutes les apparences d un audit qui
fonctionne, et rien ne les enregistre.
Meme mue que ssh_baseline, meme registre : auditd_fichiers_perimes. On n y ajoute
que des noms qu on a REELLEMENT deposes un jour.
Et `failed_when: false` cachait la panne : quinze machines a failed=0 avec auditd
mort sur les quinze. Un service de securite qui ne demarre pas doit se VOIR.
TIMERS APT-DAILY : UN ETAT D ECHEC RESIDUEL.
Masquer le service pendant que son timer tourne lui fait perdre sa cible ; systemd
le note et le GARDE (Unit to trigger vanished). `state: stopped` n efface pas un
etat failed — seul reset-failed le fait.
Ce n est pas cosmetique : une supervision qui compte les unites en echec compte ces
deux-la pour toujours, et la vraie panne s y noiera. Meme defaut que le journal de
la frontiere noye sous 982 000 entrees.
DIAGNOSTIC FAUX, CORRIGE : j avais lu « masked enabled » dans list-unit-files comme
un etat contradictoire, et construit une reparation pour le defaire. Ces colonnes
sont ETAT puis PRESET — masque avec un prereglage constructeur active est normal.
La reparation a ete annulee avant d etre livree.
make verifier : vert. make prouver : CONFORME, 55 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
|
|||
| a5c9a88f00 |
resolveur du site : le troisieme service prete pendant la jeunesse d un tenant
Apres les paquets (serveur_cache_site) et le genome (serveur_forge_site), les NOMS.
Meme patron : un installateur, un marqueur.
CE QUE CA CORRIGE, mesure sur infra-pki-01, premiere machine a porter l autorite
de Chezlepro :
DNS BLOQUE un tenant resout chez lui, sa requete ne sort pas
443 sortant OK par adresse
apt via le cache OK le mandataire resout a sa place
apt s en sortait ; TOUT LE RESTE ETAIT AVEUGLE AUX NOMS. Versionner la cle de
signature Smallstep a fait passer une tache et l echec s est deplace d un cran : le
depot lui-meme devait etre joint par son nom.
POURQUOI PAS L UNBOUND DE LA FRONTIERE : il tourne sur le boitier sans etre un
service gere, et le plan du site l avait deja ecrit une fois — un processus n est
pas un service. site-dns-01 est deploye par le moteur et verifie par le harnais.
OU VIT LA DERIVATION : dans site_inventaire.py, qui connait le plan du site ET le
registre des tenants. Le role tourne sur une machine qui n a aucune raison de lire
la carte de l hebergeur — la derivation appartient a qui detient les deux sources.
PIEGE DE FILTRE, ATTRAPE EN LE BRANCHANT : _supernets_voisins() EXCLUT l instance
montee (personne n est son propre voisin). Le site sert TOUS ceux qu il heberge — y
compris celui qu on deploie. Reutilise tel quel, il privait de resolution le seul
tenant en cours de montage. On reutilise donc la DECOUVERTE partagee sans son
filtre : deux recensements divergent, deux filtres non.
Le marqueur verifie deux choses : que le resolveur ECOUTE, et que sa liste
d autorisation ADMET reellement les tenants. Sans la seconde, la panne chez le
locataire ressemblerait a un DNS mort alors que c est une ACL.
make verifier : vert. make prouver : CONFORME, 55 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
|
|||
| bb63865a37 |
cles : le terrain etait inoccupable — la cle du tenant nait avec ses machines
Le deploiement lance depuis ops-01 s est arrete au premier geste, sur les quinze
machines a la fois : Permission denied (publickey). Les VM neuves n acceptaient que
la cle de l exploitant. Celle du runner EST declaree au plan, mais c est le SOCLE
qui la depose — et le socle doit etre applique par quelqu un qui peut deja entrer.
Boucle fermee : le tenant recevait un terrain qu il ne pouvait pas occuper.
DEUX CLES, DEUX PORTEES :
la cle du SITE -> sur le SEUL runner du tenant l insemination
la cle du TENANT -> sur TOUTES ses machines il va les configurer
POSER UNE CLE AU CLONAGE N EST PAS ENTRER CHEZ LE TENANT. C est un parametre de
creation, au meme titre que l adresse ou le disque : le site ecrit les conditions
de NAISSANCE, il n ouvre aucune session. Le site n obtient aucun acces sur ces
machines ; seul le runner du tenant en obtient un.
Forme tranchee par l exploitant : le site renseigne le seul runner, qui se charge
de toute sa flotte. Le plancher /etc/hosts suit le meme chemin — ops-01 a le sien
depuis son insemination et resout ses quinze voisines par leur nom.
LA REVOCATION EST HONOREE A LA NAISSANCE : une entree a etat absent n est pas
reposee. Sans cette lecture, une cle retiree de la flotte serait ressuscitee sur
chaque VM creee ensuite — panne lente, silencieuse, invisible au plan.
P55 garde les deux moities : la cle du site ne nait que sur un porteur de
serveur_ops_tenant, et aucune machine ne reste sans celle de son tenant. Une
frontiere tenue a une seule couche n est pas tenue. Deux controles negatifs.
make verifier : vert. make prouver : CONFORME, 55 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
|
|||
| f2f6cccd3e |
clonage : l hyperviseur juge le demarrage, plus le chronometre du module
Quinze VM creees trois a la fois. L une a depasse le delai du module PENDANT QUE
PROXMOX GENERAIT ENCORE SON ISO CLOUD-INIT :
Reached timeout while waiting for starting VM.
Last line in task before timeout: generating cloud-init ISO
Elle a demarre juste apres. flotte-creer a rendu « au moins une VM n a pas ete
creee » alors que les quinze tournaient. CE FAUX ECHEC ARRETE UNE RECONSTRUCTION :
reconstruire enchaine flotte-creer puis deployer-tout.
DEUX CORRECTIONS, LA SECONDE EST LA VRAIE. Delai plus genereux, parce que la
generation d ISO sur stockage partage se met en file quand trois clonages tombent
ensemble. Mais un delai reste un pari : son expiration ne conclut plus rien.
L HYPERVISEUR JUGE, en repondant ce qu il fait tourner — meme principe que P52, ou
l agent invite juge la materialisation a la place d une reponse SSH.
Logique verifiee sur quatre cas : seul running passe ; VM arretee, introuvable et
reponse malformee echouent. Une reponse vide ne passe pas en silence. Rejoue sur
une VM deja en marche : idempotent.
CE QUE LA CREATION DE CETTE NUIT N A PAS PROUVE : les quinze VM ont ete
materialisees DEPUIS LE POSTE, pas depuis le runner du SITE. Le chemin existait —
make inseminer, ecrit la veille — et il n a pas servi. Le poste detient
legitimement la voute du site, donc ce n est pas une faute de pouvoir ; c est une
demonstration qui manque.
make verifier : vert. make prouver : CONFORME, 54 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
|
|||
| 90ea474745 |
inseminer : le geste sort de mes mains et entre dans le depot
Some checks failed
verifier / verifier (push) Has been cancelled
L insemination avait ete conduite A LA MAIN depuis le runner du site — hors du
depot, donc sans preuve. Elle a maintenant sa cible :
make inseminer TENANT=OPS-Chezlepro
TENANT= PLUTOT QUE LE SYMLINK instance : le runner du SITE amorce PLUSIEURS
locataires ; pointer un lien global sur l un d eux le ferait se prendre pour ce
tenant. Il en NOMME un par commande. Ca borne aussi le couplage que creer-vm
imposait en silence — rien ne disait sur quels tenants ce lien pouvait pointer.
L HOTE SE DERIVE : celui qui porte serveur_ops_tenant. Meme critere que le flux
d insemination et que la cle SSH du runner — le meme mot borne les trois pouvoirs.
P54 GARDE LA LIGNE DE PARTAGE la ou elle glisserait sans bruit. Les deux couches
retenues sont les seules qui ne reclament aucun secret. Le jour ou l on en
ajouterait une, le deploiement echouerait chez le tenant sur une valeur vide, et ce
message ne dirait pas qu un POUVOIR a ete franchi. Controle negatif : ajouter
client_pki, la couche suivante, fait echouer la preuve.
UN GARDE-FOU EXISTANT A INTERCEPTE UNE INSEMINATION MAL DIRIGEE. Le make parent
exporte SETOPS_INVENTAIRE ; ma resolution en heritait et visait l inventaire d un
AUTRE ecosysteme. Le refus vient d inventory_rules, pas de la cible — exactement
l erreur qu un runner servant plusieurs locataires commettrait en silence.
make verifier : vert. make prouver : CONFORME, 54 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
|
|||
| 0595bf03c1 |
sonder : rapporter ce qui distingue, au lieu d un echec
Some checks are pending
verifier / verifier (push) Waiting to run
Trois faux diagnostics en une journee, tous dus a l instrument et aucun au composant. curl et bash /dev/tcp ecrasent quatre causes incompatibles dans le meme mot : ouvert, une POLITIQUE qui refuse, une machine ABSENTE, et la frontiere muette. LE MEME CODE DIT DEUX CHOSES SELON LE DELAI, et c est la distinction qui a coute le plus cher : EHOSTUNREACH immediat = pas de route ; le meme apres trois secondes = il n y a pas de machine, c est l ARP qui renonce. Les confondre a fait appliquer un pare-feu pour reparer un vide. est pure, donc gardee par un test qui exige que les deux ne se lisent jamais pareil. LA GARDE ECHOUAIT DU COTE SILENCIEUX. L outil dit par quelle SOURCE le paquet part et refuse de conclure sur une passerelle anycast — le piege qui m a fait declarer muet un REJECT qui emettait bien ses RST. Ma premiere version rendait « pas anycast » quand inventory_rules manquait, c est-a-dire sur un hyperviseur ou l on a copie le seul fichier : precisement la ou le piege se produit. Une garde qui echoue doit crier, pas se taire. ET « NON CONCLUANT » EST UN RESULTAT : sur une source anycast et un silence, l outil ne tranche pas, il dit quoi faire — compter les paquets du cote qui refuse, ou sonder depuis une VM. TCP seulement, et c est dit : UDP n a pas de poignee. Valide contre le reel depuis ops-01 : trois cas sur quatre, le quatrieme attendant deux machines vivantes dans un meme tenant. make verifier : vert. make prouver : CONFORME, 53 OK, 0 echec, 0 saute. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on |
|||
| 4beb7e0724 |
flux : l interne refuse a voix haute, la bordure se tait (P53)
Some checks are pending
verifier / verifier (push) Waiting to run
Decision de l exploitant : block vers l Internet, reject a l interieur, parce que
c est prudent. Ce n est pas le refus qui informe, c est CE QU IL FAIT AU SILENCE :
sous drop partout, un timeout voulait dire aucune machine, aucune route, ou une
politique. Quand la politique parle, il n en reste qu une.
nftables par hote policy drop + reject with icmpx type admin-prohibited
pare-feu Proxmox policy_in = REJECT (POLITIQUE_VM, source unique)
frontiere OPNsense block — INCHANGE, et c est la condition
admin-prohibited ET NON tcp reset : un RST est indiscernable d un port ferme sans
service. La chaine forward reste muette : elle porte le trafic qui TRAVERSE l hote,
et y repondre ferait parler cette machine au nom d une destination qui n est pas
elle.
POURQUOI C EST PRUDENT : l obscurite etait deja nulle a l interieur (chaque machine
porte un /etc/hosts qui liste ses voisines), et la bordure protege le reject —
rien d indeclare ne franchit le perimetre, donc il ne repond jamais a l Internet.
982 000 entrees par jour a la frontiere, dont 82 % un balayage VNC.
LA MESURE A CORRIGE LA MESURE, DEUX FOIS.
Ma preuve interdisait le litteral DROP et a fait echouer un code JUSTE : la
detection d une politique posee AU DATACENTER, qui est un garde-fou. Une preuve qui
interdit un mot au lieu de mesurer une propriete finit par accuser ce qu elle
devrait proteger.
Et l absence parlait deja : EHOSTUNREACH en 3,05 s pour une machine inexistante,
timeout a 6 s pour un refus de la frontiere. Mes deux erreurs de diagnostic ne
venaient pas du drop mais de ma SONDE — curl et bash /dev/tcp ecrasent les deux
dans un meme echec.
Applique : 6 VM en REJECT, 0 creee, 0 retiree. Rien ne se ferme.
Trois controles negatifs verifies.
make verifier : vert. make prouver : CONFORME, 53 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
|