Volver a la wiki

vmauth con usuario y contraseña delante de VictoriaMetrics y Alertmanager en NetBird (mega-auditoría B-45)

Contexto

scripts/netbird-proxies.sh publica en la VPN NetBird de cada servidor los puertos 8428 (VictoriaMetrics) y 9093 (Alertmanager). Hasta el 25-09-2026 llegaban directos a esos servicios, que no piden usuario ni contraseña: cualquier equipo conectado a la VPN — incluido el runner del CI en OPS — podía borrar series de métricas (/api/v1/admin/tsdb/delete_series) o silenciar alertas sin credencial alguna. La mega-auditoría de septiembre de 2026 lo marcó como hallazgo B-45.

Opciones consideradas

  1. Restringir por grupo/IP en NetBird: descartada porque el plan Free no da control fino por servicio, y el runner del CI en OPS necesita seguir leyendo métricas (alertas-ciegas-check.sh), así que cerrar OPS entero no era viable.
  2. Autenticación nativa de cada servicio: descartada porque Alertmanager no trae auth básica de fábrica, y VictoriaMetrics no separa un usuario de solo lectura de uno de escritura sin un proxy delante.
  3. (elegida) Interponer vmauth, el proxy oficial de VictoriaMetrics, delante de los dos servicios con dos usuarios: uno de equipo (acceso completo) y uno de solo lectura restringido a /api/v1/query.

Decisión elegida

Dos contenedores vmauth (victoriametrics/vmauth:v1.106.1) en compose.prod.yml, cada uno en su propio puerto de escucha (18428/19093, distinto del de VictoriaMetrics/Alertmanager) para que un proxy NetBird con la IP vieja de un contenedor no pueda saltarse la contraseña por error. scripts/netbird-proxies.sh ahora enruta 8428→vmauth:18428 y 9093→vmauth-am:19093, y cierra el proxy viejo de cada puerto ANTES de buscar el contenedor nuevo: si vmauth no arranca, el puerto queda cerrado, nunca abierto sin contraseña. observability/vmauth/start.sh falla cerrado — si el fichero de contraseña falta, está vacío o no es alfanumérico de ≥24 caracteres, vmauth no arranca. El tráfico interno (web, worker, vmalert) sigue yendo directo a victoriametrics:8428 y alertmanager:9093, sin pasar por vmauth.

Consecuencias

Pros: cierra el acceso de escritura/borrado a cualquier peer de la VPN; el usuario de solo lectura que queda en OPS (el único servidor con un proceso automatizado hablando con estos puertos) no puede borrar series ni silenciar alertas aunque se vea comprometido; fallo cerrado ante contraseña ausente o corrupta.

Contras: las dos sondas de servicios-check en OPS y el cron @reboot de PROD/STAGE tuvieron que cambiar de endpoint (/ → /backend-health, el único que llega al servicio real; vmauth contesta sus propios /health//-/healthy sin más) para no quedar ciegas. Un despliegue hecho antes de crear los ficheros de contraseña deja el contenedor en bucle de reinicio y exige borrar + recrear desde Dokploy (Docker monta una carpeta vacía donde se esperaba un fichero).

Hallazgo adicional (mismo día, commit f90cb92)

Revisando qué otros caminos llegaban a estos puertos aparecieron dos proxies socat supervivientes de la época de Tailscale (tailnet-vm, tailnet-pg, unidades systemd /usr/local/bin/tailnet-proxy-{vm,pg}.sh, Restart=on-failure) que se saltaban vmauth por completo: en STAGE, tailnet-vm se reenganchaba al :8428 apuntando DIRECTO a VictoriaMetrics; en PROD estaba en bucle esperando un puerto que ya no exponía así. Se pararon y deshabilitaron (systemctl disable --now) en los dos servidores — ficheros de unidad conservados, no reactivar. Los sustituye netbird-proxies.sh. Documentado en public/supercontext/AUTOMATISMOS.md.

Status: accepted — desplegado en PROD y STAGE (v1.164.0, PR #614, commit 1f0e1c20). Procedimiento completo para crear/rotar contraseñas, recuperar un arranque sin fichero y volver atrás: context/INFRA.md, sección vmauth.

Véase también

Subir