diff --git a/CHANGELOG.md b/CHANGELOG.md index 4131d91..07bcd10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,59 @@ # CHANGELOG — Set-OPS +## 2026-08-30 — La cle de signature est versionnee : une lignee qui se reproduit sans Internet + +**55 preuves.** Le deploiement de Chezlepro depuis son propre runner a franchi le socle et +le durcissement sur les quinze machines, et s'est arrete sur une seule : + +``` +infra-pki-01 : Request failed: +url: https://packages.smallstep.com/keys/apt/repo-signing-key.gpg +``` + +**Un tenant n'a pas de DNS sortant, et c'est voulu.** Il resout chez lui, sa requete ne +traverse jamais la frontiere. `apt` s'en sort par le mandataire du cache — qui resout a sa +place ; `get_url` n'a pas de mandataire. Mesure sur la machine : + +``` +resolv.conf 9.9.9.9, 149.112.112.112 +DNS BLOQUE +443 sortant OK (par adresse) +apt via le cache OK +``` + +Les cinq reprises du role ne pouvaient rien : elles etaient ecrites pour un serveur +**intermittent** (mesure du 2026-08-23), pas pour une resolution fermee. *Une reprise ne +repare que ce qui est passager.* + +### Une dette nommee, appelee + +C'etait ecrit dans `client_artefacts` : *« les depots tiers en HTTPS continuent d'aller en +direct […] la seconde voie est propre et **reste a faire** — et le dire vaut mieux que le +laisser croire »*. Elle a ete appelee le jour ou un ecosysteme s'est reconstruit derriere +une frontiere qui fait son travail. + +**La cle est desormais versionnee**, avec son empreinte et sa procedure de rafraichissement. +Meme idiome que les collections Ansible et les roues Python : le depot porte, la cible +n'ouvre rien. C'est ce qui rend une lignee reproductible **sans Internet**. + +*Ce que ca coute, et qui est ecrit : une rotation amont n'est plus recuperee toute seule. +Elle ne passe pas inapercue pour autant — `apt` refuse alors le depot, bruyamment. Mieux +vaut un refus lisible qu'un telechargement qui reussit depuis n'importe ou.* + +**Trouve en la recuperant** : l'URL publique **redirige** vers `pkgs.infra.smallstep.com`. +Sans suivre les redirections, on obtient un fichier VIDE que rien ne signale — un `curl -f` +sans `-L` rend zero octet et sort en succes. La procedure de mise a jour le dit, parce que +ce piege-la ne se voit qu'au deploiement suivant. + +### Le correctif du pare-feu a tenu + +Plus une seule suspension : les quinze machines ont franchi le durcissement (`ok=66` +chacune, `0 unreachable`) et repris la main apres s'etre armees. C'est la vraie nouvelle +de ce passage — le defaut d'hier soir ne se reproduit plus. + +make verifier : vert. make prouver : CONFORME, 55 OK, 0 echec, 0 saute. + ## 2026-08-30 — Le terrain etait inoccupable : la cle du tenant nait avec ses machines **55 preuves.** Le deploiement lance depuis `ops-01` s'est arrete au premier geste, sur les diff --git a/roles/serveur_step_ca/files/README-cle-smallstep.md b/roles/serveur_step_ca/files/README-cle-smallstep.md new file mode 100644 index 0000000..c9d5105 --- /dev/null +++ b/roles/serveur_step_ca/files/README-cle-smallstep.md @@ -0,0 +1,51 @@ +# La clé de signature du dépôt Smallstep — versionnée, et pourquoi + +``` +pub rsa2048 2021-05-04 [SC] + 35BA A0B3 3E9E B396 F59C A838 C0BA 5CE6 DC63 15A3 +uid Artifact Registry Repository Signer +``` + +## Pourquoi elle est ici et non téléchargée + +**Un tenant n'a pas de DNS sortant, et c'est voulu** — il résout chez lui, sa requête ne +traverse jamais la frontière. `apt` s'en sort par le mandataire du cache, qui résout à sa +place ; `get_url` n'a pas de mandataire. + +Mesuré le 2026-08-30 sur `infra-pki-01`, première machine à porter l'autorité de +certification de Chezlepro : + +``` +Request failed: +url: https://packages.smallstep.com/keys/apt/repo-signing-key.gpg +``` + +La dette était déjà nommée dans `roles/client_artefacts/defaults/main.yml` : *« les dépôts +tiers en HTTPS continuent d'aller en direct […] la seconde voie est propre et reste à +faire »*. Elle a été appelée le jour où un écosystème s'est reconstruit derrière une +frontière qui fait son travail. + +**Ce que ça achète : une lignée qui se reproduit sans Internet.** C'est le même principe +que les collections Ansible et les roues Python — le contrôleur récupère une fois, le +dépôt porte, la cible n'ouvre rien. + +## Ce que ça coûte, et qu'il faut savoir + +Cette clé **expirera ou tournera** un jour. Le dépôt apt échouera alors bruyamment, à la +vérification de signature — un échec clair, pas un silence. C'est le bon sens de la panne : +mieux vaut un refus lisible qu'un téléchargement qui réussit depuis n'importe où. + +## La remettre à jour + +Depuis une machine qui a le DNS (le poste de l'exploitant), **et en suivant les +redirections** — l'URL publique renvoie vers `pkgs.infra.smallstep.com`, et sans `-L` on +récupère un fichier VIDE que rien ne signale : + +```sh +curl -fsSL https://packages.smallstep.com/keys/apt/repo-signing-key.gpg \ + -o roles/serveur_step_ca/files/smallstep-repo-signing-key.asc +gpg --show-keys --with-fingerprint roles/serveur_step_ca/files/smallstep-repo-signing-key.asc +``` + +Comparer l'empreinte à celle du haut de ce fichier avant de committer. Une clé qu'on +remplace sans regarder son empreinte n'est plus une clé, c'est un fichier. diff --git a/roles/serveur_step_ca/files/smallstep-repo-signing-key.asc b/roles/serveur_step_ca/files/smallstep-repo-signing-key.asc new file mode 100644 index 0000000..1e2a71e --- /dev/null +++ b/roles/serveur_step_ca/files/smallstep-repo-signing-key.asc @@ -0,0 +1,19 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsBNBGCRt7MBCADkYJHHQQoL6tKrW/LbmfR9ljz7ib2aWno4JO3VKQvLwjyUMPpq +/SXXMOnx8jXwgWizpPxQYDRJ0SQXS9ULJ1hXRL/OgMnZAYvYDeV2jBnKsAIEdiG/ +e1qm8P4W9qpWJc+hNq7FOT13RzGWRx57SdLWSXo0KeY38r9lvjjOmT/cuOcmjwlD +T9XYf/RSO+yJ/AsyMdAr+ZbDeQUd9HYJiPdI04lGaGM02MjDMnx+monc+y54t+Z+ +ry1WtQdzoQt9dHlIPlV1tR+xV5DHHsejCZxu9TWzzSlL5wfBBeEz7R/OIzivGJpW +QdJzd+2QDXSRg9q2XYWP5ZVtSgjVVJjNlb6ZABEBAAHNVEFydGlmYWN0IFJlZ2lz +dHJ5IFJlcG9zaXRvcnkgU2lnbmVyIDxhcnRpZmFjdC1yZWdpc3RyeS1yZXBvc2l0 +b3J5LXNpZ25lckBnb29nbGUuY29tPsLAjgQTAQoAOBYhBDW6oLM+nrOW9ZyoOMC6 +XObcYxWjBQJgkbezAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEMC6XObc +YxWj+igIAMFh6DrAYMeq9sbZ1ZG6oAMrinUheGQbEqe76nIDQNsZnhDwZ2wWqgVC +7DgOMqlhQmOmzm7M6Nzmq2dvPwq3xC2OeI9fQyzjT72deBTzLP7PJok9PJFOMdLf +ILSsUnmMsheQt4DUO0jYAX2KUuWOIXXJaZ319QyoRNBPYa5qz7qXS7wHLOY89IDq +fHt6Aud8ER5zhyOyhytcYMeaGC1g1IKWmgewnhEq02FantMJGlmmFi2eA0EPD02G +C3742QGqRxLwjWsm5/TpyuU24EYKRGCRm7QdVIo3ugFSetKrn0byOxWGBvtu4fH8 +XWvZkRT+u+yzH1s5yFYBqc2JTrrJvRU= +=QnvN +-----END PGP PUBLIC KEY BLOCK----- diff --git a/roles/serveur_step_ca/tasks/main.yml b/roles/serveur_step_ca/tasks/main.yml index 73b6e52..e956aeb 100644 --- a/roles/serveur_step_ca/tasks/main.yml +++ b/roles/serveur_step_ca/tasks/main.yml @@ -16,47 +16,42 @@ group: root mode: "0755" -# Recuperee UNE FOIS. Sans garde, chaque deploiement recontactait le serveur du -# fournisseur : cinq cles x quatorze hotes = soixante-dix allers-retours externes pour -# des cles deja installees, et autant d'occasions qu'un tiers lent fasse tomber le -# deploiement. Arbitrage rendu le 2026-08-09 : une plateforme souveraine ne depend pas -# de six serveurs etrangers pour redeployer ce qu'elle possede deja. +# LA GARDE « RECUPEREE UNE FOIS » A DISPARU AVEC CE QU'ELLE GARDAIT (2026-08-30). # -# CONSEQUENCE ASSUMEE : une rotation de cle amont n'est plus recuperee toute seule. Elle -# ne passe pas inapercue pour autant — `apt` refuse alors le depot, bruyamment. Pour -# forcer le rafraichissement : supprimer le fichier et rejouer le role. -- name: Cette ressource est-elle deja recuperee ? (Telecharger la cle de signature Sm) - ansible.builtin.stat: - path: "{{ serveur_step_ca_depot_cle_fichier }}" - register: telecharger_la_cle_de_signature_smallste_present +# Elle evitait de recontacter le fournisseur a chaque passage — soixante-dix allers-retours +# externes pour des cles deja installees (arbitrage du 2026-08-09). La cle etant desormais +# VERSIONNEE, il n'y a plus d'aller-retour a eviter : `copy` ne sort pas, et son +# idempotence vient de la comparaison d'empreintes, pas d'un `stat` qu'on ecrit soi-meme. +# +# Le meme arbitrage est donc honore plus completement : la plateforme ne depend plus du +# tout de serveurs etrangers pour redeployer ce qu'elle possede deja. -- name: Telecharger la cle de signature Smallstep - # UN SERVEUR TIERS QUI REPOND UNE FOIS SUR DEUX NE DOIT PAS ARRETER UN DEPLOIEMENT DE - # QUARANTE MINUTES (mesure du 2026-08-23, premier deploiement de patient 0). - # - # `packages.smallstep.com` est intermittent : la meme URL pend au premier essai et rend - # 200 en 0,48 s au second. Le defaut de `get_url` est un delai de 10 secondes et AUCUNE - # reprise — le socle echouait donc sur la premiere machine, avant meme d'avoir pose le - # resolveur des autres. - # - # Mesure faite avant d'accuser : DNS resolvait, la poignee TLS aboutissait - # (`Verify return code: 0`), un transfert de 138 Ko depuis deb.debian.org passait en - # 0,09 s, et le chemin acceptait 1450 octets et refusait 1500 — exactement l'attendu en - # overlay. Le reseau n'y etait pour rien. - # - # Meme idiome que les roles Keycloak et Forgejo devant leurs propres tiers. - when: not telecharger_la_cle_de_signature_smallste_present.stat.exists - ansible.builtin.get_url: - url: "{{ serveur_step_ca_depot_cle_url }}" +# LA CLE DE SIGNATURE EST VERSIONNEE, PLUS TELECHARGEE (2026-08-30). +# +# Elle etait tiree de `packages.smallstep.com` par son NOM. Un tenant n'a pas de DNS +# sortant — il resout chez lui, sa requete ne traverse jamais la frontiere — et +# `get_url` n'a pas de mandataire, la ou `apt` s'en sort par le cache qui resout a sa +# place. Mesure sur `infra-pki-01`, premiere machine a porter l'autorite de Chezlepro : +# +# Request failed: +# +# Les cinq reprises de l'ancienne version ne pouvaient rien : elles etaient ecrites pour +# un serveur INTERMITTENT (mesure du 2026-08-23), pas pour une resolution fermee. Une +# reprise ne repare que ce qui est passager. +# +# MEME IDIOME QUE LES COLLECTIONS ET LES ROUES : le depot porte, la cible n'ouvre rien. +# C'est ce qui rend une lignee reproductible sans Internet. Empreinte, raison et +# procedure de mise a jour dans `files/README-cle-smallstep.md`. +# +# `serveur_step_ca_depot_cle_url` reste declaree : elle documente la provenance et sert +# a rafraichir le fichier depuis un poste qui a le DNS. Elle n'est plus lue au deploiement. +- name: Poser la cle de signature Smallstep (versionnee, aucun appel sortant) + ansible.builtin.copy: + src: smallstep-repo-signing-key.asc dest: "{{ serveur_step_ca_depot_cle_fichier }}" owner: root group: root mode: "0644" - timeout: 30 - register: serveur_step_ca_cle - retries: 5 - delay: 6 - until: serveur_step_ca_cle is succeeded - name: Ajouter le depot apt Smallstep ansible.builtin.template: