Beryl::Config::ResolvedHost
Host résolu : résultat d'une recherche dans la Root. Porte le
contexte (société, domaine, groupe éventuel) + la config effective
mergée + un accès direct aux credentials via credentials_for.
Constants
Construit une SSH::Connection prête à l'emploi.
Intervalle des keepalive SSH (s) d'une connexion par proxy_command.
Constructors
Instance methods
freebsd.after_unlock: — actions sur les services qui vivent sur les
données chiffrées (base, site…), jouées dans l'ORDRE par beryl unlock
quand il vient de déverrouiller au moins une unité (au boot, leur
démarrage a échoué : données absentes).
Injecte TOUTES les credentials de la société dans ENV (tous
fournisseurs confondus). Utilisé par les CLI qui peuvent
potentiellement appeler plusieurs APIs (ex: scan --dns qui
touche au DNS provider + compute provider).
Injecte les credentials d'un provider dans ENV (pour les
shards OVH/Scaleway qui lisent leurs variables depuis ENV).
Retourne le nombre de variables posées.
CE host est un bastion (point d'entrée public du vRack). Modèle :
vrack.bastion: true. Fallback legacy : bastion: true top-level.
Bastions du domaine (FQDN triés), posés par Root : replis du rebond.
Nom (court ou FQDN) du bastion par lequel joindre ce host caché, ou nil
(nil si bastion: est un booléen ou absent).
Utilisateur de connexion SSH effectif : user: explicite, sinon le 1er
(ordre ALPHABÉTIQUE) user sudo-capable de freebsd.users (groupe wheel
ou sudo: true), à défaut root. Sur les
hôtes durcis le root SSH est fermé → beryl entre par ce compte. Aligné sur
beryl sync/vrack (qui dérivaient cette logique chacun de leur côté).
Liste ORDONNÉE des users de connexion à tenter (le 1er = connect_user).
Utile aux commandes qui essaient les users en cascade quand la clé du
premier est refusée (parc hétérogène : certains hôtes n'ont pas admin).
- override EXPLICITE
freebsd.user(ouuserracine) → LUI SEUL ; - sinon tous les users sudo-capables (
wheel/sudo:true) defreebsd.users, par ordre ALPHABÉTIQUE — l'ordre de la liste ne porte aucun sens (les listes sont triées parberyl fmt) ; pour imposer un compte,user:; -
rooten dernier recours.
Credentials du (account, provider) pour ce host. Utilisé par les CLI qui font des appels API (rescue, bootstrap, scan…).
ID entier Dedibox (stocké sous dedibox.server_id dans le YAML).
Retourne la valeur sous forme de String pour homogénéité avec
les autres providers ; le parsing Int32 se fait côté
Beryl::Providers::Dedibox#request_rescue.
DNS provider du domaine (qui gère la zone). Peut différer du
provider (hébergeur) — cas typique : zone chez Gandi, serveurs
chez OVH.
Le host a-t-il du chiffrement ZFS (pools data chiffrés OU datasets zroot chiffrés du profil Option I) ? Sert à savoir s'il faut être déverrouillé avant une opération qui ÉCRIT (pkg upgrade…).
Datasets/pools dont la clé doit être chargée pour que les points de
montage chiffrés soient montés (pour vérifier le verrou via keystatus) :
pools data chiffrés + encryptionroot zroot (profil Option I).
FQDN reconstitué : <short_name>.<domaine>. Le groupe
n'apparaît pas (règle figée : pas de rails01.web.example.net).
Exception : si short_name contient déjà un point, c'est un
FQDN externe (nom hébergeur type ns3156789.ip-51-83-6.eu ou
alias DNS qui ne relève pas du domaine acme). On le garde
tel quel — sans quoi on fabriquerait un
ns3156789.ip-51-83-6.eu.example.net qui ne résout nulle part.
Caractéristiques matérielles écrites par beryl scan (bloc top-level
hardware:). nil si jamais scanné. Source de beryl info (hors-ligne).
Chemin de la clé privée SSH à utiliser pour ce host.
Ordre de résolution :
identity_file:explicitement déclaré dans le merge (YAML host, domaine,_account.ymlou_default.yml). Prime.- Résolution par convention beryl depuis
ovh.ssh_key_name: le label côté OVH (ex:user-example-com) est traduit en fichier local<ssh_dir>/philippe.example.com.key. Permet de ne pas dupliquer l'info : la même clé est référencée par son nom côté provider et résolue automatiquement côté disque. - Sinon nil.
SSH::Connectionlancera alors sans-i, et commeIdentitiesOnly=yesest forcé, l'auth publickey échouera avec un message clair (pas de fallback silencieux sur les clés par défaut du shell).
installed: false dans le host.yml → serveur PAS ENCORE installé par
beryl bootstrap (squelette de scan --discover, serveur en attente) :
les commandes de flotte (update, upgrade) le sautent au lieu d'un
refus SSH. Absent = installé (défaut). bootstrap retire la clé.
Nature de la machine : dedicated (défaut, serveur physique) ou vps
(machine virtuelle). Lu dans le champ kind: du merged (héritable du
groupe/domaine). Les commandes qui pilotent l'API « serveur dédié » de
l'hébergeur (rescue, boot-hd, vRack…) refusent un VPS via
Beryl::CLI::MachineKind.refuse_vps, au lieu d'échouer en 404 API.
Image mfsBSD SE construite et publiée par nos soins (ex. release
mfsbsd-se-15.1 de papilip/mfsbsd-se, cf.
docs/mfsbsd-maison.adoc) : mfsBSD est un projet tiers qui peut
tarder (aucune image 15.1) ou s'arrêter (FreeBSD 16). Les trois clés
vont ensemble : mfsbsd_url (adresse complète de l'.iso),
mfsbsd_version (« 15.1 ») et mfsbsd_sha256 (empreinte vérifiée
dans le rescue après téléchargement). Sans mfsbsd_url : détection
de la dernière image officielle sur GitHub, comme avant.
Notes libres de l'opérateur sur ce serveur (clé notes:, texte
multiligne). En CLÉ et non en commentaires : beryl scan --apply
réécrit le fichier et perd les commentaires, mais garde les clés.
OS du host (freebsd, debian, ubuntu, …). Défaut : freebsd (historique beryl). L'architecture ADR-014 prévoit l'extension multi-OS, l'impl actuelle ne câble que FreeBSD.
IP overlay (mesh Headscale) déclarée dans le YAML host
(overlay_ip: 100.64.x.y). Lue par ssh_host quand le mode
transport global est :overlay — cf. Phase 4 de la roadmap
Headscale dans la mémoire roadmap_beryl_headscale.md.
Gamme commerciale OVH (ex. "Advance-2"), écrite par beryl scan à
côté de service_name. nil si jamais scanné (ou non-OVH).
Datacentre OVH écrit par beryl info --refresh / scan --discover
(ovh.datacenter, tel que l'API le donne : gra3, sbg5, rbx8).
Bloc IPv6 routé vers le serveur selon OVH (ovh.ipv6_block, ex.
2001:41d0:364:3e00::/56, écrit par beryl info --refresh).
Passerelle IPv6 déclarée par OVH (ovh.ipv6_gateway, écrite par
beryl info --refresh et scan --discover).
Prix de renouvellement mensuel (HT) écrit par beryl info --refresh
(ovh.price_eur), ou posé à la main. Renvoie une CHAÎNE (ex. "89.99").
Tolère le NOMBRE comme la chaîne : price_eur: 89.99 est lu par YAML
comme un float → as_s? renverrait nil (bug : prix absent du .adoc).
Baie (rack) OVH du serveur, écrite par beryl info --refresh (ovh.rack).
Sert à repérer les serveurs CO-LOCALISÉS (panne baie = perte simultanée).
Service name OVH. Pour un host déclaré, lu dans ovh.service_name.
Pour un host virtuel (serveur neuf) dont provider: ovh est
explicitement résolu ET dont le short_name contient un point
(FQDN hébergeur), on fallback sur short_name.
parallel: N (héritable société/domaine/groupe) : serveurs traités à
la fois par une tâche de flotte (apply, upgrade, os-upgrade) ;
nil = défaut (cf. FleetJob.parallel_for). Une valeur < 1 est ignorée.
Noms des blocs providers présents dans le merged. Utile pour
les messages d'erreur quand provider: n'est pas déclaré.
protected: true dans le host.yml → beryl REFUSE les opérations qui
MODIFIENT le serveur (ex. upgrade --apply). Le dry-run et la lecture
restent autorisés. Pour les hosts sensibles (cible de pentest, serveur
gelé…). Générique — aucun nom d'hôte en dur dans le code.
Provider déclaré dans le merged (ex: "ovh", "scaleway"). Dans
le vocabulaire ADR-014 c'est le compute_provider (où le
serveur est hébergé), distinct du dns_provider du domaine.
Accès générique à un champ du bloc <provider>: (service_name,
server_id, zone, etc.).
proxy_command: : commande de rebond passée telle quelle à ssh
(-o ProxyCommand=…, %h %p compris), PRIORITAIRE sur proxy_jump.
Pour un hôte que le rebond doit joindre depuis une adresse source
précise, ex. l'adresse d'un tunnel IPsec portée par une loopback :
ssh pkg.example.net nc -s 10.255.255.1 %h %p (un ProxyJump sortirait
de l'IP publique du rebond, hors politique IPsec). La commande lancée
lit la config ssh de l'opérateur (~/.ssh/config) : elle n'est pas
hermétique comme la conversion de proxy_jump.
ProxyJump effectif. proxy_jump: explicite prime ; sinon, si bastion: <nom> est posé, on dérive <user>@<nom>.<domaine> (user du saut = celui
de la connexion). nil = connexion directe (cas par défaut).
Rebonds à essayer dans l'ordre : le proxy_jump puis, s'il désigne un
bastion du domaine, les AUTRES bastions (même user du saut) — un bastion
en panne ne coupe pas l'accès (sshd-vrack-only ouvre le 22 à tout le
sous-réseau vRack). Vide pour un host joint en direct.
reboot_group: <nom> (host.yml, héritable domaine/groupe) : les tâches de
flotte (os-upgrade, upgrade) ne traitent JAMAIS deux serveurs d'un
même groupe en même temps — ex. les bastions, un Headscale principal et
son secours. Absent = aucune contrainte.
Connexion au rescue Linux / au serveur en phase de provisioning.
TOUTE commande d'INFRASTRUCTURE (scan, wipe, bootstrap, rescue) doit
l'utiliser plutôt que connection. Deux invariants par rapport à la
connexion de production :
- user = TOUJOURS root (le rescue n'a que root ;
userdésigne l'utilisateur du serveur INSTALLÉ, ex. admin) ; - host =
rescue_ssh_host, donc l'IP PUBLIQUE et JAMAIS le vRack / l'overlay : à ce stade le vRack n'existe pas encore et il n'y a pas de ProxyJump. Un host caché en prod assh_host= IP vRack, morte côté rescue.
Options calquées sur un host fraîchement (re)installé : clé d'hôte inconnue/changeante → on ne bloque pas et on ne pollue pas known_hosts ; BatchMode pour échouer vite plutôt que de bloquer sur un prompt.
Adresse SSH pour les opérations en mode RESCUE (beryl rescue,
beryl wipe, phase rescue de beryl bootstrap).
Le système de secours (rescue Linux) ne dispose QUE de l'IP
publique du serveur : il n'est ni attaché au vRack ni joint à
l'overlay, et n'a pas de ProxyJump. Pour un host CACHÉ, ssh_host
renvoie l'IP vRack (injoignable en rescue) → on l'ignore et on vise
l'adresse publique DNS-résoluble (service OVH) ou l'IPv4 publique.
Pour tout host NON caché, on retombe sur ssh_host à l'identique
(aucun changement de comportement). Surchargable via
rescue_ssh_host: dans le YAML mergé.
Rôle FONCTIONNEL du serveur, libre et court (vpn, backup, web,
apps-crystal…) — clé role: du host.yml. Distinct de l'accès réseau
(bastion / caché / public). nil si non renseigné.
skip_recipes: : recettes héritées (défauts société ou domaine) que
beryl sync ne joue PAS sur cet hôte, ex. [ssh-hardening] sur une VM
dont les comptes d'un tiers doivent garder leur accès. Les dépendances
de la recette écartée ne sont pas tirées non plus.
ssh_config: false (host.yml, héritable domaine/groupe) : host absent des
fichiers de beryl ssh-config — ex. d'anciens serveurs que beryl ne suit
pas, joints par vos propres entrées de ~/.ssh/config. Absent = présent.
Hostname effectif pour SSH.
Ordre de résolution :
- Si transport global =
:overlayEToverlay_ip:présent → cette IP. Use case : tous les CLI beryl appelés avec--transport=overlayparlent au host via le mesh Headscale, avec un port 22 fermé en public (cf. recipesshd-overlay-only). ssh_host:explicite dans le YAML mergé. Prime sur tout le reste sauf l'overlay. Cas d'usage : test local (ssh_host: 127.0.0.1), VPN avec FQDN interne distinct du DNS public, alias DNS provider qu'on veut figer.- Si provider OVH avec
ovh.service_name: on privilégie le FQDN OVH (toujours résoluble en DNS public). - Sinon le FQDN logique (
<short_name>.<domaine>).
Avant le fix du 28 avril 2026 (commit 3b19dfb), ssh_host: du
YAML était silencieusement ignoré sauf pour OVH — incohérent et
bloquant pour tester en local.
Vrai si l'opérateur a déclaré explicitement ssh_host: dans
un YAML du merge. Distingue le cas « override YAML » du cas
« nom de host hébergeur dérivé ». Utilisé par
Beryl.format_ssh_target pour produire un libellé sémantiquement
juste : « fqdn (via 127.0.0.1) » plutôt que « fqdn (= 127.0.0.1
côté local) » qui prêterait à confusion (« local » n'est pas un
provider hébergeur).
Vrai si ssh_host provient d'un provider hébergeur
(typiquement OVH avec ovh.service_name) et diffère du FQDN
logique. Distingue ce cas du cas « override YAML » couvert
par ssh_host_explicit?. Si l'opérateur a posé un
ssh_host: YAML, ce flag est faux même si la valeur diffère
du FQDN — la responsabilité est à l'opérateur, pas au
provider.
Avertissement clé SSH : pour un host OVH, si AUCUNE clé privée n'est
résolue (ni identity_file: explicite, ni ovh.ssh_key_name valide),
beryl se connecterait SANS -i — et comme IdentitiesOnly=yes est forcé,
l'auth publickey échoue par un opaque « Permission denied ». On renvoie ici
un message clair. nil si tout va bien (clé résolue) ou host non-OVH (où
l'absence de clé peut être légitime : test local, autre provider…).
Piège typique : ovh.ssh_key_name rangé sous freebsd: au lieu de la
RACINE → ovh_ssh_key_name (qui lit le bloc ovh: racine) renvoie nil.
URL d'un binaire storcli64 (Linux) à récupérer dans le rescue pour
piloter un contrôleur RAID matériel (MegaRAID…). Le rescue OVH ne
fournit aucun outil contrôleur → beryl le curl depuis ici. Hébergé
par nos soins (ex. release acme/infra-bin). nil = pas de
reconstruction RAID possible (seule l'option « volume tel quel »).
Vrai si l'IP est déjà déclarée DANS la section vrack: (≠ fallback legacy).
Sert à beryl vrack pour ne consolider l'IP que si elle n'y est pas (et ne
pas écraser une LISTE de rotation).
1ʳᵉ IP vRack (primaire), ou nil si le host n'est pas sur le vRack.
Source de vérité du DNS interne (Beryl::VrackZone) et de ssh_host
quand le host est caché.
IP vRack du host, source de vérité du DNS interne (Beryl::VrackZone).
Lue d'un champ explicite vrack_ip: ou, à défaut, des arguments de la
recette vrack-interface dans apply_recipes: ({ ip: 192.168.42.x }).
nil si le host n'est pas sur le vRack.
IP(s) vRack normalisées en LISTE (1ʳᵉ = primaire, suivantes = alias /
rotation). Source : network.vrack_ip (scalaire OU liste). Fallback
legacy : vrack_ip: top-level puis recette vrack-interface.
Vrai si le RÔLE réseau est déjà déterminé (proxy_jump ou bastion
posé — section vrack: ou fallback legacy top-level). Sert à beryl vrack : on n'ouvre le chooser de rôle que si le rôle est encore inconnu
(re-poser la question quand il est déjà fixé n'apporte rien).
Réseau du vRack (vrack.subnet, ex. 192.168.42.0/24 ; héritable, en
général dans le _defaults.yml du domaine), ou nil. Sert au contrôle du
plan d'adressage (beryl info).
Zone DNS interne du vRack (vrack.zone, héritable), vrack.internal
par défaut (cf. Beryl::VrackZone).