From be06def899ee4fce670f6bd00cb451762632d2c5 Mon Sep 17 00:00:00 2001 From: Daniel Allaire Date: Wed, 30 Sep 2026 00:23:49 -0400 Subject: [PATCH] armement : le runner retrouve son identite SSH depuis la voute Le runner fabriquait sa paire a sa naissance : reconstruit, il avait une identite que la flotte ne connaissait pas (refuse sur les 13 machines de Technolibre). La cle privee vit dans la voute du locataire ; serveur_ops_tenant la remet et exige que sa cle publique soit declaree au plan (garde eprouvee en defaut). Co-Authored-By: Claude Opus 5.5 --- roles/serveur_ops_tenant/defaults/main.yml | 15 ++++++ roles/serveur_ops_tenant/tasks/main.yml | 56 ++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/roles/serveur_ops_tenant/defaults/main.yml b/roles/serveur_ops_tenant/defaults/main.yml index 4146cb3..e5fb910 100644 --- a/roles/serveur_ops_tenant/defaults/main.yml +++ b/roles/serveur_ops_tenant/defaults/main.yml @@ -87,3 +87,18 @@ serveur_ops_tenant_cle_destination: >- serveur_ops_tenant_sonde_depot: "{{ serveur_ops_tenant_depot }}" serveur_ops_tenant_sonde_voute: >- /opt/setops/{{ serveur_ops_tenant_sonde_depot }}/inventories/principal/group_vars/all/vault.yml + +# --- L'IDENTITE SSH DU RUNNER, CONSERVEE DANS LA VOUTE (2026-09-30) ------------------------ +# +# Le runner fabriquait sa paire de cles a sa naissance (`serveur_ops`). Chaque reconstruction +# de sa VM lui donnait donc une identite NEUVE, que le plan ne connaissait pas : les machines +# du locataire, clonees avec la cle DECLAREE (`ssh_baseline_cles_admin`), le refusaient +# toutes — « Permission denied (publickey) » sur les treize, a la reconstruction de +# Technolibre du 2026-09-30. Chez Chezlepro, la cle declaree etait deja celle d'un runner +# disparu. +# +# La cle privee vit donc dans la voute du locataire ; l'armement — le geste de l'humain — +# la remet au runner neuf, qui retrouve l'identite que la flotte attend. Vide = le runner +# garde la paire qu'il s'est fabriquee (et l'armement le dit). +serveur_ops_tenant_ssh_cle: "{{ vault_runner_cle_ssh | default('') }}" +serveur_ops_tenant_ssh_chemin: "{{ serveur_ops_tenant_racine }}/.ssh/id_ed25519" diff --git a/roles/serveur_ops_tenant/tasks/main.yml b/roles/serveur_ops_tenant/tasks/main.yml index d3fa6ad..14e4cc1 100644 --- a/roles/serveur_ops_tenant/tasks/main.yml +++ b/roles/serveur_ops_tenant/tasks/main.yml @@ -178,6 +178,62 @@ - serveur_ops_tenant_cle_deposer | bool - not ansible_check_mode +# --- L'IDENTITE SSH DU RUNNER (voir defaults/main.yml, 2026-09-30) ---------------------- +- name: Remettre au runner sa cle SSH (conservee dans la voute) + ansible.builtin.copy: + content: "{{ serveur_ops_tenant_ssh_cle | trim }}\n" + dest: "{{ serveur_ops_tenant_ssh_chemin }}" + owner: "{{ serveur_ops_tenant_utilisateur }}" + group: "{{ serveur_ops_tenant_utilisateur }}" + mode: "0600" + no_log: true + when: + - serveur_ops_tenant_ssh_cle | length > 0 + - not ansible_check_mode + +- name: Relire la cle publique qui en decoule + ansible.builtin.command: ssh-keygen -y -f {{ serveur_ops_tenant_ssh_chemin }} + changed_when: false + register: serveur_ops_tenant_ssh_publique + when: + - serveur_ops_tenant_ssh_cle | length > 0 + - not ansible_check_mode + +- name: Poser la cle publique a cote de la privee + ansible.builtin.copy: + content: "{{ serveur_ops_tenant_ssh_publique.stdout.split()[:2] | join(' ') }} setops@{{ inventory_hostname }}.{{ domaine_interne }}\n" + dest: "{{ serveur_ops_tenant_ssh_chemin }}.pub" + owner: "{{ serveur_ops_tenant_utilisateur }}" + group: "{{ serveur_ops_tenant_utilisateur }}" + mode: "0644" + when: + - serveur_ops_tenant_ssh_cle | length > 0 + - not ansible_check_mode + +# LA GARDE QUI AURAIT VU L'ECART AVANT LE DEPLOIEMENT : la cle du runner doit etre une de +# celles que le plan declare, puisque c'est celle-la que chaque machine du locataire recoit +# a sa naissance. Sinon, le runner arme se verrait refuser toute la flotte, tres loin d'ici. +- name: Exiger que la cle du runner soit declaree au plan + ansible.builtin.assert: + that: + - (serveur_ops_tenant_ssh_publique.stdout.split()[:2] | join(' ')) + in (ssh_baseline_cles_admin | default([]) | map(attribute='cle') + | map('split') | map('batch', 2) | map('first') | map('join', ' ') | list) + fail_msg: >- + La cle SSH du runner (issue de la voute) n'est PAS declaree dans + `ssh_baseline_cles_admin` : les machines du locataire, nees avec la cle declaree, le + refuseront toutes. Declarer sa cle publique au plan, ou corriger la voute. + when: + - serveur_ops_tenant_ssh_cle | length > 0 + - not ansible_check_mode + +- name: Dire qu'aucune identite n'est conservee + ansible.builtin.debug: + msg: >- + Aucune `vault_runner_cle_ssh` dans la voute : le runner garde la paire qu'il s'est + fabriquee. Sa reconstruction lui en donnera une autre, que la flotte refusera. + when: serveur_ops_tenant_ssh_cle | length == 0 + # --- Sonde de supervision (docs/supervision-conception.md) -------------------------- # Le role qui possede la verite depose sa propre sonde ; le porteur (`client_sante`) la # fait tourner et pousse le verdict, sans savoir ce qu'elle mesure.