Automatizar el informe semanal del SOC con Python
El informe semanal era tres horas de copiar y pegar que salían iguales cada lunes. Al automatizarlo con Python, los problemas de verdad no fueron el código: fueron la paginación, las zonas horarias y qué pasa cuando el script falla en silencio.
- python
- automatizacion
- soc
- reporting
- buenas-practicas
Hay una tarea que aparece en todos los SOC: el informe periódico. Cuántas alertas, de qué tipo, cuántas cerradas, qué tendencia. Se tarda horas, sale casi idéntico cada vez y nadie lo echa de menos cuando desaparece. Es el candidato perfecto para automatizar.
Lo monté en Python. El código fue lo fácil. Lo que costó fue todo lo demás.
Separar las tres fases
El primer intento fue un script que consultaba, calculaba y escribía el documento a la vez. Funcionó una semana y se volvió imposible de tocar. Rehecho en tres partes independientes:
- Extraer. Hablar con la API y guardar la respuesta cruda, sin interpretar nada.
- Normalizar. Pasar esa respuesta a una estructura propia, estable, que no cambie aunque cambie la API.
- Renderizar. Convertir esa estructura en el documento final.
La ventaja aparece a la primera incidencia. Si el informe sale raro, se sabe en qué fase mirar sin releer el script entero. Y si el fabricante cambia un campo, solo se toca la fase de normalizar.
La paginación, que siempre muerde
El error clásico, y lo cometí: pedir los datos, recibir una lista con buena pinta y darla por completa. Casi ninguna API devuelve todo de una vez. Suele haber un tope por página y un cursor para seguir.
Lo peor de este fallo es que no rompe nada. No hay excepción ni traza. Simplemente el informe dice 200 alertas donde hubo 1.400, y el número parece perfectamente plausible. Estuvo mal dos semanas antes de que alguien lo notara.
Desde entonces, cualquier consulta que pueda devolver más de un elemento pasa por una función que agota el cursor, y el resultado se contrasta con el total que declara la propia API. Si no cuadran, el script se detiene.
Zonas horarias
La API responde en UTC. El informe se lee en hora peninsular. Entre una cosa y otra hay una o dos horas según la época del año, y eso desplaza el corte de la semana.
El síntoma es sutil: las alertas del domingo por la noche caen en la semana equivocada. Los totales del mes cuadran, los semanales no, y cuesta ver por qué.
La regla que sigo ahora es simple y no la he vuelto a romper: todo se maneja en UTC y con fechas conscientes de zona horaria hasta el último momento. La conversión a hora local ocurre solo al escribir el texto, nunca en un cálculo.
Que falle en alto, no en silencio
Un script programado que falla sin avisar es peor que no tenerlo, porque la ausencia de informe se interpreta como semana tranquila. Lo que aprendí a cubrir:
- Reintentos con espera creciente ante límites de peticiones, en vez de machacar la API.
- Idempotencia. Ejecutarlo dos veces debe producir el mismo informe, no duplicar nada.
- Un aviso explícito al fallar, con la fase que se rompió. Un traceback en un log que nadie lee no es un aviso.
- Comprobaciones de coherencia: si el total de la semana es cero, casi seguro que el roto es el script y no la realidad.
Qué no automaticé
El análisis. El script reúne los datos, calcula las cifras y deja el documento montado. La lectura de por qué han subido las detecciones de un tipo concreto, o si una caída es buena noticia o un sensor caído, la sigue haciendo una persona.
Automatizar la recogida devuelve las horas que se iban en copiar y pegar. Automatizar la conclusión produce informes que nadie se cree, y con razón.
Ese generador semanal crecio con el tiempo hasta convertirse en algo mas completo: un sistema que tambien enriquece cada CVE contra NVD, CISA KEV y EPSS antes de meterlo en el informe. Lo publique en abierto: el codigo esta en GitHub.