114 lines
4.6 KiB
YAML
114 lines
4.6 KiB
YAML
|
|
---
|
||
|
|
# Devis des certificats — RELEVE seul, sur toute la flotte. Ne modifie rien (D-23).
|
||
|
|
#
|
||
|
|
# Le defaut qu'il traque est connu et recurrent : un certificat renouvele SUR DISQUE
|
||
|
|
# mais toujours servi PERIME depuis la memoire du service, tant que nginx / postfix /
|
||
|
|
# dovecot / slapd n'ont pas ete recharges. Rien ne le signale — le fichier est bon,
|
||
|
|
# `step` est content, et le navigateur voit un certificat expire.
|
||
|
|
#
|
||
|
|
# La methode ne suppose rien du service : on releve l'empreinte du certificat sur
|
||
|
|
# disque, puis l'empreinte REELLEMENT SERVIE par chaque port TLS en ecoute. Un port
|
||
|
|
# qui sert un certificat portant le meme sujet mais une autre empreinte tient une
|
||
|
|
# copie perimee en memoire.
|
||
|
|
#
|
||
|
|
# make certificats-plan
|
||
|
|
|
||
|
|
- name: Devis des certificats — disque contre mémoire
|
||
|
|
hosts: client_pki
|
||
|
|
become: true
|
||
|
|
gather_facts: true
|
||
|
|
|
||
|
|
vars:
|
||
|
|
devis_certificats_sortie: "{{ playbook_dir }}/../../instance/devis-certificats.json"
|
||
|
|
|
||
|
|
tasks:
|
||
|
|
# PRECEDENCE — `include_vars` au niveau du play PRIME sur les `group_vars`.
|
||
|
|
# Charger les defauts d'un role tels quels ferait donc mentir le devis : il
|
||
|
|
# comparerait au defaut du depot au lieu de la valeur reellement declaree par
|
||
|
|
# l'inventaire. Mesure du 2026-08-08 : le premier jet rapportait
|
||
|
|
# `client_pki_reload_services: []` sur les 14 hotes alors que quatre groupes le
|
||
|
|
# declarent. Le devis portait exactement le defaut qu'il est cense traquer.
|
||
|
|
#
|
||
|
|
# On retient donc ce que l'inventaire declare AVANT de charger les defauts, puis
|
||
|
|
# on le reimpose. (Charger sous un `name:` ne marche pas : les defauts se citent
|
||
|
|
# entre eux — `client_pki_cert` reference `client_pki_steppath` — et ces
|
||
|
|
# references ne se resolvent plus une fois enfermees dans un dictionnaire.)
|
||
|
|
- name: Retenir ce que l'inventaire déclare pour client_pki
|
||
|
|
ansible.builtin.set_fact:
|
||
|
|
devis_inventaire: >-
|
||
|
|
{{ hostvars[inventory_hostname] | dict2items
|
||
|
|
| selectattr('key', 'match', '^client_pki_') | items2dict }}
|
||
|
|
|
||
|
|
- name: Charger les défauts du rôle client_pki
|
||
|
|
ansible.builtin.include_vars:
|
||
|
|
dir: "{{ playbook_dir }}/../../roles/client_pki/defaults"
|
||
|
|
|
||
|
|
# Cle par cle : `set_fact` ne prend pas un dictionnaire entier en argument libre —
|
||
|
|
# il l'accepte sans erreur et n'en fait rien. C'est ainsi que le premier correctif
|
||
|
|
# a paru fonctionner tout en laissant le devis mentir.
|
||
|
|
- name: Rendre le dernier mot à l'inventaire
|
||
|
|
ansible.builtin.set_fact:
|
||
|
|
"{{ item.key }}": "{{ item.value }}"
|
||
|
|
loop: "{{ devis_inventaire | dict2items }}"
|
||
|
|
loop_control:
|
||
|
|
label: "{{ item.key }}"
|
||
|
|
|
||
|
|
- name: Relever le certificat sur disque
|
||
|
|
ansible.builtin.command:
|
||
|
|
argv:
|
||
|
|
- openssl
|
||
|
|
- x509
|
||
|
|
- -in
|
||
|
|
- "{{ client_pki_cert }}"
|
||
|
|
- -noout
|
||
|
|
- -subject
|
||
|
|
- -fingerprint
|
||
|
|
- -enddate
|
||
|
|
- -issuer
|
||
|
|
register: devis_cert_disque
|
||
|
|
changed_when: false
|
||
|
|
failed_when: false
|
||
|
|
|
||
|
|
- name: Relever les ports TLS en écoute et le certificat que chacun sert
|
||
|
|
ansible.builtin.shell:
|
||
|
|
executable: /bin/bash
|
||
|
|
cmd: |
|
||
|
|
set -uo pipefail
|
||
|
|
for P in $(ss -H -ltn 2>/dev/null | awk '{print $4}' | sed 's/.*://' | sort -un); do
|
||
|
|
# STARTTLS n'est pas optionnel sur ces ports : sans le dialecte, la poignee
|
||
|
|
# de main n'a pas lieu et on conclurait a tort que le port ne sert rien.
|
||
|
|
case "$P" in
|
||
|
|
25|587) ARG="-starttls smtp" ;;
|
||
|
|
143) ARG="-starttls imap" ;;
|
||
|
|
110) ARG="-starttls pop3" ;;
|
||
|
|
389) ARG="-starttls ldap" ;;
|
||
|
|
*) ARG="" ;;
|
||
|
|
esac
|
||
|
|
OUT=$(timeout 5 openssl s_client -connect 127.0.0.1:"$P" $ARG \
|
||
|
|
-servername {{ ansible_fqdn }} </dev/null 2>/dev/null \
|
||
|
|
| openssl x509 -noout -subject -fingerprint -enddate 2>/dev/null)
|
||
|
|
if [ -n "$OUT" ]; then
|
||
|
|
echo "PORT=$P"
|
||
|
|
echo "$OUT"
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
register: devis_cert_servis
|
||
|
|
changed_when: false
|
||
|
|
|
||
|
|
- name: Déposer le relevé sur le contrôleur
|
||
|
|
ansible.builtin.copy:
|
||
|
|
dest: "{{ devis_certificats_sortie }}.{{ inventory_hostname }}"
|
||
|
|
mode: "0600"
|
||
|
|
content: >-
|
||
|
|
{{ {
|
||
|
|
'hote': inventory_hostname,
|
||
|
|
'fqdn': ansible_fqdn,
|
||
|
|
'chemin': client_pki_cert,
|
||
|
|
'disque': devis_cert_disque.stdout | default(''),
|
||
|
|
'disque_rc': devis_cert_disque.rc | default(1),
|
||
|
|
'servis': devis_cert_servis.stdout | default(''),
|
||
|
|
'recharges_declares': client_pki_reload_services,
|
||
|
|
} | to_nice_json }}
|
||
|
|
delegate_to: localhost
|
||
|
|
become: false
|