Set-OPS-Public/roles/client_pki/defaults/main.yml
Daniel Allaire 8186389309 domaine public -> frontal ; noms publics vers l adresse du locataire ; dorsal refuse les inconnus
Zone publique : les expositions pointent vers ip_publique (les NS restent au site).
client_pki : l AC interne ne signe que le domaine interne. Dorsal : serveur par defaut 444.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 17:14:56 -04:00

163 lines
8.7 KiB
YAML

---
client_pki_paquets:
- step-cli
client_pki_steppath: "/etc/step"
# L'AC INTERNE SE DÉRIVE DU GROUPE QUI LA PORTE, elle ne se nomme pas (2026-08-25).
#
# Cette URL écrivait `infra-pki-01` EN DUR. Chez un tenant ça marchait toujours : la
# nomenclature nomme sa PKI ainsi, donc le littéral et la réalité coïncidaient. Le SITE
# est le premier à l'appeler autrement — `site-pki-01` — et les cinq machines ont essayé
# de s'enrôler auprès d'un hôte qui n'existe nulle part :
#
# lookup infra-pki-01.genese.internal ... no such host
#
# Le message accusait le DNS, alors que c'était le nom qui était faux. Un littéral qui a
# raison par coïncidence est un bogue qui attend son premier cas particulier.
#
# `groups['serveur_step_ca']` dit qui porte l'autorité, dans un tenant comme sur un site.
# Pas de repli : sans autorité déclarée, s'adresser à un nom inventé produirait exactement
# la panne qu'on vient de corriger. Le rôle refuse (voir tasks/main.yml).
client_pki_ca_hote: "{{ (groups['serveur_step_ca'] | default([])) | first | default('', true) }}"
client_pki_ca_url: "https://{{ client_pki_ca_hote }}.{{ domaine_interne }}:8443"
client_pki_provisioner: "admin@{{ domaine_interne }}"
# Identite de l'hote.
client_pki_nom_cert: "{{ ansible_fqdn | default(ansible_hostname) }}"
client_pki_cert: "{{ client_pki_steppath }}/certs/{{ client_pki_nom_cert }}.crt"
client_pki_cle: "{{ client_pki_steppath }}/certs/{{ client_pki_nom_cert }}.key"
# LE CERTIFICAT DOIT COUVRIR LES NOMS SOUS LESQUELS ON APPELLE LE SERVICE (2026-08-25).
#
# Les SANs ne portaient que l'identite de la MACHINE — FQDN, nom court, IP. Or un service
# se declare `expose:` au plan, sous un nom qui lui survivra : `forge.genese.internal`
# reste le nom de la forge meme si elle demenage de `site-forge-01` a `site-forge-02`.
#
# Ce nom etait publie partout — plancher /etc/hosts, zone DNS — et couvert nulle part. Le
# clonage du genome a bute dessus : « certificate subject name (site-forge-01.genese
# .internal) does not match target hostname 'forge.genese.internal' ». Du TLS correct, sur
# un nom que personne ne peut appeler : la meme panne que le depot a deja rencontree cote
# resolution, ici cote certificat.
#
# ON N'AJOUTE QUE CE QUE CET HOTE SERT REELLEMENT : `edge` nomme le groupe qui rend le
# service, et l'hote doit en faire partie. Un certificat qui revendiquerait le nom d'un
# service rendu ailleurs serait une usurpation, pas une commodite.
#
# L'AC INTERNE NE SIGNE QUE LE DOMAINE INTERNE (2026-09-29). Le web frontal sert les noms
# PUBLICS du locataire : ils relevent de Let's Encrypt. step-ca n'a aucune politique de noms
# et les aurait signes — sans danger (personne dehors ne lui fait confiance), mais sans objet.
#
# ET LE SERVICE LUI-MEME, QUAND LES MACHINES Y VONT DIRECTEMENT (2026-09-29). Avec
# `resolution_interne: service` (le site), le plancher et la zone menent le nom au service,
# pas a l'edge : c'est lui qui doit le porter. Sans cela, une reconstruction de
# `site-forge-01` aurait rendu un certificat sans `forge.genese.internal`, et le runner du
# site — qui y va directement — aurait bute sur le nom.
client_pki_expositions: "{{ hosts_statiques_expositions | default([]) }}"
client_pki_sans: >-
{{ ([client_pki_nom_cert,
ansible_hostname | default(''),
ansible_host | default('')]
+ (client_pki_expositions
| selectattr('edge', 'defined')
| selectattr('fqdn', 'defined')
| selectattr('edge', 'in', group_names)
| selectattr('domaine', 'defined')
| selectattr('domaine', 'equalto', domaine_interne | default(''))
| map(attribute='fqdn') | list)
+ (client_pki_expositions
| selectattr('fqdn', 'defined')
| selectattr('resout_vers', 'defined')
| selectattr('resout_vers', 'equalto', 'service')
| selectattr('hote', 'equalto', inventory_hostname)
| map(attribute='fqdn') | list))
| select | unique | list }}
# L'empreinte du root CA n'est PAS un intrant : elle est DERIVEE a chaud depuis l'AC
# (tasks/main.yml), parce qu'un from-zero regenere l'autorite avec une empreinte neuve.
# La stocker en voute donnerait une valeur perimee des la premiere reconstruction.
# Pour epingler explicitement une empreinte : `client_pki_ca_fingerprint_override`.
client_pki_ca_fingerprint: ""
# Secret OBLIGATOIRE (Ansible Vault).
client_pki_provisioner_password: "{{ vault_step_ca_provisioner_password | default('') }}" # rempli depuis la voute (vault_step_ca_provisioner_password)
# Depot apt officiel Smallstep (partage avec serveur_step_ca).
client_pki_depot_cle_url: "{{ client_pki_depot_schema }}://packages.smallstep.com/keys/apt/repo-signing-key.gpg"
client_pki_depot_cle_fichier: "/etc/apt/keyrings/smallstep.asc"
client_pki_depot_uri: "{{ client_pki_depot_schema }}://packages.smallstep.com/stable/debian"
client_pki_depot_suite: "debs"
# QUI PEUT LIRE LA CLE PRIVEE (2026-08-25).
#
# Elle est en `0600 root:root`, et c'est le bon defaut. Les consommateurs TLS habituels —
# nginx, Postfix, Dovecot — demarrent en root, lisent la cle, puis deprivilegient : ils
# n'ont jamais eu besoin d'autre chose.
#
# Forgejo tourne en `git` DES LE DEPART. Sur la forge du site, qui sert le genome sans
# edge devant elle, la cle etait donc illisible par le seul processus qui en a besoin.
#
# Un GROUPE lecteur et `0640` reglent ca sans ouvrir la cle a tout le monde. On declare le
# groupe explicitement, service par service : elargir par defaut serait exactement le
# genre de commodite qui finit par rendre une cle privee lisible par `nogroup`.
client_pki_cle_groupe: "root"
client_pki_cle_mode: "0600"
# LE CERTIFICAT, LUI, EST PUBLIC — et l'etait deja avant d'etre sur ce disque : il est
# presente a chaque poignee de main, a quiconque se connecte. Le garder en `0600` ne
# protegeait rien et empechait tout service non-root de le lire. Le certificat racine est
# d'ailleurs deja en `0644` juste a cote, pour la meme raison.
client_pki_cert_mode: "0644"
# Services a recharger apres un renouvellement de cert : les VRAIS consommateurs
# (nginx sur l'edge, postfix/dovecot sur le mail, slapd sur l'annuaire). Sans ca,
# le cert est renouvele sur disque mais le service sert l'ancien jusqu'a un reload.
client_pki_reload_services: []
# Marge avant echeance (secondes) sous laquelle le role RE-EMET le certificat plutot que
# d'attendre le renouvellement automatique. 3600 = une heure : large devant le minuteur
# (~14 min), serre devant la duree de vie (24 h).
client_pki_marge_renouvellement: 3600
# --- Sonde de supervision (docs/supervision-conception.md) --------------------------
#
# LES SEUILS DECOULENT DU MOMENT OU LE RENOUVELLEMENT EST DU — pas d'une intuition.
#
# `cert-renewer@.service` porte `ExecCondition=step certificate needs-renewal`, qui dit
# oui au TIERS RESTANT : 8 h pour un certificat de 24 h. Le minuteur repasse toutes les
# 15 minutes (`OnCalendar=*:1/15`). En marche normale, un certificat ne descend donc
# jamais durablement sous 8 h.
#
# PREMIERE VERSION FAUSSE, ET INSTRUCTIVE (2026-09-09) : avert a 12 h, crit a 4 h. Deux
# machines du site sur sept sont passees en AVERTISSEMENT — sur des certificats
# parfaitement sains, simplement pas encore eligibles au renouvellement. La sonde criait
# AVANT que le mecanisme ne soit cense agir.
#
# Les seuils sont donc SOUS le point de renouvellement :
# 6 h -> le renouvellement est du depuis 2 h et n'a pas abouti : huit fenetres de
# quinze minutes manquees. Ce n'est plus un hoquet.
# 3 h -> plus aucune marge ; la panne est certaine au prochain cycle.
#
# Un seuil au-dessus du point de renouvellement ne previent pas : il ment.
client_pki_sonde_avert_h: 6
client_pki_sonde_crit_h: 3
# Port local ou comparer le certificat SERVI a celui du disque. Vide = pas de comparaison
# (l'hote n'expose rien en TLS, ou son consommateur n'ecoute pas en local).
client_pki_sonde_port: ""
# --- SCHEMA DES DEPOTS TIERS (2026-09-10) --------------------------------------------
#
# `http` DES QU'UN CACHE EST DANS LE CHEMIN, `https` sinon. Ce n'est pas un relachement :
# le cache RELAIE ces depots en https vers le fournisseur (voir `serveur_artefacts`,
# `Remap-*`), et l'integrite vient des SIGNATURES du depot, qu'apt verifie de toute facon.
# Le meme raisonnement vaut deja pour `deb.debian.org` depuis toujours.
#
# Sans cette derivation, chaque machine sortait elle-meme sur Internet : le mandataire ne
# vaut que pour `http`, et le socle pose deliberement `Acquire::https::Proxy "DIRECT"`
# parce qu'un cache sans remap refuse les tunnels. Le remap leve ce refus ; encore
# faut-il DEMANDER en http.
#
# DEGRADE, JAMAIS DEVINE : pas de cache d'amorcage declare, pas de reecriture.
client_pki_depot_schema: >-
{{ 'http' if (artefacts_amorcage | default('') | string | length > 0) else 'https' }}