Construire un vrai réseau d'alarme pour son homelab (et toutes les manières dont ça peut foirer en silence)

Un homelab, ça tombe en panne. C’est normal. Le vrai problème, ce n’est pas la panne elle-même, c’est de l’apprendre trois jours plus tard en tombant dessus par hasard.
Trois exemples vécus ici, à des moments différents :
- Un watchdog réseau qui avait cessé de fonctionner silencieusement pendant plusieurs jours — découvert en enquêtant sur un tout autre problème.
- Un service d’assistant vocal resté hors service après un redémarrage, sans aucune notification.
- Un pipeline de sauvegarde avec son propre logging local, mais dans un coin que personne ne regarde jamais.
Trois mécanismes de surveillance différents, trois endroits de logs différents, et surtout : aucun canal d’alerte central. Dans les deux vrais incidents qui ont motivé ce projet, la panne a été découverte après coup, jamais signalée activement.
La solution : un Uptime Kuma privé (accessible seulement par VPN) branché sur ntfy pour les notifications push, et migrer un par un tous les watchdogs existants vers ce point central.

Round 1 : les trois premiers watchdogs
Trois services, trois mécanismes différents selon leur nature :
| Watchdog | Type de moniteur | Pourquoi |
|---|---|---|
| Service Ollama sur un PC Windows | HTTP actif | Kuma peut interroger directement son API |
| Watchdog IPv6 (script cron) | Push (dead man’s switch) | C’est un script — facile d’y ajouter un heartbeat en fin d’exécution |
| Sauvegarde quotidienne | Push | Ne tourne qu’une fois par jour, un poll actif ne colle pas |
Ça semblait simple. Ça ne l’était pas tout à fait.
Premier vrai bug réseau trouvé au passage : le serveur central ne pouvait pas du tout joindre le PC Windows qui hébergeait Ollama — ni par son IP principale, ni par une IP secondaire, alors que d’autres machines du même réseau répondaient sans problème. Le coupable : le pare-feu Windows restreint la règle au “sous-réseau local”, ce qui laisse passer le trafic d’autres appareils de la maison mais bloque celui qui arrive via le tunnel VPN, dont l’adresse source ne correspond pas à ce sous-réseau. Contournement temporaire : passer ce moniteur en mode push plutôt qu’en poll actif, le temps de creuser la vraie cause plus tard.
Deuxième surprise : le résolveur DNS local du pare-feu maison bloquait silencieusement les requêtes internes pointant vers des IP privées (protection anti-rebinding), ce qui aurait fait échouer le heartbeat du watchdog IPv6 pour toujours, sans qu’on comprenne pourquoi. Fixé avec une exception ciblée sur le domaine interne concerné.
Trois moniteurs migrés, deux vrais bugs réseau découverts et corrigés en cours de route. Pas mal pour “juste brancher un dashboard”.
Round 2 : le pare-feu Windows, pour de vrai cette fois
Le contournement push pour Ollama a fini par être réparé proprement : la vraie cause n’était pas l’adresse source qu’on croyait au départ, mais l’adresse de sortie réelle du tunnel VPN, combinée au fait que la machine avait deux passerelles par défaut différentes, ce qui causait un routage asymétrique que le pare-feu du routeur laissait tomber silencieusement. Une fois corrigé avec une règle de pare-feu élargie et une route statique, le moniteur Ollama est repassé en simple polling HTTP actif, plus simple à maintenir.
Deux autres machines du réseau (une Home Assistant, un NAS) avaient exactement le même genre de problème de routage — même classe de bug, corrigé de la même manière, moniteurs ajoutés une fois la connectivité confirmée.
Round 3 : la caméra qui ment sans le savoir
Un moniteur “Frigate répond” ne suffit pas : Frigate peut très bien répondre en HTTP 200 pendant que la caméra elle-même est plantée. Solution : un moniteur “JSON Query” qui va chercher directement le compteur d’images par seconde de la caméra dans l’API de stats de Frigate, avec une expression booléenne (camera_fps > 0). Piège rencontré : le moteur d’expression utilisé n’est pas du JSONPath classique mais du JSONata, avec ses propres règles d’échappement — à vérifier contre un vrai payload avant de faire confiance à la syntaxe.
Encore plus vicieux : un moniteur qui vérifie que les enregistrements vidéo sont bel et bien écrits en continu (pas juste que la caméra tourne). Ça permet d’attraper le cas “Frigate est up, la caméra est up, mais l’enregistrement s’est arrêté silencieusement” — un état que rien d’autre ne détecte. Ce script compare la durée cumulée enregistrée sur l’heure, avec une tolérance de quelques minutes de trous pour absorber les micro-coupures. Le piège ici : l’API de Frigate découpe les heures en buckets UTC, pas en heure locale — à ne jamais oublier quand on fait le calcul de “combien de minutes se sont écoulées cette heure-ci”.
Le bug bête qui a fait perdre le plus de temps
Un jour, l’app ntfy envoie une notification, on clique sur “ouvrir le moniteur”, et ça atterrit n’importe où. En creusant : le bouton “ouvrir” du fournisseur de notification ntfy utilise le champ URL du moniteur lui-même, pas l’URL de base de Kuma. Sauf que les moniteurs de type Push (et aussi, découverte annexe, les moniteurs de type Port) n’ont tout simplement pas de champ URL par défaut — le bouton est donc cassé par construction pour ce genre de moniteur. Solution : leur donner une URL bidon à la création, juste pour que le bouton fonctionne.
Petit détail amusant : ce bug a été retrouvé une deuxième fois, des semaines plus tard, sur un tout nouveau lot de moniteurs — preuve qu’il vaut mieux le noter noir sur blanc plutôt que compter sur sa mémoire.
L’usurpation d’identité involontaire
Un service de streaming vidéo maison redémarrait sans arrêt de façon mystérieuse. L’enquête a suivi une vraie chaîne de dominos :
- Le NAS qui l’héberge avait rebooté tout seul plusieurs jours plus tôt (RAM limitée, cause exacte jamais confirmée).
- Le service ne redémarrait pas automatiquement après coup malgré la config qui disait le contraire — fichier de PID resté périmé.
- Un watchdog cron a été ajouté (vérifie le process, relance si mort, pousse un heartbeat).
- Le moniteur s’est mis à clignoter (up/down en boucle) — panique.
- Cause du clignotement n°1 : un service DNS interne autrefois hébergé maison venait d’être décommissionné, cassant la résolution du nom d’hôte utilisé par le script de heartbeat. Corrigé en épinglant l’adresse IP directement dans l’appel HTTP, sans dépendre du DNS.
- Cause du clignotement n°2, complètement indépendante : l’intervalle de heartbeat configuré dans Kuma (2 minutes) était plus court que la fréquence réelle du cron qui pousse le heartbeat (5 minutes) — Kuma marquait donc systématiquement le moniteur “down” entre deux passages, avant de le repasser “up” au heartbeat suivant. Un flapping totalement auto-infligé, sans aucun rapport avec le DNS. Corrigé en élargissant l’intervalle.
Deux bugs indépendants, le même symptôme, découverts l’un après l’autre. Une bonne leçon : ne pas s’arrêter à la première explication plausible.
Le compte administrateur qui change de nom en plein vol
Dernier rebondissement : une tentative d’automatiser la création de moniteurs via l’API a échoué avec “mot de passe incorrect” — alors que le mot de passe, copié-collé depuis le gestionnaire de mots de passe, était clairement le bon. Fausse piste explorée en premier : une incompatibilité de version entre la bibliothèque cliente et le serveur Kuma. Fausse piste écartée, puis reprise, puis écartée à nouveau.
La vraie explication, trouvée en croisant les logs serveur avec un journal de travail personnel : une session parallèle, plus tôt dans la même journée, avait renommé le compte administrateur pour une tout autre raison, sans le documenter ailleurs sur le moment. Le nom d’utilisateur utilisé pour l’authentification API était donc simplement périmé — rien à voir avec un bug de compatibilité.
Morale : quand deux sessions de travail touchent la même infra le même jour sans se voir, la première explication technique plausible n’est pas toujours la bonne. Garder une trace écrite (même minimale) de chaque changement d’état “invisible” (comme un renommage de compte) aurait évité de tourner en rond.
Où ça en est aujourd’hui
Le dashboard central couvre maintenant une bonne quinzaine de services : DNS interne, sauvegardes automatisées, service vocal domestique, domotique, stockage réseau, serveur de streaming, caméra de surveillance et son pipeline d’enregistrement complet (capture → miroir local → synchronisation cloud). Chaque panne pousse une notification sur le téléphone en quelques secondes, testée et confirmée dans les deux sens (déclenchement volontaire d’une fausse panne, puis retour à la normale) pour chaque nouveau moniteur.
Ce qui devait être “brancher un dashboard de monitoring” a fini par débusquer un pare-feu mal configuré, une protection DNS anti-rebinding oubliée, un bug d’UI Kuma reproductible, un piège d’échelle de temps UTC, et un cas classique de main gauche qui ignore ce que fait la main droite. Le monitoring, ça ne se contente pas de surveiller l’infra — ça finit toujours par la mettre à nu.