le site pouvait inseminer un locataire, pas se configurer lui-meme

Deux defauts qui s additionnaient, et un message qui accusait le mauvais.

1. Le site n avait AUCUN moyen d autoriser une cle d administration. Un
   locataire declare ssh_baseline_cles_admin ; cote site, rien ne transmettait
   cette liste. Ses machines n autorisaient que la cle de cloud-init.

2. Le rebond etait pose sans condition. Depuis le poste c est juste — aucune
   route directe. Depuis le runner du site, qui vit DANS le site, c est un
   detour qui casse : il doit s authentifier aupres de la frontiere ou sa cle
   n est pas autorisee.

Et OpenSSH rend alors Host key verification failed / Connection closed by
UNKNOWN port 65535 — un message qui accuse les cles d HOTE alors que l echec
est une AUTHENTIFICATION, et sur le SAUTEUR, pas sur la cible.

Le critere du rebond est desormais es-tu une MACHINE du site, pas es-tu dans un
RESEAU du site : le poste porte 10.37.0.17, donc il est dans le reseau
management, et il aurait perdu son rebond alors qu il en a besoin.

L amorcage est circulaire et se rompt par le poste : lui seul entrait, il pose
la cle, le runner est ensuite autonome. Verifie : 5/5 machines du site.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
This commit is contained in:
Daniel Allaire 2026-09-14 10:08:50 -04:00
parent 7348eb93d1
commit 63437b5726

View file

@ -71,6 +71,39 @@ GROUPE_SOCLE = ["serveur_debian", "serveur_durci"]
GROUPE_FLOTTE = "hotes_actifs"
def _controleur_est_une_machine_du_site() -> bool:
"""Le controleur EST-IL l'une des machines que l'underlay declare ?
C'EST LA BONNE QUESTION, ET LA PREMIERE VERSION POSAIT LA MAUVAISE. Elle demandait
« suis-je dans un reseau du site ? » — or le poste de l'exploitant porte `10.37.0.17`,
donc il est dans le reseau `management` du site, et il aurait perdu son rebond alors
qu'il en a besoin : ses paquets arrivent sur une autre patte de la frontiere, avec
d'autres regles.
Etre DANS un reseau du site ne dit rien de ce qu'on peut atteindre. Etre une MACHINE
du site, si : la frontiere les laisse se parler entre elles.
En cas de doute — adresses illisibles, underlay muet — on rend False : poser le rebond
est le comportement d'avant, donc le seul qu'on sache sur. Degrader, jamais deviner.
"""
import subprocess
try:
sortie = subprocess.run(["ip", "-4", "-o", "addr", "show"],
capture_output=True, text=True, timeout=5).stdout
except Exception:
return False
locales = {m.split("/")[0] for ligne in sortie.splitlines() for m in ligne.split()
if "/" in m and m[0].isdigit()}
if not locales:
return False
try:
declarees = {str(h.get("ip")) for h in underlay_mod.hotes(None) if h.get("ip")}
except Exception:
return False
return bool(locales & declarees)
def plan_dir() -> Path | None:
"""Le `plan/` du SITE, a cote de son `underlay.yml` — derive du symlink, jamais redit.
@ -266,7 +299,34 @@ def inventaire() -> dict:
communes["serveur_backup_pubkey"] = str(intrants["backup_pubkey"])
if intrants.get("cle_ssh"):
communes["ansible_ssh_private_key_file"] = intrants["cle_ssh"]
if intrants.get("rebond"):
# LE SITE N'AVAIT AUCUN MOYEN D'AUTORISER UNE CLE D'ADMINISTRATION (2026-09-14).
#
# Un locataire declare `ssh_baseline_cles_admin` dans ses group_vars, et `ssh_baseline`
# les pose sur toute sa flotte. Cote site, rien ne transmettait cette liste : ses
# machines n'autorisaient donc que la cle posee par cloud-init a leur naissance.
#
# CE QUE CA COUTAIT, ET C'EST STRUCTUREL : le runner du SITE ne pouvait entrer sur
# AUCUNE machine du site. Il sait inseminer un locataire — c'est prouve — et il ne
# savait pas configurer l'hebergeur qui le porte. Tout le site avait ete deploye
# depuis le poste de l'exploitant, et rien ne disait que c'etait la seule voie.
if intrants.get("cles_admin"):
communes["ssh_baseline_cles_admin"] = intrants["cles_admin"]
# LE REBOND NE SERT QU'A CELUI QUI EST DEHORS (2026-09-14).
#
# Il etait pose sans condition. Depuis le poste de l'exploitant c'est juste : aucune
# route directe ne mene aux zones du site. Depuis le runner du site — qui vit DANS une
# de ces zones — c'est un detour qui casse : il doit s'authentifier aupres de la
# frontiere, ou sa cle n'est pas autorisee, et OpenSSH rend alors
#
# Host key verification failed.
# Connection closed by UNKNOWN port 65535
#
# un message qui accuse les cles d'HOTE alors que l'echec est une authentification, et
# sur le SAUTEUR, pas sur la cible. Une heure de fausse piste.
#
# ON NE DEMANDE PAS UN INTRANT DE PLUS : le controleur sait ou il est. S'il porte deja
# une adresse dans un reseau du site, il n'a personne a sauter.
if intrants.get("rebond") and not _controleur_est_une_machine_du_site():
communes["ansible_ssh_common_args"] = (
f"-o ProxyJump={intrants['rebond']} -o StrictHostKeyChecking=no")