Contexto
Hallazgo de auditoría (Auditoría Suprema Etapa 3, network A9/sa1 + M3/sa2):
ScrapliManager conectaba con auth_strict_key=False, deshabilitando la verificación de identidad del host SSH. Esto permite un ataque de hombre en el medio (MITM): un atacante en la red podría suplantar un equipo y capturar credenciales.
Opciones evaluadas:
- TOFU rígido: registra clave en primera conexión, bloquea cualquier cambio (seguro, pero puede bloquear nuevos equipos)
- TOFU con degradación: registra clave, la exige después, pero degrada a no-check si es primera conexión y no se puede captar la clave (seguridad + usabilidad)
- Sin verificación (estado actual): vulnerabilidad presente
Decisión
TOFU con degradación, implementado por organización sin modelo Django.
Justificación
- Seguridad: la mayoría de conexiones son a equipos ya registrados → MITM protection activo
- Usabilidad: primera conexión a nuevo equipo nunca falla por falta de clave (mejor UX que bloqueo riguroso)
- Escalabilidad: sin modelo DB, sin migración → más rápido de desplegar, menos carga
- Multi-tenancy: almacén por
org_id→ dos tenants con RFC1918 iguales no interfieren
Trade-offs aceptados
-
Riesgo residual en primera conexión: un MITM activo al conectar por primera vez a un equipo nuevo podría capturar la clave. Mitigado por:
- Arquitectura: la mayoría de deployments aislados por firewall (no acceso desde internet)
- Operativo: el equipo debe estar reachable la primera vez; atacante debe estar en el camino exacto
- Futuro: se puede tomar la clave del dispositivo vía API/SNMP anterior, o validar fuera de banda
-
Sin garantía de no regresión en conectividad: si scrapli/asyncssh rompen el interface, el fallback es
auth_strict_key=False. Mitigado por tests.
Implementación
- Archivo:
network/services/ssh_host_keys.py - Almacén:
MEDIA_ROOT/ssh_known_hosts/<org_id>/known_hosts(filesystem, sin DB) - Función pública:
scrapli_strict_args(org_id, host, port)→ dict de kwargs paraScrapliManager - Propagación:
org_iddesde request (scripts.py) o device (backups.py) - Tests: 6 tests en
test_network_ssh_tofu.py
Precedente
Diseño refleja el TOFU del Agent (terminal/agent/network/host_keys.py, s124). La diferencia: Agent = por máquina local; servidor = por tenant (multi-org).
Revisión futura
- Validación de clave fuera de banda (por API del dispositivo, SNMP, etc.)
- Rotación de claves + notificación de cambios sospechosos
- Dashboard de “claves por dispositivo por org”
Véase también
- [[feature—security—ssh-tofu-server-side]]
- [[entity—network—service—ssh-host-keys]]
- [[entity—network—service—scrapli-manager]]
- [[concept—network—ssh-host-verification]]
- [[concept—security—mitm-prevention]]