Set-OPS-Public/roles/serveur_resolveur_site/templates/sonde-resolution-locataires.sh.j2
Daniel Allaire aac74f6043 supervision : les huit derniers roles, et deux defauts que l epreuve a trouves
Les 33 roles serveur_* declarent maintenant une sonde. Les huit qui manquaient
sont ceux dont la verite ne ressemble pas a « ce service repond-il ».

Quatre marqueurs du site : ce que tasks/main.yml verifie UNE FOIS au deploiement
cesse d etre vrai sans que rien ne tombe. La racine du cache se retrouve chainee,
la forge du genome repond en n ayant plus rien dedans, un locataire n est plus
admis a resoudre, l isolation d un depot glisse.

serveur_ops_site ne sert rien : il detient un pouvoir. La sonde verifie que la
carte est la, que la voute du site est chiffree et que sa cle est en 0600 — sans
lire le contenu d aucun des trois.

serveur_icingaweb2 surveille la vitrine de la supervision elle-meme : si la
console meurt, tout reste vert et l exploitant est aveugle.

DEFAUT 1 — quatre gabarits qu Ansible aurait refuse de rendre. Jinja lit le
{# de ${#tableau[@]} comme un debut de commentaire. Le depot connaissait le
remede et l appliquait la ou quelqu un s etait fait prendre, nulle part ailleurs.
P76 rend desormais chaque gabarit de role, avec les delimiteurs qu Ansible en
tirerait — pas une recherche de motif.

DEFAUT 2 — la doctrine promettait 54 greffons et citait check_pgsql. La flotte a
monitoring-plugins-basic : 53, sans check_pgsql ni check_dns ni check_ldap. Le
paquet qui les porte traine samba et snmp sur chaque machine. Un greffon absent
sort en 127, qui n est pas un code Nagios.

21 controles negatifs sur les machines reelles du site. ansible-lint production
0/91, harnais 75 OK.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Crgis8CxCWkAGFA1ecBz3q
2026-09-14 15:43:52 -04:00

69 lines
3.6 KiB
Django/Jinja

#jinja2: comment_start_string:'{=#', comment_end_string:'#=}'
#!/bin/bash
# (Le gabarit redefinit le delimiteur de commentaire Jinja : `${#tableau[@]}` contient
# la sequence `{#`, que Jinja lirait comme un debut de commentaire. Le shell en a
# besoin ; c'est donc Jinja qui cede. Meme geste que `client_sante/setops-sante.sh.j2`
# et `serveur_nginx/sonde-edge.sh.j2`.)
# GENERE par Set-OPS (role serveur_resolveur_site). Ne pas editer a la main.
#
# SONDE « resolution-locataires » — les locataires peuvent-ils encore resoudre ici ?
#
# PAS UNE ENVELOPPE DE GREFFON. Ce qu'on mesure ici n'a pas d'equivalent standard : « le
# resolveur accepte-t-il encore de repondre AUX RESEAUX DES TENANTS », et « repond-il a
# l'adresse ou ils frappent ». La mesurer depuis la machine elle-meme est le seul endroit
# ou on peut la lire sans traverser la frontiere.
set -uo pipefail
# LA LISTE ATTENDUE EST DERIVEE DU PLAN DU SITE, pas ecrite ici. C'est le meme calcul que
# l'assertion de `tasks/main.yml` — et c'est voulu : la sonde n'est pas un second avis,
# c'est la MEME exigence, rejouee quand plus personne ne regarde.
attendus=({% for s in serveur_resolveur_site_supernets_tenants | default([]) %}'{{ s }}' {% endfor %})
CONF={{ serveur_resolveur_site_sonde_config }}
TEMOIN='{{ serveur_resolveur_site_sonde_nom }}'
ADRESSE='{{ serveur_resolveur_site_sonde_adresse }}'
if (( ${#attendus[@]} == 0 )); then
# PAS UN SUCCES DEGUISE. Un site sans locataire declare est un etat legitime — mais le
# dire est preferable a rendre un vert qui laisserait croire qu'on a verifie quelque
# chose.
echo "Aucun supernet de locataire declare au plan du site : rien a verifier ici."
exit 0
fi
# 1. CHAQUE SUPERNET DE LOCATAIRE EST-IL ENCORE ADMIS ?
#
# On lit la configuration POSEE, pas celle qu'on croit avoir posee. `unbound-control` ne
# rend pas la liste d'acces ; les fichiers, si — et ce sont eux qu'Unbound a charges.
manquants=()
for reseau in "${attendus[@]}"; do
grep -rhqE "^[[:space:]]*access-control:[[:space:]]+${reseau//./\\.}[[:space:]]+allow" "${CONF}" 2>/dev/null \
|| manquants+=("${reseau}")
done
if (( ${#manquants[@]} > 0 )); then
echo "Locataire(s) non admis a resoudre ici : ${manquants[*]}. Leur amorcage lira « Echec temporaire dans la resolution du nom » — le message d'un DNS mort."
exit 2
fi
# 2. ET REPOND-IL A L'ADRESSE OU LES LOCATAIRES FRAPPENT ?
#
# CE N'EST PAS LA SONDE `resolution` DE `serveur_resolveur` REJOUEE. Celle-la interroge
# 127.0.0.1 : elle dit « unbound traduit ». Un locataire, lui, frappe l'adresse de
# l'interface — et une ecoute peut changer sans que la boucle locale bouge. On l'a deja
# paye ailleurs : un `reload` ne reapplique PAS un changement d'adresse d'ecoute, et le
# service reste vert depuis sa propre machine.
#
# POURQUOI `dig` ET PAS `check_dns`. Le greffon existe, mais dans
# `monitoring-plugins-standard` — et ce paquet traine samba, smbclient et une pile SNMP
# sur CHAQUE machine de la flotte (mesure du 2026-09-14). `client_sante` installe
# `monitoring-plugins-basic`, 53 greffons, qui ne contient pas `check_dns`. Un greffon
# absent sort en 127, ce qui n'est pas un code Nagios : la sonde deviendrait illisible.
# `dig` vient de `dnsutils`, deja present sur un resolveur, et c'est ce qu'emploie
# `resolution.sh` a cote.
if ! dig +short +time=5 +tries=2 "@${ADRESSE}" "${TEMOIN}" A 2>/dev/null | grep -qE '.'; then
echo "Les ${#attendus[@]} locataires sont admis, mais rien ne se traduit a ${ADRESSE} — l'adresse ou ils frappent. La boucle locale peut tres bien repondre encore."
exit 2
fi
echo "Resolveur du site : ${#attendus[@]} supernet(s) de locataire admis, et « ${TEMOIN} » se resout a ${ADRESSE}."
exit 0