nas-runbooks/common/vps-memory-node.md

7.3 KiB
Raw Blame History

VPS memory-node — Objectif A : nœud mémoire persistante (10/07/2026)

Statut : en production. Le VPS Contabo (contabo-vps-qbt, tailnet 100.94.90.119) réplique en continu la mémoire du NAS : miroir git nas-runbooks, données NyoraNotes et context-hub, avec snapshots restic versionnés.

Architecture — PULL depuis le VPS (pas push depuis le NAS)

Choix imposé par deux constats du 10/07 :

  1. Pas de sudo/cron direct sur le NAS pour Claude (décision Nabil 10/07, définitive : le mot de passe sudo n'est pas transmis ; les crons NAS passent par le Planificateur de tâches DSM en root — Nabil crée les tâches, Claude écrit les scripts ; le root ponctuel se fait en session interactive avec Nabil).
  2. NAS→VPS port 22 KO par le tailnet (timeout), alors que VPS→NAS fonctionne. Cause : Tailscale Synology en mode userspace. Conséquence jour J : le « delta final NAS→VPS » se fera en pull depuis le VPS.

Tout tourne donc sur le VPS, user claude-oversight (cron) :

Quoi Script Cadence
Miroir git + rsync données /opt/memory-node/bin/memory-sync.sh horaire (h+17)
Snapshot restic /opt/memory-node/bin/backup-push.sh quotidien 03:30
Vérif intégrité + restauration test /opt/memory-node/bin/backup-verify.sh hebdo dim. 04:00

Échec de job → alerte Telegram (bot hermes-perso → Nabil) via notify-telegram.sh.

Contenu répliqué

  • /opt/memory-node/git/nas-runbooks.git : miroir bare, pull horaire depuis Gitea (100.86.197.88:3232, token Gitea lecture vps-memory-node-mirror, credentials dans la config du remote, home 700).
  • /opt/memory-node/data/nyora-notes/ et data/context-hub/ : rsync --delete depuis /volume1/docker/….
  • Exclusions délibérées : .env, *.bak, @eaDir, .DS_Store — aucun secret répliqué sur le VPS ; les .env se récupèrent via le backup USB.
  • Snapshots restic : /opt/restic-repo (rétention 14 j + 8 sem., forget --prune à chaque push).

Mot de passe restic — emplacements (jamais dans ce repo)

  • Maître : NAS /volume1/docker/scripts/.restic-password (chmod 600, Best0f).
  • Copie runtime : VPS /opt/memory-node/.restic-pass (chmod 600, claude-oversight) — nécessaire car restic s'exécute sur le VPS.
  • Les deux fichiers contiennent la même valeur. Si rotation : regénérer sur le NAS, recopier sur le VPS, restic init d'un nouveau repo (l'ancien devient illisible).

Accès VPS

  • Tailscale SSH uniquement (port 22 tailnet ; 22 public filtré par ufw, 2222/22222 fermés). root = mode check (ré-auth web périodique) ; claude-oversight = accept.
  • claude-oversight : sudoers scopé (/etc/sudoers.d/claude-oversight) — start/stop/restart de qbittorrent-nox, docker, tailscaled + journalctl/status. PAS de NOPASSWD:ALL.
  • Connexion interactive claude-oversight → alerte Telegram (/etc/profile.d/claude-oversight-login-alert.sh).
  • Docker 29 + compose v5 installés (prérequis doublure jour J), aucun conteneur lancé.

Accès NAS depuis le VPS (le seul sens qui marche)

Clé id_ed25519 de claude-oversight autorisée pour Best0f (port 22222) mais bridée par forced-command ~/.ssh/vps-memory-pull.sh :

  • source exigée 127.0.0.1 (= proxy userspace Tailscale ; un from="100.94.90.119" classique ne marche PAS, le NAS voit 127.0.0.1) ;
  • seule commande admise : rsync --server --sender (lecture seule) sur nyora-notes/ et context-hub/.

Vérifications rapides

ssh claude-oversight@100.94.90.119            # depuis le Mac (tailnet)
tail /opt/memory-node/log/memory-sync.log     # rc=0 attendu
restic -r /opt/restic-repo --password-file /opt/memory-node/.restic-pass snapshots --compact
git -C /opt/memory-node/git/nas-runbooks.git log --oneline -1   # doit suivre Gitea à 1 h près

Restauration (perte du NAS)

  1. git clone /opt/memory-node/git/nas-runbooks.git → savoir complet.
  2. restic restore latest --target /tmp/r → données NyoraNotes/context-hub datées.
  3. Relancer les services sur le VPS avec ces données (Docker déjà prêt).

Reste à faire (hors Objectif A)

  • Renommer le nœud tailnet NAS ahmed---yesminenas (Nabil, console admin Tailscale).

Incident mot de passe — audit de purge (1011/07/2026)

L'ex-mot de passe sudo Best0f (périmé, non remplacé : root NAS = Planificateur DSM + sessions interactives) a été purgé de partout où il traînait. Anti-pattern racine : le skill Hermes nas-executor (09/06/2026) l'avait hardcodé en SSHPASS="…" (10×) — de là il s'est propagé dans les backups de skills, la base d'état de l'agent, le repo git et le backup USB. Règle : un skill lit ses secrets depuis l'env/.env, jamais en littéral.

Emplacements scannés — PROPRES

Arbre + historique git nas-runbooks ; historiques git hermes-skills, hermes-platform, linux-mcp-nas, nabil-brain, claude-cowork-nas ; vault NyoraNotes (md + SQLite via strings) ; context-hub (données + SQLite) ; data/ hermes-tt et hermes-nyora ; *.md racine /volume1/docker, clone STALE, claude_contexte/ ; pingvin ; historiques shell Best0f (inexistants) ; USB _memoire/ ; VPS /opt/memory-node/.

PURGÉS (1011/07)

  • Mémoire Claude (Mac) : 3 fichiers réécrits sans la valeur.
  • hermes-perso/data/backups/skills-20260609-214432/…/nas-executor/ : SKILL.md + references/dsm-api-access.md (11 occ. → [REDACTED-purge-20260711]).
  • hermes-perso/data/state.db.corrupt-20260709-231035 (407 Mo) : rédaction binaire à longueur constante, 0 occ. restante.
  • Repo Gitea hermes-perso HEAD : commit 64fdcc5 (SSHPASS$NAS_SSH_PASSWORD). Le repo était en retard sur le live.

RÉSIDUELS — session interactive root requise

  • linux-mcp-nas/audit.log (root:root 600, invérifiable sans root) — l'historique avait été scrubbé le 08/07, à confirmer/sed si besoin.
  • Backup USB (Best0f sans écriture) : 4 fichiers skills (sets 04/07 et 10/07) + state.db.corrupt (set 10/07) — versions non purgées.
  • /volume1/@docker/volumes/ : non scannable sans root.

RÉSIDUEL ACCEPTÉ (à trancher)

  • Historique git hermes-perso : le commit 574faf1 (intro du skill) contient le mot de passe. Réécriture d'historique = lourde ; mot de passe périmé + repo privé LAN → acceptation documentée recommandée.

Constats connexes (hors purge, à corriger)

  • Le skill live nas-executor (hermes-perso) hardcode un autre secret actif (SSHPASS=…, 3×) — même anti-pattern, à passer en variable d'env.
  • L'arbre courant de nas-runbooks contient encore des secrets famille 2L2u519w* en clair (bestof/DSM dans HEBERGEMENT-SITES-STATIQUES.md, cin-search-tt…) : la rotation totale demandée par l'audit mcp-nas du 08/07 reste à faire.

mcp-vps — organe d'action blackout (12/07/2026)

Le VPS héberge désormais mcp-vps : MCP Linux (dérivé de linux-mcp-nas) exposé via Cloudflare Tunnel sur mcp.yesminedor.tn (zone migrée OVH→CF, aucun port ouvert sur l'IP Contabo), auth par chemin secret dans l'URL, alerte Telegram à chaque session. Claude peut lire le miroir bare + les répliques (/mnt/memory-node/{git,data} en ro) et agir sur le VPS (ssh vps.internal = claude-oversight, sudoers scopé inchangé) sans le NAS. Test blackout complet validé le 12/07/2026. Stack : /opt/memory-node/mcp-vps (git local + Gitea bolbol/mcp-vps). Runbook dédié : common/mcp-vps.md.