Un script de hardening dejó un balanceador de carga caído y reportó éxito
Un desarrollador relata cómo su propio script de endurecimiento para ALBs de AWS provocó una caída total al aplicar un orden incorrecto de operaciones, con salida 0.
Un ingeniero de DevOps ha compartido en Reddit un incidente que ilustra un fallo clásico en automatización: un script de hardening que terminó tumbando un balanceador de carga de AWS y, para más inri, salió con código 0. El autor admite que el problema no era de lógica de reglas, sino de orden en las operaciones.
El script estaba diseñado para reforzar ALBs existentes aplicando una postura de denegación por defecto: forzar HTTPS, eliminar cabeceras inválidas, mitigar desync y hacer que la acción por defecto del listener HTTPS sea un 403, permitiendo solo el reenvío a reglas de host-header explícitas.
Durante las pruebas contra un ALB que solo tenía un listener HTTP en el puerto 80, el script creó un nuevo listener HTTPS con una respuesta 403 por defecto. Inmediatamente después, intentó descubrir el target group existente consultando la configuración del propio listener HTTPS que acababa de crear. Como en ese momento no había ningún forward configurado (solo el fixed-response 403), el resultado fue vacío. La rama que debía añadir la regla de reenvío por host-header se saltó, y el script continuó hasta dejar fijado el 403 como acción por defecto permanente. El balanceador quedó devolviendo 403 para cualquier petición, incluso con el Host correcto, porque no existía ninguna regla que permitiera reenviar.
El autor identifica tres fallos que generalizar:
- Descubrir antes de mutar: el script leía el estado después de haberlo modificado. Cualquier operación de descubrimiento debe hacerse antes de la primera escritura.
- Una advertencia tras el daño no es una salvaguarda: el mensaje aconsejando añadir la regla manualmente apareció después de que el 403 ya fuese permanente. Solo narraba el desastre.
- El exit code 0 fue lo más peligroso: en un pipeline, eso cuenta como paso verde y todo lo demás continúa. La primera señal real habría sido la caída de producción.
La corrección del script incluye tres cambios: leer el target group del listener HTTP como respaldo y capturarlo antes de tocar nada; crear la regla de permiso antes de cambiar el default a 403; y abortar por completo si no se encuentra ningún target group, en lugar de dejar el tráfico en un agujero negro. Además, recomienda añadir un modo dry-run, algo que debería haber existido desde el principio.
Lo que más molesta al autor es que ninguna herramienta estática habría detectado el problema: ShellCheck limpio, bash válido, todas las llamadas a la API de AWS correctas. El ALB quedó exactamente en el estado que el código describía, y ese estado era una caída. Para encontrar el fallo tuvo que ejecutar el script contra una infraestructura con una forma que no había previsto y luego verificar el resultado desde fuera, como usuario, en lugar de conformarse con el código de salida.
El autor pregunta cómo abordar el testeo de este tipo de situaciones. Sus ideas pasan por reproducir entornos similares a producción en un sandbox y probar con curl desde fuera, pero reconoce que no escala a todas las permutaciones. Ha publicado la parte de auditoría de su código como herramienta de solo lectura, aunque no entra en detalles aquí.