Commit graph

10 commits

Author SHA1 Message Date
84b5ecc71d frontiere posee, et cinq sondes qui disaient faux
Application de ce que l entree precedente avait prepare : 49 regles creees,
5 retirees. Cibles Prometheus 2/8 -> 8/8, hotes dans Loki 1/7 -> 7/7.

Puis correction de ce que l application a revele. Cinq defauts, tous de la
meme famille : un reglage qui ne suit pas l interrupteur dont il depend.

  - la sonde de Loki interrogeait en HTTPS un Loki servant en clair ;
  - la sonde de la forge visait http:// sur un port 443 chiffre, puis
    validait un certificat emis pour le FQDN en interrogeant 127.0.0.1 ;
  - la sonde du runner comparait six depots a UNE branche quand le plan en
    declare une par depot. Elle contredisait la declaration qu elle etait
    censee verifier : elle n accusait pas la machine, elle s accusait
    elle-meme.

Le tenant restait juste dans les cinq cas. C est le site, qui deploie ces
roles autrement, qui les a tous reveles d un coup.

La sonde des journaux, elle, avait deux defauts a la naissance. Elle criait
une perte deja reparee, faute de dire sur QUELLE fenetre - un ecart sans sa
fenetre n est pas une mesure, c est un nombre. Et elle alertait sur la
cicatrice plutot que sur la plaie : le compteur d Alloy est cumulatif, donc
six machines restaient orange pour toujours. Ce qui alerte est desormais la
CROISSANCE. En echange, un cas muet leve maintenant : zero envoi et zero
rejet n est pas la sante, c est un agent qui ne fait rien.

Enfin, le runner ne pouvait plus cloner le genome. Defaut PREEXISTANT,
revele par le redeploiement et non cause par lui - le diff des regles
generees le montre. generer_nftables(site=True) lisait le plan du TENANT :
derive se resolvait donc a 3000, le port que Forgejo ecoute derriere un
edge, alors que le plan du site dit 443 et explique pourquoi. La forge
ouvrait un port que personne n ecoute et laissait 443 ferme a toute la
flotte.

Mesure finale : Icinga 51/51, Prometheus 8/8, Loki 7/7, prouver 64 OK,
lint 0 defaut sur 82 fichiers. Controles negatifs sur des COPIES des
sondes : les quatre rendent CRITICAL.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 10:27:12 -04:00
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
2026-09-10 02:48:55 -04:00
43666cff6e site : un SITE a bien un plan — et huit defauts que lui seul pouvait reveler
J'ai repete toute la journee qu'un SITE n'est pas un plan. C'etait faux : j'en
reconstruisais un morceau par morceau dans underlay.yml sans le nommer. Ce qui est vrai,
c'est qu'un site ne DERIVE pas — il declare ses adresses parce qu'il EST le terrain — et
ne passe donc pas par `instancier`. Mais ne pas deriver n'est pas ne pas avoir de plan.

SITE-Chezlepro/plan/{10-intrants,serveurs,applications}.yml ; underlay.yml ne garde que
la fabric. Ce qui est MESURE d'un cote, ce qui est VOULU de l'autre. Les groupes viennent
du registre des applications, les gardes ont suivi le plan (4 controles negatifs).

Huit defauts, tous invisibles chez un tenant parce qu'il a toujours tout :
  - client_pki codait `infra-pki-01` EN DUR — vrai par coincidence de nomenclature ;
  - aucun moyen pour un service non-root de lire la cle (Forgejo tourne en `git`) ;
  - le certificat, PUBLIC par nature, restait en 0600 ;
  - l'unite Forgejo n'avait pas d'ExecReload : un cert renouvele aurait ete servi perime ;
  - le role ne savait pas servir TLS lui-meme (il y avait toujours un edge) ;
  - le cert ne couvrait pas le nom de SERVICE, faute d'`expose:` ;
  - les registres se chargeaient en tout-ou-rien : sans domaines.yml, plancher vide ;
  - le flux declarait 3000 en dur.

Le message accusait presque toujours autre chose : le DNS quand c'etait un nom faux, une
permission de fichier quand c'etait un port privilegie, rien du tout quand le plancher
s'ecrivait vide.

ROOT_URL est gravee dans les URL de clonage : la forge sert desormais sur 443, avec
CAP_NET_BIND_SERVICE, et son URL n'a plus de port.

Verifie depuis le reseau : Verify return code 0, https://forge.genese.internal/ -> 200.

42 preuves vertes, flux coherents (34 roles, 92 flux).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 13:15:34 -04:00
bd1b897815 forgejo : apprendre SQLite, et retirer ce qui ne servait pas
Some checks are pending
verifier / verifier (push) Waiting to run
Doute de l'exploitant sur patient 0 : « je doute de la pertinence de pgsql ». Mesure
plutot que discussion.

REDIS NE SERVAIT A RIEN : le role serveur_forgejo ne le mentionne ni dans son app.ini, ni
dans ses defauts, et ne declare aucun lien. Heritage du modele `forge`. Retire du plan.

POSTGRESQL ETAIT EXIGE PAR LE ROLE : DB_TYPE = postgres en dur, resoudre_base sans
condition. Le doute etait fonde, le moteur ne savait pas faire autrement.

INTERRUPTEUR `serveur_forgejo_bd: postgres|sqlite`. En sqlite la base devient un FICHIER
sous serveur_forgejo_data. Ce que ca change ailleurs : rien. Le job de sauvegarde
`serveur_forgejo` emporte deja ce dossier ; PGSSLROOTCERT etait deja conditionne au mode
TLS ; et P35 lit desormais l'interrupteur (convention `<role>_bd`, group_vars de
l'instance puis defaut du role), donc n'attend aucune entree de registre. Une valeur
inconnue est REFUSEE au debut du role plutot que de retomber en silence sur PostgreSQL.

PATIENT 0 PASSE DE SIX A QUATRE MACHINES (Dovecot, Redis, PostgreSQL et sa VM). Sur la
machine dont tout descend, chaque service en moins est une chose de moins a defendre, a
sauvegarder et a rebatir. Et l'effet depasse patient 0 : une offre `forge` pour un petit
organisme cesse d'exiger une VM PostgreSQL.

LA NEUVIEME. En verifiant P35 sur patient 0, elle a rendu un verdict JUSTE SUR LE MAUVAIS
ECOSYSTEME : `plan = RACINE / "instance" / "plan"`, le symlink en dur. Neuvieme resolution
d'instance codee en dur en cinq jours. Ce n'est plus une serie de bogues, c'est une piece
manquante : une resolution unique et partagee, a faire en une fois et de tete reposee.

Enseigne : SQLite au glossaire (P39 l'exige desormais), et le README du role documente
l'interrupteur et ce qu'il ne change pas.

make verifier 40/40 ; make ci 40/40 ; lint et syntaxe du role verts.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-22 13:10:05 -04:00
ffb515cf3c idempotence : Prometheus trie ses cibles, Forgejo conserve son secret JWT
Prometheus : intersect rend un ENSEMBLE, dont l'ordre d'iteration n'est pas
stable d'un processus a l'autre. Le fichier se rendait differemment a chaque
passage — memes cibles, ordre different — et le service redemarrait pour rien.
Trie sur les hotes.

Forgejo : JWT_SECRET est genere par le service et ajoute par lui a la fin
d'app.ini. Le gabarit ne le portait pas, donc chaque rendu l'EFFACAIT et
Forgejo en generait un nouveau. Ce n'etait pas du bruit : chaque deploiement
invalidait les jetons OAuth2 emis par la forge. Le role le relit et le repose ;
meme empreinte avant/apres, changed=0 aux 2e et 3e passages.

Trois erreurs de methode de ma part dans cette enquete :
- conclu « diff vide donc contenu identique » alors que no_log masquait le diff
- applique un replace sur le gabarit SANS verifier qu'il avait pris (la section
  [oauth2] n'existait pas), affiche un succes, et interprete trois passages sur
  cette base
- garde une expression Jinja indiagnosticable en place a cause de no_log

Verifier l'effet, pas l'intention — un replace qui ne trouve rien reussit
silencieusement, exactement comme kcadm -s sur une map.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 14:44:03 -04:00
6a62f0a4c7 authentification : SSO Keycloak devant, secours par sudo, formulaire local fermé
Directive : toute authentification web passe par Keycloak, LDAP est la source
unique des comptes, chaque service garde un accès de secours par sudo sur
l'hôte. Les trois sont indissociables — la chaîne service → Keycloak → LDAP est
en série, donc sans secours une panne exclut tout le monde, y compris pour
réparer. Portée : le web seulement ; IMAP/SMTP se lient à LDAP directement et
SSH est en clé seule.

Posture <rôle>_connexion_locale, false par défaut. Le compte local existe — il
ne peut pas dépendre de Keycloak — mais son formulaire n'est plus proposé au
repos : ouvert en permanence, il contourne la politique de mot de passe, le MFA
et surtout la révocation centrale.

Vérifié auprès de l'amont, puis par rendu réel des gabarits dans les deux
postures :
- Grafana  GF_AUTH_DISABLE_LOGIN_FORM  → ferme ;
- Forgejo  ENABLE_INTERNAL_SIGNIN + ENABLE_BASIC_AUTHENTICATION → ferme, API
  Basic comprise. N'existe que depuis la v10 (ticket amont 7476) ; le rôle
  épingle 10.0.0 et un assert refuse la fermeture en deçà, car le réglage serait
  ignoré sans erreur ;
- Nextcloud hide_login_form → MASQUE seulement : ?direct=1 reste le chemin de
  secours documenté par l'amont. Écrit comme tel, sans prétendre à l'équivalence.

Défaut attrapé par le rendu : la condition Forgejo sans `| bool` n'émettait rien
dans aucune posture — une valeur en chaîne est vraie au sens Jinja, la connexion
locale serait restée ouverte en silence.

docs/authentification.md, décisions D-38 à D-41. ansible-lint (production) sans
échec, 28 preuves OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 16:50:36 -04:00
a51ddc6296 Zéro-confiance : Forgejo→PG en verify-full
SSL_MODE=verify-full dans app.ini [database] + PGSSLROOTCERT (root_ca step-ca)
dans l'unité systemd (lib/pq lit l'env). root_ca déjà 0644 (fix client_pki).

Prouvé sur forge-01 : accueil 200, SSL_MODE=verify-full, PGSSLROOTCERT ok,
aucune erreur TLS/DB. Déploiement propre du 1er coup (patron éprouvé).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 18:53:31 -04:00
e9ca943425 Forgejo : identité visuelle Alliance (custom/ officiel, léger)
Branding via le dossier custom/ de Forgejo (mécanisme officiel, résistant
aux MAJ) : accent aurore par variables CSS, logo/favicon étoile, page
d'accueil brandée (home.tmpl), thème sombre, nom + méta. Codifié dans
serveur_forgejo (branding/app_name/theme). Prouvé sur forge-01.

+ CHANGELOG : entrées wiki pédagogique (14 unités) et GUI (boutons cohérents).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
EOF
2026-07-04 15:47:39 -04:00
e214dcf4ed Forgejo au SSO OIDC (2e app SSO) — éprouvé sur forge-01
serveur_forgejo (10.0.0) : PostgreSQL via registre, exposé par l'edge
(auto-dérivé), source OAuth2 vers Keycloak (add-oauth idempotent), client
OIDC forgejo via serveur_keycloak_clients, auto-enregistrement OIDC
(identités depuis l'annuaire seulement).

Prouvé : testmail (LDAP) → « Se connecter avec Chezlepro » → compte
auto-créé, connecté au tableau de bord.

5 bugs de 1er déploiement corrigés : dépendance sendmail→postfix ;
app.ini propriété git (persiste secrets) ; ordre admin/migrations
(flush_handlers + wait_for) ; HTTP_ADDR 0.0.0.0 (edge distant) ;
auto-enregistrement OIDC.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-03 15:52:38 -04:00
Alliance Boreale
3dd3f43ad8 Set-OPS — moteur d'ecosystemes numeriques souverains (Alliance Boreale) 2026-06-24 20:17:46 -04:00