2026-06-24 20:17:46 -04:00
|
|
|
---
|
2026-07-07 06:45:12 -04:00
|
|
|
# L'empreinte du root CA est la SOURCE DE VÉRITÉ de l'autorité elle-même : on la
|
|
|
|
|
# dérive à chaud (robuste au from-zero — une AC régénérée a une empreinte neuve).
|
|
|
|
|
# `client_pki_ca_fingerprint_override` permet d'épingler explicitement si besoin.
|
|
|
|
|
- name: Dériver l'empreinte du root CA depuis l'autorité
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
cmd: "step certificate fingerprint {{ serveur_step_ca_steppath | default('/etc/step-ca') }}/certs/root_ca.crt"
|
|
|
|
|
delegate_to: "{{ groups['serveur_step_ca'][0] }}"
|
|
|
|
|
changed_when: false
|
|
|
|
|
check_mode: false
|
|
|
|
|
register: client_pki_fingerprint_ac
|
|
|
|
|
|
|
|
|
|
- name: Retenir l'empreinte (dérivée de l'AC, sauf override explicite)
|
|
|
|
|
ansible.builtin.set_fact:
|
|
|
|
|
client_pki_ca_fingerprint: "{{ client_pki_ca_fingerprint_override | default(client_pki_fingerprint_ac.stdout | trim, true) }}"
|
|
|
|
|
|
|
|
|
|
- name: Exiger l'empreinte AC et le mot de passe provisioner (Vault)
|
2026-06-24 20:17:46 -04:00
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- client_pki_ca_fingerprint | length > 0
|
|
|
|
|
- client_pki_provisioner_password | length > 0
|
|
|
|
|
fail_msg: >-
|
2026-07-07 06:45:12 -04:00
|
|
|
Empreinte du root CA indisponible (step-ca joignable et déployé ?) ;
|
|
|
|
|
client_pki_provisioner_password requis (via Ansible Vault).
|
2026-06-24 20:17:46 -04:00
|
|
|
|
|
|
|
|
- name: Assurer le repertoire des trousseaux apt
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: /etc/apt/keyrings
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0755"
|
|
|
|
|
|
|
|
|
|
- name: Telecharger la cle de signature Smallstep
|
|
|
|
|
ansible.builtin.get_url:
|
|
|
|
|
url: "{{ client_pki_depot_cle_url }}"
|
|
|
|
|
dest: "{{ client_pki_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-cli
|
|
|
|
|
ansible.builtin.apt:
|
|
|
|
|
name: "{{ client_pki_paquets }}"
|
|
|
|
|
state: present
|
|
|
|
|
update_cache: true
|
|
|
|
|
|
|
|
|
|
- name: Creer le repertoire STEPPATH des certificats
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ client_pki_steppath }}/certs"
|
|
|
|
|
state: directory
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0755"
|
|
|
|
|
|
|
|
|
|
- name: Deployer le mot de passe du provisioner
|
|
|
|
|
ansible.builtin.copy:
|
|
|
|
|
content: "{{ client_pki_provisioner_password }}"
|
|
|
|
|
dest: "{{ client_pki_steppath }}/provisioner.pass"
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0600"
|
|
|
|
|
no_log: true
|
|
|
|
|
|
deployer : l'ordre des couches, et l'autorite qui se signe elle-meme
`make deployer` triait les groupes alphabetiquement apres le socle :
`client_metrique` passait avant `serveur_step_ca`, donc exigeait un certificat
que l'autorite, pas encore deployee, ne pouvait pas avoir emis — sur l'hote de
l'AC lui-meme. `docs/couches-deploiement.yml` existe pour definir cet ordre et
dit « integrations deployees en dernier » ; `make site` le lit, `deployer` ne
l'avait jamais lu. Meme registre desormais.
Deux politiques universelles se contredisaient : `client_pki` exemptait l'AC,
`client_metrique` refuse toute exemption. L'exemption confondait « ne pas
s'enroler » et « ne pas avoir de certificat ». `client_pki` distingue les deux
chemins : bootstrap pour les autres, EMISSION LOCALE sur l'AC. L'exemption
disparait, la doctrine reste.
Effet de bord instructif : `step ca bootstrap` ecrit aussi le defaults.json qui
porte l'URL de l'AC. En sautant le bootstrap on perdait l'information sans le
voir. `--ca-url` et `--root` sont explicites pour tous les hotes.
Mesure : infra-pki-01 et infra-dns-01 entierement deployees, aucun echec,
step-ca health=ok, powerdns resout la zone souveraine, et les deux hotes portent
un certificat de l'AC interne.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 23:57:01 -04:00
|
|
|
# L'AUTORITE EST UN CAS A PART, mais pas une exception. Elle n'a pas a « s'enroler »
|
|
|
|
|
# aupres d'elle-meme : sa racine est deja sur son disque, et un bootstrap la ferait
|
|
|
|
|
# aller la chercher par le reseau, chez elle, en verifiant une empreinte qu'elle vient
|
|
|
|
|
# de produire. Elle a en revanche besoin de CERTIFICATS comme tout le monde — sans quoi
|
|
|
|
|
# ses propres services (node_exporter) restent en clair, et `client_metrique` echoue.
|
|
|
|
|
#
|
|
|
|
|
# La distinction est donc : pas d'enrolement, mais emission locale. C'est ce qui permet
|
|
|
|
|
# de retirer l'exemption de `client_pki` sans contredire « l'AC est la source de la
|
|
|
|
|
# confiance » — elle l'est, et c'est precisement pourquoi elle peut se signer elle-meme.
|
|
|
|
|
- name: Reconnaitre l'hote qui PORTE l'autorite
|
|
|
|
|
ansible.builtin.set_fact:
|
|
|
|
|
client_pki_est_autorite: "{{ inventory_hostname in (groups['serveur_step_ca'] | default([])) }}"
|
|
|
|
|
|
2026-06-24 20:17:46 -04:00
|
|
|
- name: Etablir la confiance dans l'AC interne (bootstrap + installation racine)
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
cmd: >-
|
|
|
|
|
step ca bootstrap
|
|
|
|
|
--ca-url {{ client_pki_ca_url }}
|
|
|
|
|
--fingerprint {{ client_pki_ca_fingerprint }}
|
|
|
|
|
--install --force
|
|
|
|
|
creates: "{{ client_pki_steppath }}/certs/root_ca.crt"
|
|
|
|
|
environment:
|
|
|
|
|
STEPPATH: "{{ client_pki_steppath }}"
|
deployer : l'ordre des couches, et l'autorite qui se signe elle-meme
`make deployer` triait les groupes alphabetiquement apres le socle :
`client_metrique` passait avant `serveur_step_ca`, donc exigeait un certificat
que l'autorite, pas encore deployee, ne pouvait pas avoir emis — sur l'hote de
l'AC lui-meme. `docs/couches-deploiement.yml` existe pour definir cet ordre et
dit « integrations deployees en dernier » ; `make site` le lit, `deployer` ne
l'avait jamais lu. Meme registre desormais.
Deux politiques universelles se contredisaient : `client_pki` exemptait l'AC,
`client_metrique` refuse toute exemption. L'exemption confondait « ne pas
s'enroler » et « ne pas avoir de certificat ». `client_pki` distingue les deux
chemins : bootstrap pour les autres, EMISSION LOCALE sur l'AC. L'exemption
disparait, la doctrine reste.
Effet de bord instructif : `step ca bootstrap` ecrit aussi le defaults.json qui
porte l'URL de l'AC. En sautant le bootstrap on perdait l'information sans le
voir. `--ca-url` et `--root` sont explicites pour tous les hotes.
Mesure : infra-pki-01 et infra-dns-01 entierement deployees, aucun echec,
step-ca health=ok, powerdns resout la zone souveraine, et les deux hotes portent
un certificat de l'AC interne.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 23:57:01 -04:00
|
|
|
when: not client_pki_est_autorite | bool
|
|
|
|
|
|
|
|
|
|
- name: Poser la racine depuis le disque local (l'autorite ne s'enrole pas aupres d'elle-meme)
|
|
|
|
|
ansible.builtin.copy:
|
|
|
|
|
src: "{{ serveur_step_ca_steppath | default('/etc/step-ca') }}/certs/root_ca.crt"
|
|
|
|
|
dest: "{{ client_pki_steppath }}/certs/root_ca.crt"
|
|
|
|
|
remote_src: true
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
when: client_pki_est_autorite | bool
|
2026-06-24 20:17:46 -04:00
|
|
|
|
2026-07-04 18:45:16 -04:00
|
|
|
- name: Rendre le certificat racine lisible par tous (cert public, requis par les clients TLS)
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ client_pki_steppath }}/certs/root_ca.crt"
|
|
|
|
|
mode: "0644"
|
|
|
|
|
|
2026-07-05 18:43:23 -04:00
|
|
|
- name: Lire les SAN du certificat d'hote existant (detection de derive)
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
cmd: "openssl x509 -in {{ client_pki_cert }} -noout -ext subjectAltName"
|
|
|
|
|
register: client_pki_san_actuels
|
|
|
|
|
changed_when: false
|
|
|
|
|
failed_when: false
|
|
|
|
|
|
|
|
|
|
# Re-emet si le cert est absent OU si un SAN voulu manque (ex: nouvelle exposition
|
|
|
|
|
# ajoutee au plan -> client_pki_sans mis a jour). Plus de garde 'creates' aveugle.
|
|
|
|
|
- name: Obtenir / re-emettre le certificat d'hote (absent ou SAN derives)
|
2026-06-24 20:17:46 -04:00
|
|
|
ansible.builtin.command:
|
deployer : l'ordre des couches, et l'autorite qui se signe elle-meme
`make deployer` triait les groupes alphabetiquement apres le socle :
`client_metrique` passait avant `serveur_step_ca`, donc exigeait un certificat
que l'autorite, pas encore deployee, ne pouvait pas avoir emis — sur l'hote de
l'AC lui-meme. `docs/couches-deploiement.yml` existe pour definir cet ordre et
dit « integrations deployees en dernier » ; `make site` le lit, `deployer` ne
l'avait jamais lu. Meme registre desormais.
Deux politiques universelles se contredisaient : `client_pki` exemptait l'AC,
`client_metrique` refuse toute exemption. L'exemption confondait « ne pas
s'enroler » et « ne pas avoir de certificat ». `client_pki` distingue les deux
chemins : bootstrap pour les autres, EMISSION LOCALE sur l'AC. L'exemption
disparait, la doctrine reste.
Effet de bord instructif : `step ca bootstrap` ecrit aussi le defaults.json qui
porte l'URL de l'AC. En sautant le bootstrap on perdait l'information sans le
voir. `--ca-url` et `--root` sont explicites pour tous les hotes.
Mesure : infra-pki-01 et infra-dns-01 entierement deployees, aucun echec,
step-ca health=ok, powerdns resout la zone souveraine, et les deux hotes portent
un certificat de l'AC interne.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 23:57:01 -04:00
|
|
|
# `--ca-url` et `--root` EXPLICITES : sur un hote ordinaire ils sont redondants avec
|
|
|
|
|
# le `defaults.json` qu'ecrit `step ca bootstrap`, mais l'autorite ne bootstrape pas
|
|
|
|
|
# — elle n'aurait donc aucune de ces deux valeurs. Les nommer ici vaut mieux que de
|
|
|
|
|
# dependre d'un fichier ecrit par une etape qu'on saute volontairement.
|
2026-06-24 20:17:46 -04:00
|
|
|
cmd: >-
|
|
|
|
|
step ca certificate {{ client_pki_nom_cert }}
|
|
|
|
|
{{ client_pki_cert }} {{ client_pki_cle }}
|
deployer : l'ordre des couches, et l'autorite qui se signe elle-meme
`make deployer` triait les groupes alphabetiquement apres le socle :
`client_metrique` passait avant `serveur_step_ca`, donc exigeait un certificat
que l'autorite, pas encore deployee, ne pouvait pas avoir emis — sur l'hote de
l'AC lui-meme. `docs/couches-deploiement.yml` existe pour definir cet ordre et
dit « integrations deployees en dernier » ; `make site` le lit, `deployer` ne
l'avait jamais lu. Meme registre desormais.
Deux politiques universelles se contredisaient : `client_pki` exemptait l'AC,
`client_metrique` refuse toute exemption. L'exemption confondait « ne pas
s'enroler » et « ne pas avoir de certificat ». `client_pki` distingue les deux
chemins : bootstrap pour les autres, EMISSION LOCALE sur l'AC. L'exemption
disparait, la doctrine reste.
Effet de bord instructif : `step ca bootstrap` ecrit aussi le defaults.json qui
porte l'URL de l'AC. En sautant le bootstrap on perdait l'information sans le
voir. `--ca-url` et `--root` sont explicites pour tous les hotes.
Mesure : infra-pki-01 et infra-dns-01 entierement deployees, aucun echec,
step-ca health=ok, powerdns resout la zone souveraine, et les deux hotes portent
un certificat de l'AC interne.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 23:57:01 -04:00
|
|
|
--ca-url {{ client_pki_ca_url }}
|
|
|
|
|
--root {{ client_pki_steppath }}/certs/root_ca.crt
|
2026-06-24 20:17:46 -04:00
|
|
|
--provisioner {{ client_pki_provisioner }}
|
|
|
|
|
--provisioner-password-file {{ client_pki_steppath }}/provisioner.pass
|
2026-07-02 00:00:10 -04:00
|
|
|
{% for s in client_pki_sans | select | unique %}--san {{ s }} {% endfor %}
|
2026-06-24 20:17:46 -04:00
|
|
|
--force
|
|
|
|
|
environment:
|
|
|
|
|
STEPPATH: "{{ client_pki_steppath }}"
|
2026-07-05 18:43:23 -04:00
|
|
|
when: >-
|
|
|
|
|
client_pki_san_actuels.rc != 0
|
|
|
|
|
or (client_pki_sans | select | unique | reject('equalto', '')
|
|
|
|
|
| reject('in', client_pki_san_actuels.stdout | default(''))
|
|
|
|
|
| list | length > 0)
|
|
|
|
|
changed_when: true
|
|
|
|
|
notify: Recharger les consommateurs du cert
|
2026-06-24 20:17:46 -04:00
|
|
|
|
|
|
|
|
- name: Deployer l'unite systemd de renouvellement
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: cert-renewer@.service.j2
|
|
|
|
|
dest: /etc/systemd/system/cert-renewer@.service
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
notify: Recharger systemd
|
|
|
|
|
|
|
|
|
|
- name: Deployer le minuteur de renouvellement
|
|
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: cert-renewer@.timer.j2
|
|
|
|
|
dest: /etc/systemd/system/cert-renewer@.timer
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
notify: Recharger systemd
|
|
|
|
|
|
|
|
|
|
- name: Activer le renouvellement automatique du certificat d'hote
|
|
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: "cert-renewer@{{ client_pki_nom_cert }}.timer"
|
|
|
|
|
enabled: true
|
|
|
|
|
state: started
|
|
|
|
|
daemon_reload: true
|