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

94 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
```bash
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---yesmine``nas` (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`.**