Set-OPS-Public/roles/serveur_nginx/templates/sonde-edge.sh.j2
Daniel Allaire 6b6a56ab3f sondes filtrage et edge : elles verifient le service rendu ; l edge refuse les noms inconnus
filtrage soumet GTUBE ; edge interroge chaque exposition en local. Sans serveur
par defaut, un nom inconnu recevait Keycloak : 000-defaut.conf (444, rejet TLS).
Garde test_sondes_syntaxe : chaque gabarit de sonde se rend en bash valide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 19:40:26 -04:00

56 lines
2.9 KiB
Django/Jinja

#jinja2: comment_start_string:'{=#', comment_end_string:'#=}'
#!/bin/bash
# GENERE par Set-OPS (role serveur_nginx). Ne pas editer a la main.
#
# SONDE « edge » — l'edge ecoute, sa configuration tient, et ce qu'il publie REPOND
#
# Contrat : docs/supervision-conception.md (API des greffons Nagios) — une ligne, 0/1/2.
# Mise en defaut PAR PARAMETRE : `serveur_nginx_sonde_ports` (port qui n'ecoute pas).
set -uo pipefail
PORTS="{{ serveur_nginx_sonde_ports }}"
systemctl is-active --quiet nginx || { echo "L'edge (nginx) n'est pas actif."; exit 2; }
# LA CONFIGURATION SUR DISQUE, PAS SEULEMENT CELLE EN MEMOIRE. nginx garde la derniere
# configuration VALIDE et continue de servir ; une configuration cassee ne se voit qu'au
# prochain redemarrage — c'est-a-dire au pire moment, souvent des mois plus tard.
nginx -t >/dev/null 2>&1 \
|| { echo "L'edge sert, mais sa configuration sur disque est INVALIDE : le prochain demarrage echouera."; exit 2; }
manquants=()
for p in ${PORTS}; do
ss -ltn 2>/dev/null | grep -qE "[:.]${p}[[:space:]]" || manquants+=("${p}")
done
if (( ${#manquants[@]} > 0 )); then
echo "L'edge n'ecoute pas sur : ${manquants[*]} — ce qui est publie derriere est injoignable."
exit 2
fi
# CE QUI EST PUBLIE REPOND-IL ? (2026-09-28) Ecouter n'est pas servir : un service publie
# dont l'amont est tombe rend 502, et l'edge reste « valide, a l'ecoute ». On interroge chaque
# exposition EN LOCAL — son nom et son SNI, vers 127.0.0.1 — : on teste ce que l'EDGE sert,
# sans dependre de la resolution de qui que ce soit. `-k` : le certificat est l'affaire de la
# sonde `certificat` ; ici, la question est la reponse. Une redirection (302 vers la
# connexion) est une reponse saine ; un 5xx ou un silence ne l'est pas.
{=# LE MEME FILTRE QUE LES VHOSTS (`expositions.conf.j2`) : un hote connu, une adresse, un
port. Une exposition sans port web (`dns`, `pki`, `sauvegarde` au site) n'a pas de vhost :
l'attendre ici faisait crier la sonde pour trois noms que l'edge ne publie pas. #=}
{% set publiees = [] %}
{% for expo in serveur_nginx_expositions | default([]) %}
{% if expo.hote in hostvars and hostvars[expo.hote].ansible_host is defined and expo.port %}
{% set _ = publiees.append(expo.fqdn) %}
{% endif %}
{% endfor %}
EXPOSITIONS="{{ publiees | unique | sort | join(' ') }}"
en_defaut=(); servies=0
for n in ${EXPOSITIONS}; do
code=$(curl -sk -o /dev/null -w '%{http_code}' --max-time 8 --resolve "${n}:443:127.0.0.1" "https://${n}/" 2>/dev/null)
if [[ "${code}" =~ ^[234][0-9][0-9]$ ]]; then servies=$((servies + 1)); else en_defaut+=("${n}=${code:-000}"); fi
done
perf="| expositions=${servies};;;0; en_defaut=${#en_defaut[@]}"
if (( ${#en_defaut[@]} > 0 )); then
echo "L'edge ecoute, mais des expositions ne sont PAS servies : ${en_defaut[*]} (000 = silence, 5xx = amont en defaut). ${perf}"
exit 2
fi
echo "Edge : configuration valide, ecoute sur ${PORTS}, ${servies} exposition(s) servie(s). ${perf}"