feat/monitoring #6

Merged
thystips merged 2 commits from feat/monitoring into main 2026-08-02 01:50:15 +02:00
Owner
No description provided.
Le monitoring était la dernière zone d'ombre : quatre nœuds, sept peerings
externes, et aucun moyen de savoir qu'une session est tombée autrement qu'en
s'en apercevant. `ansible/README.md` réservait un rôle `monitoring` sans code
derrière, et `flow-matrix.md` avait déjà tranché sur la forme qu'il ne devait
pas prendre — « un exporter installé demain sur `[::]:9100` tombe sur le drop ».

Le modèle est le push, et c'est ce choix qui porte tout le reste : les exporters
restent sur `127.0.0.1`, Alloy les relève en local et pousse vers la stack
Mimir/Loki qui existe déjà. Le pare-feu ne gagne **aucune règle**, entrante ni
sortante — le commentaire du gabarit décrivait exactement ce moment, il dit
maintenant pourquoi il n'a pas fallu y toucher.

Le prix du push est nommé plutôt que subi : un nœud qui se tait ressemble à un
nœud sain. L'alerte d'absence côté Grafana n'est donc pas un raffinement, c'est
ce qui empêche de construire une supervision aveugle à sa propre panne.

Deux choses qu'aucun exporter ne peut produire passent par le collecteur
`textfile`, sans ouvrir de socket. WireGuard, parce qu'un tunnel n'a pas d'état
— seul l'âge du dernier handshake veut dire quelque chose. Et les sondes DNS
anycast, parce qu'Alloy vit dans la table globale quand les adresses vivent dans
la VRF : une sonde blackbox partirait par la mauvaise table et échouerait pour
une raison étrangère au DNS. `ip vrf exec` la met du bon côté, et le NSID que
Knot renvoie dit **quel** nœud a répondu — la seule chose qui prouve qu'un
basculement anycast a eu lieu.

Deux prérequis manquaient, tous deux invisibles jusqu'à l'échec :

- `thystips.xyz` n'existe sur aucun serveur public, et l'Unbound global récurse
  depuis la racine, délibérément. La zone est donc routée vers le résolveur du
  site, déclaré dans `topology/`, et **hors VRF** : faire dépendre la résolution
  de l'ingest de l'overlay ferait mourir la supervision avec ce qu'elle surveille.
- L'ingest présente un certificat de notre propre step-ca. Le root est récupéré
  en TOFU — l'hôte de la CA présente un certificat de cette CA, il n'y a pas de
  premier pas vérifié — puis épinglé sur son empreinte, ce qui le rétablit.

Le transport passe par la patte privée de Roubaix, restée en TODO depuis
l'origine. `topology/` décrit maintenant le plan privé et son routeur, sous une
clé `private_router` distincte de `site_router` : cette dernière signifie
« participant DN42 » et entraîne un router-id réservé, des sessions iBGP et un
enregistrement de zone, dont `outrider` n'a rien. Les réutiliser casserait
l'inventaire au premier `ansible-inventory --list`.

Le plugin refuse maintenant les quatre erreurs que ce plan rend possibles : une
adresse DN42 sur la patte privée — qui est en table globale, donc hors de tout
filtre Bird —, une adresse hors du segment de sa passerelle, une route par
défaut qui volerait celle par où Ansible arrive, et un résolveur interne
qu'aucune route n'atteint. Les quatre sont vérifiées par test négatif.

`render-check.py` couvre trois rôles de plus, rend **chaque** patte LAN au lieu
de la première — le gabarit branche dessus — et passe les scripts shell à
`bash -n`, pour la même raison qu'il passe le jeu de règles à `nft -c` : sur un
routeur, une erreur de syntaxe est une métrique qui cesse d'être écrite, pas
quelque chose qui échoue visiblement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FGwvXLVXJ2PrRFwJTB3Xp9
Six corrections, toutes trouvées en déroulant sur un nœud avant les trois autres.
Aucune n'était visible à la lecture.

Le root CA privé est retiré. Le plan supposait que l'ingest présentait un
certificat de notre step-ca, comme les endpoints `api-ssl` des RouterOS. Il
présente un certificat **Let's Encrypt**, que le magasin de la distribution
valide déjà. Vérifié plutôt que supposé — et l'installer aurait élargi ce qu'un
routeur de bordure accorde, pour un besoin inexistant.

La télémétrie serait sortie par l'IPv6 publique. Les noms de la zone interne
portent une AAAA routable et une A privée, et RFC 6724 préfère la première : le
lien privé serait resté inutilisé. Une entrée `gai.conf` limitée au préfixe
ATNET remet l'A devant, et le fichier reproduit la table par défaut de glibc —
une seule ligne `precedence` remplace la table entière, ce qui aurait réordonné
toute la sélection d'adresses du nœud. Mesuré après coup : Alloy sort bien de
`10.1.242.203` vers `10.2.70.168`.

`kdig` n'accepte pas `+tries`, qui est une option de `dig` — les quatre sondes
DNS revenaient à zéro sans rien dire. Et ni le NSID ni le temps de réponse ne
sont là où `dig` les met : le premier est entre guillemets, le second sur la
ligne `;; From … in N ms`. Les sondes montrent maintenant ce pour quoi elles
existent — depuis `fr-rbx2`, l'autoritatif répond `fr-rbx1`, donc l'anycast
route.

Le rôle rejoint le premier play au lieu d'en avoir un à lui. Il nomme
`rpki_metrics_bind`, et les `defaults` d'un rôle ne sont en portée que pour le
play qui le joue. `render-check.py` masquait le problème en fournissant la
variable de son côté ; il le fait toujours, mais en disant maintenant pourquoi.

`base` flush ses handlers après avoir configuré les dépôts. Sinon apt installe
depuis une source qu'il n'a jamais lue, et `cache_valid_time` aggrave le cas
plutôt qu'il ne l'aide : un cache rafraîchi la minute d'avant reste « valide »,
donc jamais relu. Le message est « No package matching 'alloy' », qui désigne
tout sauf la cause.

Le reste est plus petit : `gpg` n'est pas installé sur ces routeurs et n'a pas à
l'être — apt lit un keyring ASCII sous une extension `.asc` ; `unarchive` ne sait
pas vérifier une empreinte, donc téléchargement et extraction sont deux étapes,
vers un répertoire versionné pour qu'une montée de version ne soit pas sautée par
`creates` ; et l'unité systemd de `bird_exporter` manquait tout simplement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FGwvXLVXJ2PrRFwJTB3Xp9
thystips deleted branch feat/monitoring 2026-08-02 01:50:15 +02:00
thystips referenced this pull request from a commit 2026-08-02 01:50:15 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ThysTips_dn42/infra-dn42!6
No description provided.