ANY UDP tronque, AXFR/NOTIFY/UPDATE refuses depuis dehors, debit par /24 (rafale 300 -> 70 reponses, 230 tronquees). PowerDNS garde le 53 pour les primaires ; le frontal ecoute 1053, ou la frontiere redirigera. Sonde par le frontal. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
65 lines
3.3 KiB
Django/Jinja
65 lines
3.3 KiB
Django/Jinja
#!/bin/bash
|
|
# GENERE par Set-OPS (role serveur_dns_public). Ne pas editer a la main.
|
|
#
|
|
# SONDE « zones-publiques » — le serveur public sert-il TOUTES les zones qu'il doit servir ?
|
|
#
|
|
# Contrat : docs/supervision-conception.md (API des greffons Nagios) — une ligne, 0/1/2.
|
|
# Mise en defaut PAR PARAMETRE : `serveur_dns_public_sonde_attendu` (seuil impossible).
|
|
set -uo pipefail
|
|
|
|
ATTENDU={{ serveur_dns_public_sonde_attendu }}
|
|
ICI={{ serveur_dns_public_ecoute }}
|
|
|
|
systemctl is-active --quiet pdns || { echo "Le serveur DNS public (pdns) n'est pas actif."; exit 2; }
|
|
systemctl is-active --quiet dnsdist || { echo "Le frontal public (dnsdist) n'est pas actif : Internet n'obtient plus aucune reponse."; exit 2; }
|
|
|
|
# ON INTERROGE CE QUE LE MONDE INTERROGERA : le SOA de chaque zone, sur l'adresse d'ecoute.
|
|
# Un secondaire qui n'a jamais recu sa zone repond REFUSED ou SERVFAIL — ce qui, vu d'un
|
|
# registraire, se lit « serveur de noms defaillant ».
|
|
servies=0
|
|
manquantes=()
|
|
{% for zone in serveur_dns_public_relations | map(attribute='zones') | flatten %}
|
|
# PAR LE FRONTAL : c'est le chemin que prend l'Internet. PowerDNS peut servir la zone et
|
|
# dnsdist la refuser — seul ce chemin-ci voit les deux.
|
|
if [[ -n "$(dig +short +time=3 +tries=1 @"${ICI}" -p {{ serveur_dns_public_frontal_port }} SOA {{ zone }} 2>/dev/null)" ]]; then
|
|
servies=$((servies + 1))
|
|
else
|
|
manquantes+=("{{ zone }}")
|
|
fi
|
|
{% endfor %}
|
|
|
|
# LES SIGNATURES DES ZONES SIGNEES (2026-09-16). Le primaire du locataire renouvelle ses
|
|
# signatures chaque semaine ; son serial servi est l'heure (SOA-EDIT EPOCH), et le site
|
|
# retire la zone a chaque rafraichissement. Si ce relais casse, rien ne tombe tout de suite :
|
|
# les signatures servies EXPIRENT, en 7 a 14 jours, et le domaine devient BOGUS d'un coup.
|
|
# Normalement il reste entre 7 et 14 jours ; on avertit sous 6, on alerte sous 3.
|
|
maintenant=$(date -u +%s)
|
|
alerte=()
|
|
avert=()
|
|
{% for zone in serveur_dns_public_relations | map(attribute='signees') | map('default', []) | flatten %}
|
|
exp=$(dig +dnssec +noall +answer +time=3 +tries=1 @"${ICI}" -p {{ serveur_dns_public_port }} SOA {{ zone }} 2>/dev/null | awk '$4 == "RRSIG" { print $9; exit }')
|
|
if [[ -z "$exp" ]]; then
|
|
alerte+=("{{ zone }} (non signee)")
|
|
else
|
|
jours=$(( ( $(date -u -d "${exp:0:8} ${exp:8:2}:${exp:10:2}:${exp:12:2}" +%s) - maintenant ) / 86400 ))
|
|
if (( jours < 3 )); then alerte+=("{{ zone }} (${jours} j)")
|
|
elif (( jours < 6 )); then avert+=("{{ zone }} (${jours} j)"); fi
|
|
fi
|
|
{% endfor %}
|
|
|
|
if (( servies < ATTENDU )); then
|
|
echo "Le serveur public ne sert que ${servies} zone(s) sur ${ATTENDU} : ${manquantes[*]:-?} — ces domaines ne resolvent plus depuis Internet.|zones=${servies};${ATTENDU};;0;"
|
|
exit 2
|
|
fi
|
|
{# `${#tableau[@]}` ouvrirait un commentaire Jinja : ces lignes sont rendues telles quelles. #}
|
|
{% raw %}
|
|
if (( ${#alerte[@]} > 0 )); then
|
|
echo "Signatures DNSSEC absentes ou sur le point d'expirer : ${alerte[*]} — ces domaines deviennent BOGUS pour les resolveurs validants.|zones=${servies};${ATTENDU};;0;"
|
|
exit 2
|
|
fi
|
|
if (( ${#avert[@]} > 0 )); then
|
|
echo "Signatures DNSSEC qui ne se renouvellent plus : ${avert[*]} — le primaire du locataire relaie-t-il encore ?|zones=${servies};${ATTENDU};;0;"
|
|
exit 1
|
|
fi
|
|
{% endraw %}
|
|
echo "Serveur public : ${servies} zone(s) servie(s) sur ${ATTENDU}, signatures a jour.|zones=${servies};${ATTENDU};;0;"
|