Descripción
Procedimiento operacional para rotar la clave de cifrado de credenciales Fernet en CreaRack Pro, manteniendo la integridad de todos los datos encriptados existentes sin downtime.
Cuándo ejecutar
- Rotación preventiva: Anualmente o cada 6 meses (según política de seguridad).
- Compromiso sospechado: Si existe evidencia de que la clave ha sido expuesta.
- Cambio de gestión: Al transferir la instalación a nuevo responsable de seguridad.
- Actualización de key rotation policy: Si se cambian los requisitos de rotación.
Requisitos
- Acceso SSH/shell a servidor de producción.
- Permisos para ejecutar comandos Django en el contenedor app.
- Variable de entorno
CREDENTIALS_ENCRYPTION_KEYeditable en Dokploy (o.envlocal). CREDENTIALS_LEGACY_KEYSconfigurable (lista colon-separated).- BD PostgreSQL accesible desde el contenedor (standard).
- Backup reciente de BD (ejecutar antes de este procedimiento como precaución).
Pasos
Fase 1: Preparación
-
Generar nueva clave Fernet:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" # Output: gAAAAABnFhZZA6-K3... (32 bytes, base64)Guardarlo en un lugar temporal seguro (p.ej. KeePass, vault).
-
Crear backup de BD (como precaución):
docker exec crearacksql pg_dump -U crearacksql > backup_pre_rotation_$(date +%Y%m%d_%H%M%S).sql -
Validar acceso a settings:
- Si usa Dokploy: acceder al dashboard, ir a
Environment. - Si usa
.envlocal: verificar que el archivo sea editable.
- Si usa Dokploy: acceder al dashboard, ir a
Fase 2: Actualizar claves en configuración
-
Mover clave actual a legacy:
- Obtener el valor actual de
CREDENTIALS_ENCRYPTION_KEY. - Añadirlo a
CREDENTIALS_LEGACY_KEYS(formato:clave1:clave2:clave3).
Ejemplo:
CREDENTIALS_ENCRYPTION_KEY = gAAAAABnFhZZA6-K3... (VIEJA, será legacy) CREDENTIALS_LEGACY_KEYS = "" (antes vacío) # DESPUÉS: CREDENTIALS_ENCRYPTION_KEY = gAAAAABnFhZZA6-K3... (NUEVA, generada en paso 1) CREDENTIALS_LEGACY_KEYS = "gAAAAABnFhZZA6-K3..." (VIEJA, para descifrado de datos históricos) - Obtener el valor actual de
-
Desplegar cambios (via Dokploy o manual):
- Si Dokploy: guardar cambios, aguardar redeploy automático (típicamente <5 min).
- Si manual: actualizar
.env, reiniciar contenedordocker-compose restart app.
Validar deployment:
# Esperar a que el contenedor esté ready docker logs crearacksql_app | tail -20 # Buscar "Running on ..."
Fase 3: Re-cifrar datos existentes
-
Ejecutar command en modo —dry-run (validación):
docker exec crearacksql python manage.py reencrypt_credentials --dry-runOutput esperado:
[reencrypt_credentials] rows scanned=1245 reencrypted=892 failed=0 [reencrypt_credentials] DeviceProfile: 234 rows scanned, 189 reencrypted [reencrypt_credentials] MonitoringTarget: 567 rows scanned, 403 reencrypted [reencrypt_credentials] StoredCredential: 234 rows scanned, 189 reencrypted ...Validar que:
failed=0(ningún error).reencrypted > 0(hay datos que fueron re-cifrados, lo que esperamos).- No hay excepciones en los logs.
-
Ejecutar en producción (sin
--dry-run):docker exec crearacksql python manage.py reencrypt_credentialsSalida similar a dry-run, pero esta vez actualiza la BD.
Tiempo estimado:
- Base de datos típica (1k-10k credenciales): 10-60 segundos.
- Si toma más: es normal (DB I/O), monitorear en paralelo con
docker stats.
-
Validar en logs:
docker logs crearacksql_app | grep "reencrypt_credentials" | tail -20Buscar mensaje final:
[reencrypt_credentials] ✓ completed successfully.
Fase 4: Verificación post-rotación
-
Verificar polling SNMP (validar que credenciales siguen siendo válidas):
- Acceder al dashboard.
- Navegar a Network → Device Profiles.
- Seleccionar un profile con SNMP v2c/v3.
- Ejecutar “Test SNMP” o “Refresh Interfaces”.
- Debe responder sin error (las credenciales descifran correctamente).
-
Verificar monitoreo (targets siguen recolectando métricas):
- Ir a Monitoring → Targets.
- Seleccionar un target activo.
- Verificar que last polling time es reciente (< 2 min).
- Métricas deben estar actualizándose.
-
Revisar logs de aplicación:
docker logs crearacksql_app | grep -i "decrypt\|encrypt\|credential" | tail -50No deben haber errores como:
Invalid tokenDecryption failedKey not found
Fase 5: Limpieza (opcional, después de días/semanas)
- Opcionalmente, limpiar legacy keys (después de verificar estabilidad por ≥1 semana):
- Si todos los datos han sido re-cifrados con la nueva clave,
CREDENTIALS_LEGACY_KEYSpuede ser vaciado. - Pero: es recomendable mantenerlo por ≥3 meses por si hay rollback de BD (disaster recovery).
CREDENTIALS_LEGACY_KEYS = "" (limpiar)- Redeploy (paso 5).
- Si todos los datos han sido re-cifrados con la nueva clave,
Rollback
Si algo falla o necesita revertir:
Antes del paso 7 (aún no re-cifrado)
- Revertir
CREDENTIALS_ENCRYPTION_KEYyCREDENTIALS_LEGACY_KEYSa valores anteriores. - Redeploy.
- Todo sigue funcionando (datos aún están cifrados con clave original).
Después del paso 7 (ya re-cifrado)
- No hay rollback fácil: los datos ya están con nueva clave.
- Opción: restaurar BD desde backup del paso 2.
Luego revertir claves y redeploy.docker exec crearacksql psql -U crearacksql < backup_pre_rotation_YYYYMMDD_HHMMSS.sql
Troubleshooting
| Síntoma | Causa | Solución |
|---|---|---|
reencrypt_credentials devuelve failed > 0 | Token Fernet corrupto (raro) o clave no en legacy chain | Verificar CREDENTIALS_LEGACY_KEYS incluye todas las claves históricas. Ver logs detallados. |
| SNMP test falla post-rotación | Credenciales aún en plaintext (migración incompleta) o token no descifra | Revisar que decrypt_or_passthrough está siendo usado en pollers. Ejecutar command nuevamente. |
| BD no contesta tras rotación | Timeout DB | Aumentar timeout en --timeout del command (si aplica). Verificar conectividad SSH/DB. |
| Dokploy no redeploy automático | Settings cambios no detectados | Forzar redeploy manual en dashboard o CLI. |
Automatización (opcional)
Para instalaciones con rotación frecuente, considerar cron job:
# /etc/cron.d/crearacksql_credential_rotation (trimestral, p.ej. primer domingo del trimestre)
0 2 1 */3 0 root docker exec crearacksql python manage.py reencrypt_credentials >> /var/log/crearacksql/credential_rotation.log 2>&1
Véase también
- [[entity—core—service—credential-manager]]
- [[entity—network—model—device-profile]]
- [[entity—monitoring—model—monitoring-target]]
- [[feature—security—t1-cifrado-snmp-reposo]]
- [[concept—security—credential-encryption]]