2026-06-24 20:17:46 -04:00
|
|
|
---
|
|
|
|
|
- name: Exiger les secrets de l'AC (Vault)
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- serveur_step_ca_password | length > 0
|
|
|
|
|
- serveur_step_ca_provisioner_password | length > 0
|
|
|
|
|
fail_msg: >-
|
|
|
|
|
serveur_step_ca_password et serveur_step_ca_provisioner_password
|
|
|
|
|
sont requis (a fournir via Ansible Vault).
|
|
|
|
|
|
|
|
|
|
- name: Assurer le repertoire des trousseaux apt
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: /etc/apt/keyrings
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0755"
|
|
|
|
|
|
step-ca : la cle de signature versionnee — plus aucun appel sortant pour l obtenir
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 : Echec temporaire dans la resolution du nom
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 : 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 (2026-08-23), pas pour une resolution fermee. Une reprise ne repare que
ce qui est passager.
UNE DETTE NOMMEE, APPELEE. client_artefacts le disait : les depots tiers en HTTPS
vont en direct, la seconde voie est propre et RESTE A FAIRE. Elle a ete appelee le
jour ou un ecosysteme s est reconstruit derriere une frontiere qui fait son travail.
La cle est versionnee, avec son empreinte et sa procedure de rafraichissement. 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.
Cout ecrit : une rotation amont n est plus recuperee toute seule, mais elle ne passe
pas inapercue — apt refuse alors le depot, bruyamment.
TROUVE EN LA RECUPERANT : l URL publique REDIRIGE vers pkgs.infra.smallstep.com.
Sans suivre les redirections on obtient un fichier VIDE, et curl -f sans -L sort en
succes. La procedure le dit, parce que ce piege ne se voit qu au deploiement suivant.
Le correctif du pare-feu a tenu : plus une seule suspension, quinze machines a
ok=66 et 0 unreachable.
make verifier : vert. make prouver : CONFORME, 55 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-08-30 12:13:39 -04:00
|
|
|
# LA GARDE « RECUPEREE UNE FOIS » A DISPARU AVEC CE QU'ELLE GARDAIT (2026-08-30).
|
2026-08-09 14:05:25 -04:00
|
|
|
#
|
step-ca : la cle de signature versionnee — plus aucun appel sortant pour l obtenir
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 : Echec temporaire dans la resolution du nom
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 : 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 (2026-08-23), pas pour une resolution fermee. Une reprise ne repare que
ce qui est passager.
UNE DETTE NOMMEE, APPELEE. client_artefacts le disait : les depots tiers en HTTPS
vont en direct, la seconde voie est propre et RESTE A FAIRE. Elle a ete appelee le
jour ou un ecosysteme s est reconstruit derriere une frontiere qui fait son travail.
La cle est versionnee, avec son empreinte et sa procedure de rafraichissement. 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.
Cout ecrit : une rotation amont n est plus recuperee toute seule, mais elle ne passe
pas inapercue — apt refuse alors le depot, bruyamment.
TROUVE EN LA RECUPERANT : l URL publique REDIRIGE vers pkgs.infra.smallstep.com.
Sans suivre les redirections on obtient un fichier VIDE, et curl -f sans -L sort en
succes. La procedure le dit, parce que ce piege ne se voit qu au deploiement suivant.
Le correctif du pare-feu a tenu : plus une seule suspension, quinze machines a
ok=66 et 0 unreachable.
make verifier : vert. make prouver : CONFORME, 55 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-08-30 12:13:39 -04:00
|
|
|
# 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.
|
2026-08-09 14:05:25 -04:00
|
|
|
|
step-ca : la cle de signature versionnee — plus aucun appel sortant pour l obtenir
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 : Echec temporaire dans la resolution du nom
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 : 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 (2026-08-23), pas pour une resolution fermee. Une reprise ne repare que
ce qui est passager.
UNE DETTE NOMMEE, APPELEE. client_artefacts le disait : les depots tiers en HTTPS
vont en direct, la seconde voie est propre et RESTE A FAIRE. Elle a ete appelee le
jour ou un ecosysteme s est reconstruit derriere une frontiere qui fait son travail.
La cle est versionnee, avec son empreinte et sa procedure de rafraichissement. 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.
Cout ecrit : une rotation amont n est plus recuperee toute seule, mais elle ne passe
pas inapercue — apt refuse alors le depot, bruyamment.
TROUVE EN LA RECUPERANT : l URL publique REDIRIGE vers pkgs.infra.smallstep.com.
Sans suivre les redirections on obtient un fichier VIDE, et curl -f sans -L sort en
succes. La procedure le dit, parce que ce piege ne se voit qu au deploiement suivant.
Le correctif du pare-feu a tenu : plus une seule suspension, quinze machines a
ok=66 et 0 unreachable.
make verifier : vert. make prouver : CONFORME, 55 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019f91zs9SDdwSzL2CVei6on
2026-08-30 12:13:39 -04:00
|
|
|
# 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: <urlopen error [Errno -3] Echec temporaire dans la resolution du nom>
|
|
|
|
|
#
|
|
|
|
|
# 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
|
2026-06-24 20:17:46 -04:00
|
|
|
dest: "{{ serveur_step_ca_depot_cle_fichier }}"
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
|
|
|
|
|
- name: Ajouter le depot apt Smallstep
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: smallstep.sources.j2
|
|
|
|
|
dest: /etc/apt/sources.list.d/smallstep.sources
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
|
|
|
|
|
- name: Installer step-ca et step-cli
|
2026-07-01 21:44:14 -04:00
|
|
|
when: not ansible_check_mode # dry-run : le depot Smallstep n'est pas reellement ajoute
|
2026-06-24 20:17:46 -04:00
|
|
|
ansible.builtin.apt:
|
|
|
|
|
name: "{{ serveur_step_ca_paquets }}"
|
|
|
|
|
state: present
|
|
|
|
|
update_cache: true
|
|
|
|
|
|
|
|
|
|
- name: Creer l'utilisateur systeme step
|
|
|
|
|
ansible.builtin.user:
|
|
|
|
|
name: "{{ serveur_step_ca_utilisateur }}"
|
|
|
|
|
system: true
|
|
|
|
|
home: "{{ serveur_step_ca_steppath }}"
|
|
|
|
|
create_home: false
|
|
|
|
|
shell: /usr/sbin/nologin
|
|
|
|
|
|
restauration : la reconstruction remet l'etat de l'incarnation precedente
Chaque role proprietaire (AC, bases, annuaire, Nextcloud, rspamd/DKIM,
courriel, forge, web) remet son etat au moment ou il le creerait neuf,
depuis le dernier instantane anterieur a la naissance de la machine.
La sauvegarde refuse de deposer tant qu'un etat d'avant attend.
Outil de noeud setops-restaurer ; cibles sauvegarder-maintenant,
restauration-etat, restauration-renoncer ; test_restauration.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 02:39:22 -04:00
|
|
|
# L'AC NE RENAIT PAS SI ELLE A DEJA VECU (2026-09-30).
|
|
|
|
|
#
|
|
|
|
|
# `step ca init` fabriquait une racine neuve a chaque reconstruction : toute confiance
|
|
|
|
|
# accordee a l'ancienne (postes, navigateurs, autres ecosystemes) tombait sans bruit.
|
|
|
|
|
# Technolibre a change de racine le 2026-09-30, Chezlepro le 2026-09-13.
|
|
|
|
|
#
|
|
|
|
|
# C'est ICI, avant l'init, que l'AC d'une incarnation precedente doit revenir : ensuite,
|
|
|
|
|
# toute la flotte s'enrole aupres d'elle comme d'habitude. Plus tard, il faudrait
|
|
|
|
|
# reenroler chaque machine.
|
|
|
|
|
- name: L'autorite a-t-elle deja ete initialisee ?
|
|
|
|
|
ansible.builtin.stat:
|
|
|
|
|
path: "{{ serveur_step_ca_steppath }}/config/ca.json"
|
|
|
|
|
register: serveur_step_ca_ca_json
|
|
|
|
|
|
|
|
|
|
- name: Restauration — l'autorite d'une incarnation precedente ?
|
|
|
|
|
ansible.builtin.include_role:
|
|
|
|
|
name: client_backup
|
|
|
|
|
tasks_from: restaurer.yml
|
|
|
|
|
vars:
|
|
|
|
|
client_backup_restaurer_jeu: serveur_step_ca
|
|
|
|
|
client_backup_restaurer_vierge: "{{ not serveur_step_ca_ca_json.stat.exists }}"
|
|
|
|
|
|
|
|
|
|
- name: Restauration — remettre l'autorite (racine, intermediaire, base des emissions)
|
|
|
|
|
changed_when: true
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
argv:
|
|
|
|
|
- /usr/local/sbin/setops-restaurer
|
|
|
|
|
- fichiers
|
|
|
|
|
- --instantane
|
|
|
|
|
- "{{ client_backup_restauration.instantane }}"
|
|
|
|
|
- --proprietaire
|
|
|
|
|
- "{{ serveur_step_ca_utilisateur }}:{{ serveur_step_ca_utilisateur }}"
|
|
|
|
|
- "{{ serveur_step_ca_steppath }}"
|
|
|
|
|
when: client_backup_restauration.etat == 'a_restaurer'
|
|
|
|
|
|
|
|
|
|
# LES CLES SONT CHIFFREES PAR LE MOT DE PASSE DE L'EPOQUE. La tache suivante reecrit
|
|
|
|
|
# `password.txt` depuis la voute : si la voute a change depuis, step-ca ne demarrerait
|
|
|
|
|
# plus, et l'erreur parlerait de dechiffrement, pas de restauration.
|
|
|
|
|
- name: Restauration — lire les mots de passe restaures
|
|
|
|
|
ansible.builtin.slurp:
|
|
|
|
|
src: "{{ serveur_step_ca_steppath }}/{{ item }}"
|
|
|
|
|
loop: [password.txt, provisioner_password.txt]
|
|
|
|
|
register: serveur_step_ca_mdp_restaures
|
|
|
|
|
no_log: true
|
|
|
|
|
when: client_backup_restauration.etat == 'a_restaurer'
|
|
|
|
|
|
|
|
|
|
- name: Restauration — la voute ouvre-t-elle encore ces cles ?
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- (serveur_step_ca_mdp_restaures.results[0].content | b64decode) == serveur_step_ca_password
|
|
|
|
|
- (serveur_step_ca_mdp_restaures.results[1].content | b64decode) == serveur_step_ca_provisioner_password
|
|
|
|
|
fail_msg: >-
|
|
|
|
|
L'AC restauree ({{ client_backup_restauration.instantane }}) est chiffree par un mot
|
|
|
|
|
de passe que la voute ne porte plus. Remettre les anciennes valeurs de
|
|
|
|
|
vault_step_ca_password / provisioner dans la voute, ou renoncer a cette AC.
|
|
|
|
|
no_log: true
|
|
|
|
|
when: client_backup_restauration.etat == 'a_restaurer'
|
|
|
|
|
|
|
|
|
|
- name: Restauration — acter l'autorite remise
|
|
|
|
|
ansible.builtin.include_role:
|
|
|
|
|
name: client_backup
|
|
|
|
|
tasks_from: acter.yml
|
|
|
|
|
vars:
|
|
|
|
|
client_backup_acter_etat: restaure
|
|
|
|
|
when: client_backup_restauration.etat == 'a_restaurer'
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Creer le repertoire STEPPATH
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ serveur_step_ca_steppath }}"
|
|
|
|
|
state: directory
|
|
|
|
|
owner: "{{ serveur_step_ca_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_step_ca_utilisateur }}"
|
|
|
|
|
mode: "0700"
|
|
|
|
|
|
|
|
|
|
- name: Deployer le mot de passe de l'AC
|
|
|
|
|
ansible.builtin.copy:
|
|
|
|
|
content: "{{ serveur_step_ca_password }}"
|
|
|
|
|
dest: "{{ serveur_step_ca_steppath }}/password.txt"
|
|
|
|
|
owner: "{{ serveur_step_ca_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_step_ca_utilisateur }}"
|
|
|
|
|
mode: "0600"
|
|
|
|
|
no_log: true
|
|
|
|
|
notify: Redemarrer step-ca
|
|
|
|
|
|
|
|
|
|
- name: Deployer le mot de passe du provisioner
|
|
|
|
|
ansible.builtin.copy:
|
|
|
|
|
content: "{{ serveur_step_ca_provisioner_password }}"
|
|
|
|
|
dest: "{{ serveur_step_ca_steppath }}/provisioner_password.txt"
|
|
|
|
|
owner: "{{ serveur_step_ca_utilisateur }}"
|
|
|
|
|
group: "{{ serveur_step_ca_utilisateur }}"
|
|
|
|
|
mode: "0600"
|
|
|
|
|
no_log: true
|
|
|
|
|
|
|
|
|
|
- name: Initialiser l'autorite de certification (une seule fois)
|
2026-07-01 21:44:14 -04:00
|
|
|
when: not ansible_check_mode # dry-run : le binaire step n'est pas encore installe
|
2026-06-24 20:17:46 -04:00
|
|
|
ansible.builtin.command:
|
|
|
|
|
cmd: >-
|
|
|
|
|
step ca init
|
|
|
|
|
--deployment-type standalone
|
|
|
|
|
--name "{{ serveur_step_ca_nom }}"
|
|
|
|
|
--dns "{{ serveur_step_ca_dns }}"
|
|
|
|
|
--address "{{ serveur_step_ca_adresse }}"
|
|
|
|
|
--provisioner "{{ serveur_step_ca_provisioner }}"
|
|
|
|
|
--password-file {{ serveur_step_ca_steppath }}/password.txt
|
|
|
|
|
--provisioner-password-file {{ serveur_step_ca_steppath }}/provisioner_password.txt
|
|
|
|
|
{{ '--acme' if serveur_step_ca_acme | bool else '' }}
|
|
|
|
|
creates: "{{ serveur_step_ca_steppath }}/config/ca.json"
|
|
|
|
|
become: true
|
|
|
|
|
become_user: "{{ serveur_step_ca_utilisateur }}"
|
|
|
|
|
environment:
|
|
|
|
|
STEPPATH: "{{ serveur_step_ca_steppath }}"
|
|
|
|
|
|
|
|
|
|
- name: Deployer l'unite systemd step-ca
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: step-ca.service.j2
|
|
|
|
|
dest: /etc/systemd/system/step-ca.service
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
notify: Redemarrer step-ca
|
|
|
|
|
|
|
|
|
|
- name: Activer et demarrer step-ca
|
2026-07-01 21:01:53 -04:00
|
|
|
when: not ansible_check_mode
|
2026-06-24 20:17:46 -04:00
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: "{{ serveur_step_ca_service }}"
|
|
|
|
|
enabled: true
|
|
|
|
|
state: started
|
|
|
|
|
daemon_reload: true
|
sondes : les cinq qui manquaient le plus (autorite, base, annuaire, zones, edge)
CORRECTION DE COMPTE D ABORD. J avais annonce cinq groupes sans sonde. La
mesure en donne VINGT-SEPT : j avais compte ceux que j avais en tete, pas
ceux que le depot contient. Il en reste vingt-deux.
LES CINQ, PAR ORDRE DE DEGAT SILENCIEUX.
autorite (step_ca) — la plus urgente : nos certificats vivent 24 h, une AC
muette ne casse rien aujourd hui et casse TOUT demain, d un coup, sur les
21 machines. Elle surveille aussi l expiration de la RACINE, que personne
ne regarde parce qu elle vit des annees (relevee a 3642 jours).
base (postgresql) — une VRAIE requete, pas pg_isready : celui-ci dit que
le port repond, pas que la base sert. Plus le compte des connexions : a
saturation, chaque application tombe sans que la base ait l air morte.
annuaire (openldap) — elle COMPTE les entrees. Un annuaire vide repond
success a tout : le mensonge des sauvegardes vides, vert et sans contenu.
zones (powerdns) — un autoritatif sans zone repond NXDOMAIN a tout, ce qui
se lit comme « ce nom n existe pas ».
edge (nginx) — elle valide la configuration SUR DISQUE : nginx sert la
derniere valide, et une configuration cassee ne se voit qu au prochain
demarrage, souvent des mois plus tard.
Les cinq eprouvees vertes sur le sain puis rouges PAR PARAMETRE, sans
toucher a un service.
Etat : 20 sondes sur 19 roles, 23 services distincts, 70 instances, 67 au
vert. Les trois autres sont connues : deux sauvegardes sans donnee a
emporter, et Loki en delai de stabilisation apres redeploiement.
make prouver : CONFORME, 64 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-10 03:47:03 -04:00
|
|
|
|
|
|
|
|
# --- 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.
|
|
|
|
|
- name: Assurer le repertoire des sondes de supervision
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: /usr/local/lib/setops/sondes
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0755"
|
|
|
|
|
|
|
|
|
|
- name: Deposer la sonde « autorite »
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: sonde-autorite.sh.j2
|
|
|
|
|
dest: /usr/local/lib/setops/sondes/autorite.sh
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0750"
|