1. Memoria y accesos → 2. Exposición de red → 3. Conflictos y servicios → 4. Limpieza y mantenimiento.
Cambios de SSH y firewall: solo con acceso de recuperación verificado. No apagar bots ni eliminar datos sin acordar el alcance.
Alcance
Auditoría local de solo lectura iniciada a las 13:40 CEST (UTC+02:00). No se detuvieron servicios, borraron archivos, actualizaron paquetes ni cambiaron accesos. Única escritura deliberada: este informe. Se consultaron /proc, systemd, Docker, sockets, reglas de red, metadatos de perfiles y logs. No se extrajeron conversaciones ni credenciales. Las muestras son secuenciales y la carga cambió durante la revisión; no representan un benchmark ni un inventario transaccional.
Dictamen
Estado operativo con riesgo crítico de memoria y exposición de red que requiere revisión inmediata. La CPU y el almacenamiento no son el cuello de botella observado. Ya hay muertes de procesos por OOM, por lo que no es una advertencia hipotética. Prioridad: continuidad y seguridad; limpieza de disco después.
Recursos
- Ubuntu 24.04.4 LTS; kernel activo 6.8.0-136-generic.
- 6 CPU lógicas. Uptime: 42 días. Carga inicial: 0.88 / 0.70 / 0.76.
- vmstat: CPU ociosa 81–90% en los intervalos posteriores a la línea histórica, sin espera de E/S relevante en esa muestra.
- RAM total: 11,960 MiB. MemAvailable inicial: aproximadamente 483 MiB; última lectura: 74 MiB (0.62%). Sin swap.
- Kernel: 6 líneas únicas «Out of memory: Killed process» en 24 horas y 41 en siete días. Entre las víctimas: Chrome, ffmpeg y Hermes/comfy. No confundir líneas auxiliares del OOM con víctimas adicionales.
- Disco raíz: 290 GiB, 133 GiB usados, 157 GiB disponibles, 46% ocupado; inodos al 6%.
- Dos sondas ampliadas terminaron por timeout de 30 s. Esto limita la revisión; por sí solo no demuestra una causa concreta. Se suspendieron las exploraciones amplias al observar 74 MiB disponibles.
Atribución de memoria
Lectura de smaps_rollup, usando PSS para reducir doble conteo de páginas compartidas:
- Hermes: 34 procesos, aproximadamente 5.28 GiB PSS. Incluye gateways, sesiones y dashboard; no son 34 bots distintos.
- Node/Next/MainThread: 38 procesos, aproximadamente 2.39 GiB PSS, incluidos dashboards, MCP y n8n.
- Grupo python: aproximadamente 1,045 MiB PSS; ComfyUI en /root/comfy aporta unos 518 MiB.
- Java/Keycloak: unos 506 MiB PSS.
- Uvicorn: nueve procesos, unos 352 MiB PSS.
- Rodovibes: aproximadamente 318 MiB PSS en esa muestra; no es el único ni el mayor consumidor del sistema.
Las sumas por procesos y por cgroups no deben mezclarse: user@0.service incluye servicios descendientes.
Seguridad y red
Hallazgos de alta prioridad
- UFW inactivo. iptables INPUT ACCEPT; DOCKER-USER vacío. IPv6 INPUT ACCEPT.
- Contenedores publicados en todas las interfaces IPv4/IPv6: PostgreSQL 5432, Redis 6379, Adminer 8082, Keycloak 8180, Prometheus 9090 y MinIO 9000/9001.
- También escuchan ampliamente CUPS 631, servicio Hermes/callcenter 8644 y Node 58741.
- Prueba local de Redis sin credenciales: PING respondió +PONG. Demuestra al menos PING sin autenticación, no prueba permisos sobre datos ni acceso desde Internet.
- HTTP local: Prometheus 9090, Adminer 8082 y CUPS 631 devolvieron 200. Un 200 no acredita acceso administrativo sin autenticación.
- Puertos 8644 y 58741 devolvieron 404 en /. Esto no significa que estén protegidos: no se auditaron todas sus rutas ni su autorización.
- No se comprobó el firewall del proveedor ni se hizo un escaneo desde una máquina externa. La exposición está confirmada a nivel de bindings/reglas locales; la alcanzabilidad externa completa queda pendiente.
SSH
- permitrootlogin yes, passwordauthentication yes, pubkeyauthentication yes, maxauthtries 6.
- Fail2ban no activo.
- En el journal SSH de 24 h: 8,800 registros Failed password, 6,074 Invalid user y cuatro Accepted password. Estas categorías pueden solaparse; no deben sumarse como atacantes o intentos únicos.
- Los cuatro accesos aceptados necesitan validación del propietario contra horarios/IPs. No hay evidencia suficiente aquí para afirmar intrusión o declarar todos legítimos.
- Los archivos .env/auth.json encontrados en las raíces de perfiles revisadas no tenían permisos para grupo/otros. Esto no audita copias, backups ni secretos en otras rutas.
- Numerosos servicios y los gateways bajo el gestor de usuario root ejecutan con privilegios elevados. Los perfiles Hermes no equivalen a aislamiento de sistema operativo.
Recomendación segura
- Verificar una llave SSH funcional, usuario administrativo y consola de recuperación; mantener una segunda sesión abierta antes de cambiar acceso.
- Reducir bindings de servicios internos a loopback o red privada. Revisar dependencias antes de recrear contenedores. Proteger servicios publicados con autenticación, TLS y proxy cuando corresponda.
- Aplicar firewall de host/proveedor preservando SSH y las rutas de producción. No confiar solo en UFW para puertos publicados por Docker; revisar DOCKER-USER y reglas IPv6.
- Tras validar acceso por llave, desactivar login root por contraseña y autenticación por contraseña si el flujo operativo lo permite. Añadir rate limiting/Fail2ban.
- Separar agentes y aplicaciones mediante usuarios dedicados o contenedores y permisos mínimos.
Servicios, Hermes y fallos
- Primera muestra: 49 servicios de sistema y 30 de usuario en ejecución; posteriormente 29 de usuario. El inventario cambia con la actividad.
- Metadatos revisados: 44 raíces con config.yaml; 29 state files con PID existente. Los PID/state files por sí solos no prueban salud ni correspondencia completa de todos los perfiles.
- Estados de adapters declarados en esa muestra: 27 Telegram connected; dos Buzz fatal (atlas-finance y zoran-cyprus-art). No se realizó una conversación real por cada bot.
- agenticvibes: 79 reinicios registrados y conflictos getUpdates con otro consumidor de Telegram. El journal confirma fallos de recuperación, no solo una etiqueta histórica. La ubicación del consumidor competidor no quedó resuelta; podría ser otro proceso/host. No detener consumidores a ciegas.
- hermes-gateway.service: 4,529 reinicios acumulados; el journal muestra intentos previos de iniciar con un gateway ya existente. En la muestra final relevante estaba running desde 08:17:52, Result=success: no afirmar que seguía reiniciándose continuamente. También hay warnings de keepalive MCP Roblox.
- Credenciales Telegram iguales en configuraciones: comfy/comfyauth, company-builder/softvibes-analyzer, beglobal_training/beglobal-member. Son riesgos de doble polling al activar ambos perfiles, no prueba de conflictos activos en todos esos pares. Ninguno explica por sí mismo agenticvibes.
- Dos servicios fallidos desde el arranque del 1 de agosto: cloud-init.service y systemd-networkd-wait-online.service. Investigar la causa antes del reinicio; no equivalen a ausencia actual de conectividad.
- Tres scopes históricos de Chromium fallidos.
- Docker: nueve contenedores activos; buzz-minio-init finalizó con código 0, normal para un inicializador.
- buzz-keycloak: unhealthy, 60,363 fallos consecutivos de healthcheck en la muestra; HTTP local en 8180 devolvió 500. Consumo 509.3 MiB frente a límite 512 MiB. Hay que revisar logs, heap, DB y endpoint de readiness; no atribuir el fallo únicamente a RAM ni solo al healthcheck.
- n8n, su proxy y Postgres de Hermy tienen memory_limit=0 (sin límite explícito). Los contenedores inspeccionados usan json-file sin opciones max-size/max-file explícitas.
Disco y candidatos de depuración
Mediciones du en GiB; pueden variar frente a df por archivos abiertos, hardlinks y actividad concurrente.
- /root/.hermes: aproximadamente 33.26 GiB; profiles 32.45 GiB. NO borrar perfiles, sesiones, skills o bases por tamaño.
- /root/tech-legal-counsel-workspace: 18.81 GiB; video_graph/sources 17.13 GiB y audio 1.49 GiB. Son fuentes/contenido, no caché descartable.
- /root/.cache: 11.68 GiB; Hermit 7.46 GiB, de los cuales pkg 5.84 GiB y cache 1.61 GiB. pkg puede contener toolchains referenciadas: no borrar a mano.
- /root/buzz: 9.33 GiB; target 7.59 GiB. Artefactos de compilación, candidatos solo tras comprobar que ningún servicio usa esos ejecutables y que se pueden reconstruir.
- /root/rag-anything/.venv: 6.69 GiB. Entorno de ejecución, no basura automática.
- /root/.npm: 4.07 GiB; _cacache 2.99 GiB, _npx 1.08 GiB. _npx puede sostener MCP activos.
- /tmp: aproximadamente 4.9 GiB, con builds, entornos y archivos de trabajo. No eliminar globalmente: hay sockets y rutas de procesos activos.
- Journal: 2.3 GiB; /var/log total 2.8 GiB.
- Docker informó 8.295 GB de imágenes y 4.972 GB reclamables. La cifra requiere análisis por imagen/capa; no es autorización para prune -a ni para borrar volúmenes.
Ahorro orientativo, condicionado
Los tamaños observados de npm _cacache, pip, uv y Hermit cache suman aproximadamente 6.46 GiB. No garantizan recuperación total: revisar toolchains/hardlinks/procesos y usar limpieza nativa por gestor. Si se confirma que target de Buzz es prescindible, el conjunto llegaría a unos 14.05 GiB, con coste de recompilación. No sumar automáticamente a Docker, perfiles o corpus multimedia como si todo fuera desechable.
Definir retención del journal (por ejemplo 500 MiB–1 GiB, según auditoría), rotación de logs Docker y exportación/backup de material antiguo. Guardar evidencia de los accesos SSH y fallos antes de rotar logs.
Mantenimiento y recuperación
- /var/run/reboot-required presente: libc y kernels 6.8.0-137/138/139 instalados requieren reinicio; sigue activo 136.
- apt list --upgradable, sin refrescar índices, mostró 24 entradas actualizables. Es una fotografía de caché local, no una comprobación online completa.
- En la revisión de timers solo apareció dpkg-db-backup como respaldo identificable. No demuestra ausencia de backups externos, cron u otra solución. No se verificó restauración ni backup completo de perfiles/DB.
- Antes de reiniciar: respaldo verificable, inventario de procesos manuales, unidades habilitadas, orden de dependencias y consola del proveedor. ComfyUI y un dashboard de Be Global estaban en scopes de sesión, por lo que no hay garantía de arranque autónomo por esa evidencia.
Plan priorizado (propuesto, no ejecutado)
P0 — Estabilidad inmediata
- Evitar temporalmente renders, navegadores y delegaciones simultáneas; escoger con el propietario qué cargas no esenciales pausar.
- Añadir swap de contingencia, por ejemplo 4 GiB iniciales, con persistencia y parámetros revisados. Es amortiguación ante picos, no sustituto de RAM ni de una cola de trabajos.
- Objetivo inicial: recuperar al menos 2 GiB disponibles bajo carga normal y observar OOM/PSI, no solo free.
- Resolver conflictos de polling conservando el consumidor legítimo; revisar especialmente agenticvibes.
P0 — Reducir superficie de ataque
- Validar accesos SSH recientes y vía de recuperación.
- Restringir puertos internos y endurecer SSH sin perder acceso ni romper dependencias Docker.
P1 — Estabilizar servicios
- Depurar Keycloak con un caso reproducible y logs; no aumentar memoria a costa de empeorar el OOM global.
- Revisar MCP innecesarios por perfil: elegir por uso real. Clasificar servicios en 24/7, bajo demanda y desarrollo.
- Usar colas para vídeo/Chrome/builds y límites cgroup medidos. Un MemoryMax demasiado bajo también mata tareas; medir picos antes de aplicarlo.
- Migrar procesos manuales que deban sobrevivir a servicios supervisados, sin duplicarlos.
P2 — Capacidad y limpieza
- Si se necesitan todos los bots, dashboards y generación multimedia simultáneamente, evaluar 24–32 GiB de RAM o separar producción de builds/render/ComfyUI. Es una recomendación de capacidad provisional, no una garantía sin medición de picos.
- Limpiar cachés/builds aprobados, archivar fuentes con respaldo y ajustar retención. No borrar perfiles activos ni bases, ni usar drop_caches como remedio de memoria.
- Programar actualizaciones y reinicio en ventana de mantenimiento, con pruebas de Telegram, web y DB posteriores.
P3 — Prevención
- Alertas de MemAvailable/PSI, OOM, restart loops, adapters desconectados, HTTP 5xx, healthchecks y disco.
- Backups cifrados fuera del VPS con retención y prueba de restauración de SQLite/Postgres/configuración. Copias consistentes, no copiar arbitrariamente un SQLite activo sin WAL.
- Revisión semanal del inventario de bots/puertos/MCP y presupuesto de memoria por servicio.
Siguiente acción mínima
Autorizar una fase de estabilización acotada: swap de contingencia y revisión del conflicto de agenticvibes, preservando todos los bots/productos hasta acordar qué pausar. Tratar cambios de firewall/SSH en un paso separado con acceso de recuperación verificado. No se ejecutó ninguna de estas modificaciones durante la auditoría.