# Intervention shogun.ovh — apt-get update réparé + supervision DNS

**Date** : 2026-10-31 · **Agent** : vps-admin · **Serveur** : `shogun@shogun.ovh -p 2022` (Debian 12, Yunohost, 2e VPS)

## Symptôme

`apt-get update` impossible (timeout) — récurrent.

## Cause racine

**dnsmasq (DNS local, point unique) figé** : daemon actif mais ne lit plus sa socket UDP 53 (213 Ko en attente). `/etc/resolv.conf` → `127.0.0.1` (resolvconf) → tout le serveur sans DNS. Réseau OK (ping, TCP 80, DNS externe OK).

**Journal (`journalctl -u dnsmasq`, persistant) — récurrence établie** :

- Wedges avérés : 30/09 (timeout), 15/10 (SIGTERM ignoré → SIGKILL), 31/10 (idem = panne du soir).
- **Floods horaires** : `max requêtes concurrentes (150)` — 258× sur le boot du 15/10→31/10, **quasi toutes les heures à la minute :27** (108× puis 56× sur les boots précédents → empire). Flooder = app/conteneur, pas un cron système.

## Correctifs appliqués

| # | Action | Détail |
|---|---|---|
| 1 | Fix immédiat | `systemctl restart dnsmasq` (via `sudo -S` + secret) → `apt-get update` rc=0 |
| 2 | **Watchdog** | `/usr/local/sbin/cron-5min-dns-watchdog.sh` + `/etc/cron.d/dns-watchdog` (`*/5`) : `dig @127.0.0.1` **rc≠0** (silence, pas le contenu — NXDOMAIN est sain) → restart `timeout 180` + alerte ntfy |
| 3 | Alerte ntfy | user dédié `watchdog@shogun.ovh` (write-only, topic `vps-shogun`), secret `/root/.config/ntfy-watchdog.env` (600 root, `curl -K -` via stdin) — reçu par `guillaume_ryckelynck` (admin) dans l'app ntfy sur `https://ntfy.shogun.ovh` |
| 4 | **Traçage flooder** | `/etc/dnsmasq.d/99-trace-queries.conf` : `log-queries=extra` → `/var/log/dnsmasq-queries.log` (IP source par requête) — **temporaire**, à retirer après identification à la prochaine :27 |
| 5 | Seuil | `/etc/dnsmasq.d/98-limits.conf` : `dns-forward-max=300` (bande-plâtre le temps du traçage) |
| 6 | Rotation | `/etc/logrotate.d/dnsmasq-queries` : daily, 7 rétentions, `copytruncate` (validé) |

Tests : chemin nominal en `env -i` (env cron) → silencieux rc=0 ; échec forcé → restart + alerte reçue ; publication ntfy HTTP 200.

## Nettoyage

- `/etc/sudoers.d/apt-nopasswd` **supprimé** (inopérant : écrasé par le rôle LDAP `admins` → `(root) ALL` ; le sudo passe par le coffre pass).
- Secret : `opencode/shogun-sudo` (coffre pass, injecté en pipe, jamais affiché).

## À faire / surveiller

- **Après la prochaine minute :27** : lire `/var/log/dnsmasq-queries.log` → identifier le flooder, retirer le traçage.
- Si dnsmasq se re-figure → watchdog + `journalctl -u dnsmasq`.
- Services en échec relevés : `gitlab-runsvdir`, `mongod`.

## Voir aussi

Skill [[80_CONFIG/IA_SKILLS/Shogun-admin]] (accès, secrets, supervision du 2e serveur).

## Journée du 01/11 — flooder identifié + ménage complet

### 🔴 Flooder DNS identifié et coupé : module `dnsmasq` de netdata

Méthode : preuve par élimination (arrêt/restart netdata → delta TXT 0 puis reprise) puis **désactivation par lots** dans `go.d.conf`. ⚠️ Pièges : les tests `go.d.plugin` standalone sont non concluants (sans pipe netdata, le binaire ne tourne pas) et le binaire **mange le stdin** du script ssh (d'où sorties perdues).

| Test (contexte service) | Résultat |
|---|---|
| service ON / OFF | delta 10 / delta 0 → netdata = seule source |
| `dns_query`+`dnsmasq`+`dnsdist` OFF | delta 0 → lot entier coupable |
| `dns_query` OFF, `dnsmasq` ON, `dnsdist` OFF | delta 9 → **dns_query/dnsdist innocentés** |
| **`dnsmasq: no`** | **delta 0 sur 20 s** ✅ |

**Fix** : `/var/www/netdata/etc/netdata/go.d.conf` regénéré depuis stock avec `bind: no` + **`dnsmasq: no`** (fichier `go.d/bind.conf` redondant supprimé). Le module dnsmasq de netdata interrogeait dnsmasq en TXT `*.bind` (format réservé à BIND) **1×/seconde** — dnsmasq n'est pas BIND → requêtes inutiles. Cessé.

Note : ce flood était du **bruit de fond** (6 TXT/s, 30 000 lignes/8 h), pas la cause directe des saturations horaires.

### 🟠 Saturations horaires (:44) — traçage en place

- Échantillonneur **`/etc/cron.d/dns-burst-capture`** (`44 * * * *`) + `/usr/local/sbin/cron-horaire-dns-burst-capture.sh` → `/var/log/dns-burst-capture.log` (rotation `/etc/logrotate.d/dns-burst-capture`, daily/7).
- Capture : sockets `ss` vers 127.0.0.1:53 sur 80 s (minute :44 entière) + journal filtré. **À lire après la prochaine :44**, puis retirer le cron + script + log.
- Constat au pic : 212 PTR inversées 192.168.x.x + `index.localai.io` forwardé aux 12 amonts ; corrélation purge wikijs (:44:17) / localai (:44:13), saturation à :44:49.

### ✅ Ménage du 01/11

- **GitLab** : paquet `gitlab-ce` purgé (état fantôme `rc`), unit orpheline `gitlab-runsvdir` supprimée — aucune donnée (dossiers déjà absents).
- **MongoDB** : base inspectée **sur copie** (conteneur `mongo:4.4` éphémère, auto-nettoyé) → base **`wekan`** (2,8 Mo, dernière écriture **2024-08-16**, Wekan désinstallé depuis). Backup `/var/backups/mongodb-wekan-20261101.tar.gz` (207 Mo) puis **9 paquets mongodb purgés** + `/var/lib/mongodb` supprimé (511 Mo récupérés).
- **Services en échec : 0** après ménage (gitlab + mongod + logrotate réparé via `su root guacamole` ×2).
- **ntfy** : compte **`shogun`** créé (admin) → app `https://ntfy.shogun.ovh`, topic `vps-shogun`. Secret temp `opencode/shogun-ntfy` supprimé du coffre (mdp changé par GRK).
- **Grist** : `chown -R grist:grist /home/yunohost.app/grist/` → fin du `SQLITE_READONLY` (NRestarts figé à 693).

### Clôture du traçage (01/11 11h)

- **Flooder horaire :44 identifié = Home Assistant (`hass`)** : capture 10:44 → 258/261 sockets DNS de `hass` (scan reverse du /24 `192.168.100.0/24`, pic 341 PTR/s à :44:44). Bénin (device tracker), aggravé par le TXT netdata depuis corrigé — **plus aucune saturation depuis 08:44**.
- **Nettoyage effectué** : `dns-burst-capture` (cron+script+log) et `99-trace-queries.conf` + `/var/log/dnsmasq-queries.log` supprimés, dnsmasq redémarré (DNS OK).
- **`dns-forward-max=300` conservé** (`98-limits.conf`) comme filet contre le scan HA.
- **Décision** : laisser le scan HA tel quel (bénin, plus de saturation).
- Vigilance : si saturations reviennent → regarder `journalctl -u dnsmasq` (watchdog 5 min déjà en place).
