2026-06-24 20:17:46 -04:00
|
|
|
---
|
|
|
|
|
serveur_icinga_paquets:
|
|
|
|
|
- icinga2
|
|
|
|
|
- icingadb
|
|
|
|
|
- icingadb-redis
|
|
|
|
|
- postgresql-client # pour importer le schema vers la BD distante
|
|
|
|
|
|
|
|
|
|
serveur_icinga_service_icinga2: "icinga2"
|
|
|
|
|
serveur_icinga_service_icingadb: "icingadb"
|
|
|
|
|
serveur_icinga_service_redis: "icingadb-redis"
|
|
|
|
|
|
|
|
|
|
# Depot apt officiel Icinga (paquet trousseau + source signee).
|
|
|
|
|
serveur_icinga_keyring_url: >-
|
|
|
|
|
https://packages.icinga.com/icinga-archive-keyring_latest+debian{{ ansible_distribution_major_version }}.deb
|
|
|
|
|
serveur_icinga_depot_source: >-
|
|
|
|
|
deb [signed-by=/usr/share/keyrings/icinga-archive-keyring.gpg]
|
|
|
|
|
https://packages.icinga.com/debian icinga-{{ ansible_distribution_release }} main
|
|
|
|
|
|
|
|
|
|
# Base Icinga DB : resolue depuis le registre par le groupe consommateur.
|
|
|
|
|
serveur_icinga_groupe: "serveur_icinga"
|
2026-07-05 00:40:57 -04:00
|
|
|
serveur_icinga_db_host: "" # dérivé (FQDN) par resoudre_base au déploiement
|
2026-06-24 20:17:46 -04:00
|
|
|
|
|
|
|
|
# Redis dedie a Icinga DB (paquet icingadb-redis).
|
|
|
|
|
serveur_icinga_redis_host: "localhost"
|
|
|
|
|
serveur_icinga_redis_port: 6380
|
|
|
|
|
|
|
|
|
|
serveur_icinga_config: "/etc/icingadb/config.yml"
|
|
|
|
|
serveur_icinga_schema: "/usr/share/icingadb/schema/pgsql/schema.sql"
|
2026-07-04 20:32:05 -04:00
|
|
|
|
|
|
|
|
# TLS vers PostgreSQL (zero-confiance). true = IcingaDB verifie le cert serveur
|
|
|
|
|
# contre le root_ca step-ca (host dans le SAN). root_ca doit etre lisible (0644).
|
|
|
|
|
serveur_icinga_db_tls: false
|
|
|
|
|
serveur_icinga_db_ca: "/etc/step/certs/root_ca.crt"
|
supervision : c'est le DEPOT qui dit ou en sont les sauvegardes
Icinga ne surveillait rien : aucun objet Host ni Service de Set-OPS, seulement
la config Debian d'origine sur localhost.
Superviser setops-sauvegarde.service aurait reproduit le defaut du jour meme :
l'unite etait VERTE sur onze noeuds pendant qu'elle n'emportait rien. Le noeud
sait qu'il a LANCE sa sauvegarde, pas qu'elle est ARRIVEE. backup-01 evalue donc
ses depots et pousse un resultat passif par noeud vers l'API Icinga.
Trois criteres, parce qu'un seul suffit a mentir : l'instantane existe, il est
recent (26 h / 50 h), il contient au moins un fichier.
Le sens du flux est delibere : le depot parle a la supervision, jamais l'inverse
— compromettre mon-01 ne donne aucun acces aux sauvegardes.
Le ttl de 6 h fait la fraicheur : si le rapporteur se tait, Icinga perime les
services tout seul. C'est le silence qui a laisse le defaut vivre un mois.
Deux erreurs corrigees par la mesure :
- --data-urlencode refuse en Bad Request (l'API veut du JSON) ; le flux, le TLS
et l'auth marchaient, seule la charge etait perdue.
- le seuil « vide » en octets signalait a tort idm-01 (2363 o) : un export LDIF
d'un annuaire a un compte pese cela. « Vide » se mesure en FICHIERS. Et le
verdict est un AVERTISSEMENT : la machine ne distingue pas « les donnees ont
disparu » de « il n'y en a pas encore ».
Reserve assumee : curl -k — l'API presente le cert de sa propre AC, pas step-ca.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 21:39:05 -04:00
|
|
|
|
icinga : le pair est verifie — mais pas avec un certificat step-ca
Objectif : supprimer le `curl -k` du rapporteur. Fait, et la maniere a ete
imposee par la mesure.
SERVIR UN CERTIFICAT STEP-CA SUR L'API EST IMPOSSIBLE. Icinga le dit lui-meme :
« Our certificate will expire soon, but we own the CA. Renewing. » Il renouvelle
tout certificat expirant sous 30 jours ; les notres vivent 24 h ; possedant une
AC, il re-emet avec la sienne et ecrase le notre a chaque demarrage. Collision
entre deux politiques de PKI, et la notre n'est pas negociable.
Deux decouvertes en chemin, toutes deux par le garde-fou `icinga2 daemon -C`
ajoute au role, qui a ARRETE le deploiement avant de redemarrer la supervision :
- cert_path/key_path/ca_path sont DEPRECIES depuis 2.8 ; les poser reveille un
chemin de code herite qui exige en plus un objet Endpoint ;
- l'identite de l'API est le CN du certificat. NodeName valait « mon-01 », donc
le SAN aussi, alors qu'on appelle par le FQDN : aucune verification n'aurait
pu reussir. NodeName est desormais aligne sur le FQDN.
A LA PLACE : Icinga garde son AC (domaine de confiance FERME, legitime) et
backup-01 verifie le pair contre CETTE AC, recuperee depuis mon-01 au
deploiement. Le pair est authentifie ; seule la racine differe.
Controle negatif — une verification qu'on ne teste pas est un ornement : avec la
mauvaise AC (step-ca), curl refuse (« unable to get local issuer certificate ») ;
avec la bonne, les neuf rapports passent.
Sous-AC step-ca ecartee : elle poserait sur l'hote de supervision une cle capable
d'EMETTRE pour n'importe quel nom, alors qu'on a choisi le sens du flux pour que
compromettre mon-01 ne donne rien.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 08:33:50 -04:00
|
|
|
# --- Identite TLS de l'API (5665) ---
|
|
|
|
|
# Icinga s'emet lui-meme son certificat, avec sa propre AC : il renouvelle tout ce qui
|
|
|
|
|
# expire sous 30 jours, et les certificats Set-OPS vivent 24 h. Lui servir un certificat
|
|
|
|
|
# step-ca est donc impossible — il l'ecrase a chaque demarrage (mesure le 2026-08-11).
|
|
|
|
|
# Le consommateur verifie donc le pair contre l'AC d'Icinga : domaine de confiance ferme,
|
|
|
|
|
# pair authentifie, plus aucun `curl -k`.
|
|
|
|
|
#
|
|
|
|
|
# NodeName aligne sur le FQDN : le certificat auto-emis porte NodeName en CN et en SAN,
|
|
|
|
|
# et c'est par le FQDN qu'on appelle l'API. Sans cet alignement, aucune verification ne
|
|
|
|
|
# peut reussir.
|
reconstruction from-zero : sept defauts, tous invisibles sur une flotte debout
Chezlepro reconstruit depuis zero en 10.17.x.x. Sept defauts sont tombes, et
AUCUN n'etait detectable autrement — c'est tout l'argument de la reconstruction
comme preuve.
1. aucune route vers le tenant sur le poste (posee a la main, jamais persistee)
2. backup-01 exigeait l'AC d'Icinga — dependance non declaree
3. ma correction inversait les couches : REFUSEE PAR P08 avant d'entrer
4. base Forgejo a moitie initialisee (sequelle de l'arret du n°2)
5. /etc/hosts : nom court avant le FQDN -> hostname -f faux sur les 14 machines
6. API Icinga jamais activee (garde `creates:` d'api setup)
7. restic refuse tout le lot si un chemin declare manque
LE CINQUIEME DEPASSAIT ICINGA. hostname -f rend le PREMIER nom : toute la flotte
se croyait appelee « mon-01 ». Visible sur le certificat d'Icinga, mais le meme
piege attendait Postfix (myhostname), les journaux, les certificats. FQDN d'abord.
CE QU'ON NE CORRIGE PAS : icinga2 api setup REECRIT NodeName d'apres le nom court
et nomme ses certificats d'apres lui. Aligne avant, il est ecrase ; aligne apres,
les certificats portent le mauvais nom. On adopte sa convention : le depot appelle
l'API par le nom court, celui que le certificat porte.
serveur_icinga_node_name derive desormais de l'INVENTAIRE, pas d'ansible_fqdn —
un fait qui depend du resolveur et rendait « mon-01 » alors que le FQDN etait bon.
Le commentaire ecrit pour avertir qu'une sequence accolade-diese casse les
gabarits Jinja contenait cette sequence, et cassait le gabarit. Neuf hotes en
echec pour un avertissement mal redige.
Sept devis CONFORME, prouver 36/36, make test 0. Neuf sauvegardes reussies.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 03:36:56 -04:00
|
|
|
# DERIVE DE L'INVENTAIRE, pas de `ansible_fqdn`. Le fait depend du resolveur de la
|
|
|
|
|
# machine et de la forme de /etc/hosts — il a rendu « mon-01 » alors que le FQDN etait
|
|
|
|
|
# correct (2026-08-12), produisant un certificat SAN=mon-01 que personne ne pouvait
|
|
|
|
|
# verifier en appelant par le nom complet. L'inventaire, lui, est la meme source que
|
|
|
|
|
# celle dont `serveur_backup` compose son URL : les deux ne peuvent pas diverger.
|
|
|
|
|
serveur_icinga_node_name: "{{ inventory_hostname }}.{{ domaine_interne }}"
|
icinga : le pair est verifie — mais pas avec un certificat step-ca
Objectif : supprimer le `curl -k` du rapporteur. Fait, et la maniere a ete
imposee par la mesure.
SERVIR UN CERTIFICAT STEP-CA SUR L'API EST IMPOSSIBLE. Icinga le dit lui-meme :
« Our certificate will expire soon, but we own the CA. Renewing. » Il renouvelle
tout certificat expirant sous 30 jours ; les notres vivent 24 h ; possedant une
AC, il re-emet avec la sienne et ecrase le notre a chaque demarrage. Collision
entre deux politiques de PKI, et la notre n'est pas negociable.
Deux decouvertes en chemin, toutes deux par le garde-fou `icinga2 daemon -C`
ajoute au role, qui a ARRETE le deploiement avant de redemarrer la supervision :
- cert_path/key_path/ca_path sont DEPRECIES depuis 2.8 ; les poser reveille un
chemin de code herite qui exige en plus un objet Endpoint ;
- l'identite de l'API est le CN du certificat. NodeName valait « mon-01 », donc
le SAN aussi, alors qu'on appelle par le FQDN : aucune verification n'aurait
pu reussir. NodeName est desormais aligne sur le FQDN.
A LA PLACE : Icinga garde son AC (domaine de confiance FERME, legitime) et
backup-01 verifie le pair contre CETTE AC, recuperee depuis mon-01 au
deploiement. Le pair est authentifie ; seule la racine differe.
Controle negatif — une verification qu'on ne teste pas est un ornement : avec la
mauvaise AC (step-ca), curl refuse (« unable to get local issuer certificate ») ;
avec la bonne, les neuf rapports passent.
Sous-AC step-ca ecartee : elle poserait sur l'hote de supervision une cle capable
d'EMETTRE pour n'importe quel nom, alors qu'on a choisi le sens du flux pour que
compromettre mon-01 ne donne rien.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 08:33:50 -04:00
|
|
|
serveur_icinga_ca: "/var/lib/icinga2/ca/ca.crt"
|
reconstruction from-zero : sept defauts, tous invisibles sur une flotte debout
Chezlepro reconstruit depuis zero en 10.17.x.x. Sept defauts sont tombes, et
AUCUN n'etait detectable autrement — c'est tout l'argument de la reconstruction
comme preuve.
1. aucune route vers le tenant sur le poste (posee a la main, jamais persistee)
2. backup-01 exigeait l'AC d'Icinga — dependance non declaree
3. ma correction inversait les couches : REFUSEE PAR P08 avant d'entrer
4. base Forgejo a moitie initialisee (sequelle de l'arret du n°2)
5. /etc/hosts : nom court avant le FQDN -> hostname -f faux sur les 14 machines
6. API Icinga jamais activee (garde `creates:` d'api setup)
7. restic refuse tout le lot si un chemin declare manque
LE CINQUIEME DEPASSAIT ICINGA. hostname -f rend le PREMIER nom : toute la flotte
se croyait appelee « mon-01 ». Visible sur le certificat d'Icinga, mais le meme
piege attendait Postfix (myhostname), les journaux, les certificats. FQDN d'abord.
CE QU'ON NE CORRIGE PAS : icinga2 api setup REECRIT NodeName d'apres le nom court
et nomme ses certificats d'apres lui. Aligne avant, il est ecrase ; aligne apres,
les certificats portent le mauvais nom. On adopte sa convention : le depot appelle
l'API par le nom court, celui que le certificat porte.
serveur_icinga_node_name derive desormais de l'INVENTAIRE, pas d'ansible_fqdn —
un fait qui depend du resolveur et rendait « mon-01 » alors que le FQDN etait bon.
Le commentaire ecrit pour avertir qu'une sequence accolade-diese casse les
gabarits Jinja contenait cette sequence, et cassait le gabarit. Neuf hotes en
echec pour un avertissement mal redige.
Sept devis CONFORME, prouver 36/36, make test 0. Neuf sauvegardes reussies.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 03:36:56 -04:00
|
|
|
# Ou le depot de sauvegarde attend cette AC (cf. serveur_backup_ca_verification).
|
|
|
|
|
serveur_icinga_ca_destination_depot: "/etc/setops/icinga-ca.crt"
|
icinga : le pair est verifie — mais pas avec un certificat step-ca
Objectif : supprimer le `curl -k` du rapporteur. Fait, et la maniere a ete
imposee par la mesure.
SERVIR UN CERTIFICAT STEP-CA SUR L'API EST IMPOSSIBLE. Icinga le dit lui-meme :
« Our certificate will expire soon, but we own the CA. Renewing. » Il renouvelle
tout certificat expirant sous 30 jours ; les notres vivent 24 h ; possedant une
AC, il re-emet avec la sienne et ecrase le notre a chaque demarrage. Collision
entre deux politiques de PKI, et la notre n'est pas negociable.
Deux decouvertes en chemin, toutes deux par le garde-fou `icinga2 daemon -C`
ajoute au role, qui a ARRETE le deploiement avant de redemarrer la supervision :
- cert_path/key_path/ca_path sont DEPRECIES depuis 2.8 ; les poser reveille un
chemin de code herite qui exige en plus un objet Endpoint ;
- l'identite de l'API est le CN du certificat. NodeName valait « mon-01 », donc
le SAN aussi, alors qu'on appelle par le FQDN : aucune verification n'aurait
pu reussir. NodeName est desormais aligne sur le FQDN.
A LA PLACE : Icinga garde son AC (domaine de confiance FERME, legitime) et
backup-01 verifie le pair contre CETTE AC, recuperee depuis mon-01 au
deploiement. Le pair est authentifie ; seule la racine differe.
Controle negatif — une verification qu'on ne teste pas est un ornement : avec la
mauvaise AC (step-ca), curl refuse (« unable to get local issuer certificate ») ;
avec la bonne, les neuf rapports passent.
Sous-AC step-ca ecartee : elle poserait sur l'hote de supervision une cle capable
d'EMETTRE pour n'importe quel nom, alors qu'on a choisi le sens du flux pour que
compromettre mon-01 ne donne rien.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 08:33:50 -04:00
|
|
|
|
supervision : c'est le DEPOT qui dit ou en sont les sauvegardes
Icinga ne surveillait rien : aucun objet Host ni Service de Set-OPS, seulement
la config Debian d'origine sur localhost.
Superviser setops-sauvegarde.service aurait reproduit le defaut du jour meme :
l'unite etait VERTE sur onze noeuds pendant qu'elle n'emportait rien. Le noeud
sait qu'il a LANCE sa sauvegarde, pas qu'elle est ARRIVEE. backup-01 evalue donc
ses depots et pousse un resultat passif par noeud vers l'API Icinga.
Trois criteres, parce qu'un seul suffit a mentir : l'instantane existe, il est
recent (26 h / 50 h), il contient au moins un fichier.
Le sens du flux est delibere : le depot parle a la supervision, jamais l'inverse
— compromettre mon-01 ne donne aucun acces aux sauvegardes.
Le ttl de 6 h fait la fraicheur : si le rapporteur se tait, Icinga perime les
services tout seul. C'est le silence qui a laisse le defaut vivre un mois.
Deux erreurs corrigees par la mesure :
- --data-urlencode refuse en Bad Request (l'API veut du JSON) ; le flux, le TLS
et l'auth marchaient, seule la charge etait perdue.
- le seuil « vide » en octets signalait a tort idm-01 (2363 o) : un export LDIF
d'un annuaire a un compte pese cela. « Vide » se mesure en FICHIERS. Et le
verdict est un AVERTISSEMENT : la machine ne distingue pas « les donnees ont
disparu » de « il n'y en a pas encore ».
Reserve assumee : curl -k — l'API presente le cert de sa propre AC, pas step-ca.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 21:39:05 -04:00
|
|
|
# --- Supervision des sauvegardes (resultats passifs pousses par le depot) ---
|
|
|
|
|
# Le controle porte sur la VERITE DE TERRAIN (l'instantane cote depot), pas sur l'unite
|
|
|
|
|
# systemd du noeud source : une unite verte sur un depot vide a menti pendant un mois.
|
|
|
|
|
serveur_icinga_setops_conf: "/etc/icinga2/conf.d/setops-sauvegardes.conf"
|
|
|
|
|
serveur_icinga_api_conf: "/etc/icinga2/conf.d/setops-api-users.conf"
|
|
|
|
|
serveur_icinga_api_utilisateur: "setops-depot"
|
|
|
|
|
serveur_icinga_api_motdepasse: "{{ vault_icinga_api_depot | default('') }}"
|
|
|
|
|
|
|
|
|
|
# Hote portant les depots : DERIVE du groupe, jamais ecrit en dur.
|
|
|
|
|
serveur_icinga_hote_sauvegarde: "{{ (groups['serveur_backup'] | default([]) | first) | default('') }}"
|
|
|
|
|
|
|
|
|
|
# Noeuds dont on ATTEND un instantane : ceux qui portent client_backup ET detiennent
|
|
|
|
|
# reellement de l'etat. Meme regle que `client_backup_jobs`, et meme source que P36 —
|
|
|
|
|
# la liste en clair du catalogue, lue depuis le role qui la possede.
|
|
|
|
|
serveur_icinga_sauvegarde_attendue: >-
|
|
|
|
|
{{ (client_backup_groupes_etat | default([]) | map('extract', groups)
|
|
|
|
|
| select('defined') | flatten | unique | list)
|
|
|
|
|
| intersect(groups['client_backup'] | default([])) }}
|
2026-09-02 17:48:19 -04:00
|
|
|
|
supervision : systemctl --failed entre dans Icinga (role client_sante)
CE QU IL FERME. openipmi.service echouait a chaque demarrage sur les
quatorze machines depuis le 2026-09-02, et systemctl --failed rendait ZERO
partout : non parce qu elles allaient bien, mais parce qu aucune n avait
redemarre depuis. Il a fallu qu un humain redemarre une machine pour que
le defaut existe aux yeux de quelqu un. Un controle qui ne peut echouer
qu au demarrage ne mesure rien tant que rien ne demarre.
PASSIF, ET A DUREE DE VIE. Un controle actif ne voit pas la machine MUETTE.
Ici c est le noeud qui parle, et le ttl de son envoi fait la fraicheur :
sans nouvelle, Icinga perime le service tout seul. Le silence alerte autant
que l echec. Le minuteur declenche AU DEMARRAGE autant que toutes les 15
min : les echecs de cette famille naissent au boot.
CRITIQUE DES LA PREMIERE UNITE, jamais un seuil — une unite en echec est
soit un vrai probleme soit du bruit a retirer, et un seuil ferait vivre le
bruit. Les tolerances se nomment une par une, vide par defaut.
CONTROLE NEGATIF. Unite factice sur obs-01, etat relu dans IcingaDB :
CRITICAL, et le verdict NOMME l unite. Les treize autres OK. Apres
nettoyage : 14/14 OK.
UN CONFLIT EVITE. setops-sauvegardes.conf definissait les object Host ; un
second fichier de controle aurait redefini les memes, et Icinga refuse un
objet en double — la configuration entiere aurait ete rejetee, donc AUCUNE
supervision, en voulant en ajouter. Les hotes vivent maintenant dans
setops-hotes.conf, definis une fois.
TROIS OBSTACLES. ${#tableau[@]} contient {# que Jinja lit comme un debut de
commentaire (remede : comment_start_string en tete du gabarit). Ma premiere
sonde a traduit un 403 « Missing permission: objects/query/service » en
« 0 service » — encore un echec qui ecrasait permission ; l etat se lit
dans IcingaDB. Et un echec apt transitoire sur mon-01, local et disparu au
second essai : mesure avant conclusion.
NON FAIT : le SITE n a pas recu client_sante.
make prouver : CONFORME, 63 OK, 0 echec, 0 saute.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-09 20:32:08 -04:00
|
|
|
# LES NOEUDS DONT ON RAPPORTE LA SANTE : tous ceux du plan.
|
|
|
|
|
#
|
|
|
|
|
# `serveur_debian` est le socle — tout hote deploye le porte. Il n'y a donc pas de liste a
|
|
|
|
|
# tenir : un noeud qui entre dans l'ecosysteme entre dans la supervision, et un noeud
|
|
|
|
|
# rase en sort. Une liste ecrite a la main aurait ce defaut precis : elle ne bouge que
|
|
|
|
|
# quand quelqu'un y pense.
|
|
|
|
|
serveur_icinga_sante_attendue: "{{ groups['serveur_debian'] | default([]) }}"
|
|
|
|
|
|
|
|
|
|
# LES HOTES A DEFINIR, UNE SEULE FOIS — l'union de ce que les controles attachent.
|
|
|
|
|
#
|
|
|
|
|
# Icinga REFUSE un `object Host` en double : deux fichiers de controle qui definissent le
|
|
|
|
|
# meme hote font rejeter TOUTE la configuration, donc AUCUNE supervision. Les hotes vivent
|
|
|
|
|
# donc dans `setops-hotes.conf`, et les fichiers de controle n'attachent que des services.
|
|
|
|
|
serveur_icinga_hotes_supervises: >-
|
|
|
|
|
{{ (serveur_icinga_sante_attendue
|
|
|
|
|
+ serveur_icinga_sauvegarde_attendue
|
|
|
|
|
+ ([serveur_icinga_hote_sauvegarde] if serveur_icinga_hote_sauvegarde else []))
|
|
|
|
|
| unique | list }}
|
|
|
|
|
|
|
|
|
|
serveur_icinga_hotes_conf: "/etc/icinga2/conf.d/setops-hotes.conf"
|
|
|
|
|
serveur_icinga_sante_conf: "/etc/icinga2/conf.d/setops-sante.conf"
|
|
|
|
|
|
2026-09-02 17:48:19 -04:00
|
|
|
# A QUI LA SUPERVISION PARLE — vide = personne, et on le DIT.
|
|
|
|
|
#
|
|
|
|
|
# Icinga livre son exemple avec `root@localhost`. Une supervision qui voit tout et
|
|
|
|
|
# n'en parle a personne a le meme effet qu'une supervision absente, en plus couteux :
|
|
|
|
|
# elle rassure. Renseigne, ce champ cree un destinataire dans le groupe auquel les
|
|
|
|
|
# notifications sont deja assignees.
|
|
|
|
|
#
|
|
|
|
|
# Vide, aucun destinataire n'est pose et le deploiement le SIGNALE — plutot que de
|
|
|
|
|
# laisser croire qu'une alerte partira.
|
|
|
|
|
serveur_icinga_destinataire: ""
|