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:
parent
7348eb93d1
commit
63437b5726
1 changed files with 61 additions and 1 deletions
|
|
@ -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")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue