nas-runbooks/common/mcp-nas-reference.md

3.6 KiB

mcp-nas — Référence opérationnelle (consolidée)

Date : 2026-07-09 (fusionne MCP-NAS-SCRIPTING.md 2026-06-23 + mcp-nas-run-command-v2.md 2026-07-04, + contraintes post-audit 2026-07-08) Tags : infra, mcp-nas, scripting, securite

Environnement du container (vérifié 09/07/2026, image post-audit)

Propriété Valeur
Shell /bin/bash, user root uid=0, cap_drop: [ALL] + no-new-privileges
Python 3.11 — requests, sqlite3, json, urllib, subprocess
git ABSENT (retiré au rebuild post-audit) → API HTTP Gitea obligatoire
docker CLI / docker.sock ABSENTS (socket retiré P0 audit 08/07) → API Portainer
/mnt/docker = /volume1/docker, RW
Réseau host via 172.17.0.1 ou alias nas.internal (extra_hosts). 192.168.100.33 inaccessible

run_command v2 (P0 du 04/07, commit 30560984fa)

La commande est écrite dans un script par Python (zéro parsing shell) puis sourcée dans tmux :

  • Heredocs natifs (<<'EOF', quotes, $VAR, backticks) ; testé 5 250 chars en un appel.
  • Busy-check : pane occupé → refus propre (options : capture_pane, send_keys, reset_session).
  • Timeout intelligent : Ctrl-C + sonde ; session préservée si le shell répond.
  • reset_session : reprise d'une session bloquée SANS destruction (vim : send_keys ':q!' d'abord).
  • Cleanup au boot : sessions tmux orphelines + /tmp/mcp_* purgés.
  • Denylist ancrée (P1, commit 7fb13c5) : patterns ancrés en début de segment, heredocs exclus. Défense en profondeur, PAS une frontière de sécurité.
  • Interdits toujours actifs : reboot, mkfs, dd of=/dev/, rm -rf racines critiques, docker rm -f, syno

Ne plus utiliser : workaround base64 2 appels, découpage printf-append, limite 350 chars — tout cela date de la v1.

Contraintes post-audit sécurité (08/07/2026) — vérifiées le 09/07

  1. cap_drop: [ALL] → pas de CAP_DAC_OVERRIDE : les dossiers 0700 appartenant à uid 1026 (ex. hermes-*/data/) sont illisibles même en root. C'est voulu. Lecture des data/ Hermes → passer par un autre canal (Mac, ou décision Nabil).
  2. ~/.ssh du container vidé au rebuild : plus de clé pour ssh Best0f@172.17.0.1:22222. SSH host depuis mcp-nas = indisponible tant que la clé n'est pas re-provisionnée (décision Nabil — l'audit recommandait justement de sortir les clés).
  3. docker.sock retiré → gestion containers via API Portainer (http://nas.internal:9000, POST /api/auth → jwt, endpoint_id=2 ; l'ID container change après recreate, toujours le re-résoudre).
  4. Gitea : API HTTP avec GITEA_DEPLOY_TOKEN (repo-scopé, dans hermes-platform/.env) — jamais le mot de passe bolbol dans une URL (fuite audit.log + ps). Lire le token dans une variable depuis le fichier, pas en clair dans la commande.
  5. Rebuild du container : depuis le Mac (ssh -p 22222 Best0f@192.168.100.33, cd /volume1/docker/linux-mcp-nas && sudo docker compose build && up -d --force-recreate), jamais depuis mcp-nas lui-même.

Services internes depuis mcp-nas

nas.internal (= 172.17.0.1) : Gitea :3232, Portainer :9000, NyoraNotes :8787, nyora-doc-api :3050, Bifrost :3085 (LAN) / http://bifrost:8080 (réseau n8n), context-hub :3093.

Bonnes pratiques

  • Scripts Python : heredoc cat <<'EOF' > /tmp/s.py … EOF puis python3 /tmp/s.py.
  • Session par défaut claude fiable ; reset_session avant de créer une session neuve.
  • Secrets : toujours via variable lue depuis .env (export GT=$(grep … | cut -d= -f2)), jamais inline — audit.log journalise chaque commande.