plancher : nommer ce qui est hors de l'ecosysteme
Some checks are pending
verifier / verifier (push) Waiting to run
Some checks are pending
verifier / verifier (push) Waiting to run
Le plancher /etc/hosts ne savait nommer que ce que l'ecosysteme contient. Or un ecosysteme enfant doit atteindre la forge dont il descend, et ce nom-la resout vers l'adresse publique depuis l'overlay -- pas vers l'adresse du LAN, que la frontiere bloque a juste titre. hosts_statiques_externes accueille ces declarations. Le fichier etant regenere integralement a chaque passage, une entree posee a la main ne tiendrait pas. La poignee TCP disait "ouvert" sur l'adresse bloquee alors qu'aucune donnee ne passait -- seule la livraison compte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
7d71f37528
commit
8e125b71cb
3 changed files with 110 additions and 0 deletions
79
CHANGELOG.md
79
CHANGELOG.md
|
|
@ -1,5 +1,84 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 2026-08-23 — Les miroirs du génome, et un nom qui ne résout pas pareil selon d'où on le demande
|
||||
|
||||
La copie du génome sur patient 0 était **figée au jour du poussage**. Elle ne l'est plus :
|
||||
les deux dépôts publics sont désormais des **miroirs** Forgejo, resynchronisés toutes les
|
||||
huit heures depuis la forge amont. L'étiquette signée `v2026.08.21` traverse le miroir
|
||||
intacte — vérifié `SSH SIGNATURE` présente sur le dépôt reconstruit.
|
||||
|
||||
Les trois dépôts privés attendent un jeton amont en **lecture seule**. Le premier jeton
|
||||
fourni pouvait ÉCRIRE : un `PATCH` sur le dépôt parent a été accepté (HTTP 200), alors que
|
||||
`administration`, `organisation` et `user` rendaient bien 403 — l'instrument était donc
|
||||
fiable, et le verdict aussi. Un enfant qui peut réécrire son parent inverse le sens de la
|
||||
filiation ; le jeton est refusé tant qu'il n'est pas ramené à `read:repository`.
|
||||
|
||||
### Le piège du jour : un nom, deux réponses
|
||||
|
||||
`forge.alliance-boreale.ca` ne résout pas pareil selon l'endroit d'où on le demande :
|
||||
|
||||
```
|
||||
depuis le poste d'administration -> 192.168.14.66 (LAN de l'hébergeur)
|
||||
depuis l'overlay de patient 0 -> 69.70.26.51 (adresse publique)
|
||||
```
|
||||
|
||||
Et depuis patient 0, **c'est l'adresse publique qui marche** : le tenant a le droit de
|
||||
sortir sur l'internet et pas d'entrer dans le LAN `192.168.x` de son hôte — le
|
||||
default-deny entre les deux mondes, qui fait exactement son travail.
|
||||
|
||||
La mesure, prise depuis `forge-01` :
|
||||
|
||||
```
|
||||
ping 100 octets -> 192.168.14.66 BLOQUÉ (même 100 octets : pas un problème de MTU)
|
||||
ping / https -> internet passe, toutes tailles
|
||||
curl https://69.70.26.51/api/v1/version -> {"version":"8.0.3"} la vraie forge amont
|
||||
la forge locale de patient 0 -> {"version":"16.0.2"} bien distincte
|
||||
8 essais sur 8 -> HTTP 200 en ~6,7 ms (retour en épingle local, stable)
|
||||
```
|
||||
|
||||
Et une fois de plus, **la poignée TCP a menti** : `192.168.14.66:443` répondait « ouvert »
|
||||
alors qu'aucune donnée ne passait. Seule la livraison compte.
|
||||
|
||||
### `hosts_statiques_externes` — nommer ce qui est hors de l'écosystème
|
||||
|
||||
Le plancher `/etc/hosts` ne savait nommer que ce que l'écosystème contient. Or un
|
||||
écosystème doit atteindre des noms du dehors, à commencer par la forge dont il descend.
|
||||
Poser l'entrée à la main ne tiendrait pas : le fichier est **regénéré intégralement** à
|
||||
chaque passage du rôle. La déclaration vit donc au plan :
|
||||
|
||||
```yaml
|
||||
hosts_statiques_externes:
|
||||
- ip: "69.70.26.51"
|
||||
noms: ["forge.alliance-boreale.ca"]
|
||||
pourquoi: "forge amont du génome — l'adresse interne est bloquée par la frontière"
|
||||
```
|
||||
|
||||
On épingle l'adresse dont on a **prouvé** qu'elle livre. Si un enregistrement à horizon
|
||||
partagé rendait un jour l'adresse interne, le miroir s'arrêterait sans bruit — et une
|
||||
copie du génome qui vieillit en silence est précisément le défaut que ce dépôt combat.
|
||||
|
||||
### Ce que la conversion a coûté, et pourquoi elle est gardée
|
||||
|
||||
Forgejo ne convertit pas un dépôt ordinaire en miroir : il faut le détruire et le
|
||||
recréer. Trois gardes encadrent donc l'opération, et deux ont mordu pour de bon :
|
||||
|
||||
- **l'amont contient-il déjà le local ?** La première version exigeait l'égalité et a
|
||||
refusé la conversion pour un simple commit de retard. Le bon critère est l'inclusion —
|
||||
`merge-base --is-ancestor`, qui distingue « en retard » (sans risque) de « en avance »
|
||||
(destruction de travail).
|
||||
- **un répertoire résiduel est-il vraiment vide ?** Une migration avortée avait laissé
|
||||
une coquille de `set-ops-public.git` — 0 référence — qui bloquait la suivante avec
|
||||
« Files already exist ». On ne la retire qu'après avoir compté les références.
|
||||
|
||||
Leçon d'outillage, aussi : `no_log: true` avait masqué l'erreur `409` **et** l'avait
|
||||
rendue indéchiffrable. La tâche qui porte le mot de passe reste muette, mais un `debug`
|
||||
séparé rend maintenant le statut et le message.
|
||||
|
||||
### À suivre
|
||||
|
||||
Les hôtes de patient 0 résolvent par Quad9 et **n'interrogent pas leur propre serveur
|
||||
`infra-dns-01`**. L'écosystème fait tourner un résolveur que personne n'utilise.
|
||||
|
||||
## 2026-08-23 — Patient 0 porte le génome : la boucle est fermée
|
||||
|
||||
Les cinq dépôts qui fabriquent la lignée vivent désormais sur la forge de patient 0 —
|
||||
|
|
|
|||
|
|
@ -9,3 +9,25 @@ hosts_statiques_domaine: "{{ domaine_interne | default('') }}"
|
|||
# du DNS. Best-effort : ignoré si le plan n'est pas disponible (ex. préparation du template).
|
||||
hosts_statiques_publier_expositions: true
|
||||
hosts_statiques_expositions: []
|
||||
|
||||
# --- Hôtes EXTERNES à l'écosystème -------------------------------------------
|
||||
#
|
||||
# Le plancher ne savait nommer que ce que l'écosystème contient. Or un écosystème a
|
||||
# besoin d'atteindre des noms du dehors — à commencer par la forge dont il descend.
|
||||
#
|
||||
# LE PIÈGE, MESURÉ LE 2026-08-23. `forge.alliance-boreale.ca` résout vers 192.168.14.66
|
||||
# depuis le poste d'administration, et vers 69.70.26.51 — l'adresse PUBLIQUE — depuis
|
||||
# l'overlay de patient 0, qui ne sait pas l'atteindre de l'intérieur (pas de retour en
|
||||
# épingle). Le clone initial du miroir avait pourtant réussi : la résolution n'est pas
|
||||
# stable, elle dépend du résolveur interrogé. Un miroir qui se synchronise toutes les
|
||||
# huit heures serait tombé dessus tôt ou tard, et le silence aurait duré.
|
||||
#
|
||||
# Poser l'entrée à la main dans /etc/hosts ne tiendrait pas : ce fichier est REGÉNÉRÉ
|
||||
# intégralement à chaque passage du rôle. La déclaration doit donc vivre au plan.
|
||||
#
|
||||
# Format :
|
||||
# hosts_statiques_externes:
|
||||
# - ip: "192.168.14.66"
|
||||
# noms: ["forge.alliance-boreale.ca"]
|
||||
# pourquoi: "forge amont — l'adresse publique est injoignable de l'intérieur"
|
||||
hosts_statiques_externes: []
|
||||
|
|
|
|||
|
|
@ -26,3 +26,12 @@ ff02::2 ip6-allrouters
|
|||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if hosts_statiques_externes %}
|
||||
|
||||
# --- Hôtes EXTERNES à l'écosystème (déclarés au plan) ---
|
||||
# Un nom qui existe hors de l'écosystème peut résoudre vers une adresse PUBLIQUE que
|
||||
# l'écosystème ne sait pas atteindre depuis l'intérieur. Ces entrées le corrigent.
|
||||
{% for ext in hosts_statiques_externes %}
|
||||
{{ "%-15s" | format(ext.ip) }} {{ ext.noms | join(' ') }}{{ (' # ' ~ ext.pourquoi) if ext.pourquoi is defined else '' }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
|
|
|||
Loading…
Reference in a new issue