Lo que los audit logs de Kubernetes no muestran
Los puntos ciegos de los audit logs de Kubernetes: actividad en contenedores, acceso a kubelet y etcd, huecos de política, campos falsificables y qué los cubre.
TL;DR. El audit log de Kubernetes ve las solicitudes al API server y nada más. No ve lo que ocurre dentro de un contenedor o en un nodo, las solicitudes hechas directamente al kubelet o a etcd, los cambios de IAM cloud ni el tráfico de red. Lo que ve depende de tu política de auditoría y de la del proveedor gestionado; algunos campos (IP de origen, user agent) están influidos por el cliente; y las reglas basadas en patrones no detectan a atacantes que se comportan como tus administradores. Combínalo con detección de runtime, logs de nodos y contenedores, logs de auditoría cloud y logs de flujo.
Todos los artículos de esta serie defienden que el audit log es el centro de una investigación en Kubernetes. Este explica dónde termina, para que un resultado «limpio» se lea por lo que es.
Punto ciego 1: dentro de los contenedores y en los nodos
El API server autoriza y registra la solicitud que abre una sesión exec, incluido su comando inicial, y después retransmite bytes que no registra. Todo lo posterior es invisible:
- los comandos tecleados en una shell interactiva;
- los procesos que lanza la aplicación tras una RCE (una reverse shell, un binario descargado);
- los cambios de archivos dentro del contenedor;
- todo lo que se haga en el nodo tras un escape de contenedor: claves SSH nuevas, entradas de cron, reutilización de credenciales del kubelet, contenedores arrancados directamente a través de un socket del runtime.
El audit log muestra la preparación (un contenedor privilegiado, un hostPath de /, un exec con chroot /host), no la ejecución. Para lo demás necesitas evidencia de runtime: Falco o un EDR en los nodos, los logs propios de los nodos (journald, logs de autenticación), los logs de contenedores y un snapshot del disco de los nodos afectados.
El analizador acepta alertas de Falco en JSON junto a los audit logs y pone ambas cosas en una misma línea de tiempo; las alertas de prioridad Error o superior se convierten en hallazgos.
Punto ciego 2: vías que esquivan el API server
| Vía | Por qué no está en el audit log |
|---|---|
| API del kubelet en el puerto 10250, llamada directamente | Responde el propio kubelet; el API server no interviene |
nodes/proxy a través del API server | Se registra como nodes/proxy, no como el exec que realiza (consulta nodes/proxy) |
| Acceso directo a etcd | Lee y escribe el estado del clúster por debajo del API server |
| Socket del runtime desde un pod que monta el host | Arranca contenedores que Kubernetes no conoce |
| Manifiestos de pods estáticos escritos en un nodo | Los ejecuta el kubelet; solo aparece el pod espejo, creado por la identidad del nodo |
| IAM cloud (access entries de EKS, roles de IAM de GKE, Azure RBAC) | El acceso se concede en el plano de control cloud y lo registra el proveedor |
La parte cloud tiene su propio rastro de auditoría: CloudTrail para EKS, Cloud Audit Logs para GKE y el registro de actividad de Azure para AKS. Los sitios hermanos AWS Forensics, GCP Forensics y Azure Forensics los cubren.
Punto ciego 3: lo que la política no guardó
Lo que puedes detectar está limitado por lo que se registró:
- El nivel
Metadataelimina los cuerpos de las solicitudes. La creación de un DaemonSet es visible; si era privilegiado, qué imagen ejecutaba o qué rol concedía un binding, no. Varias detecciones simplemente no pueden saltar. La guía de la política de auditoría muestra qué registrar. - Las políticas gestionadas toman sus propias decisiones: la política de EKS publicada en la guía de buenas prácticas de EKS no registra los Events; GKE envía las lecturas a los logs de Data Access, desactivados por defecto; la categoría
kube-audit-adminde AKS descartagetylist. Consulta la guía de EKS, GKE y AKS. - Entrega y tamaño. EKS describe la entrega de los logs del plano de control como «best effort», y CloudWatch Logs limita las entradas a 1 MB, así que los objetos muy grandes pueden quedar truncados.
- Retención. Los logs que caducaron antes de empezar la investigación se han perdido. El acceso inicial suele ser anterior a la detección.
- Cobertura. En clústeres autogestionados, cada instancia del API server registra las solicitudes que atendió; olvidar el archivo de un nodo del plano de control es perder parte de la historia.
El analizador informa de lo que leyó (archivos, rango temporal, fuentes, registros omitidos y truncados) precisamente para que estos huecos se vean.
Punto ciego 4: campos en los que no se puede confiar del todo
sourceIPs: la referencia de eventos de auditoría advierte que todas las IPs salvo la última puede fijarlas el cliente medianteX-Forwarded-For. Detrás de balanceadores o endpoints privados, la última IP puede ser una dirección de infraestructura.userAgent: lo aporta el cliente. Un atacante cuidadoso envía el mismo agente que el workload cuyo token robó.- Identidad: el log nombra la credencial, no a la persona. Un token robado y su workload legítimo se ven idénticos salvo por el contexto (origen, horario, comportamiento).
- Impersonation: lee
usereimpersonatedUserjuntos; informar solo de uno atribuye mal las acciones.
Punto ciego 5: atacantes que parecen normales
Las reglas de detección buscan patrones. Marcan una cuenta de servicio que ejecuta kubectl exec, un binding a cluster-admin, una imagen de minero. No marcan:
- a un atacante que usa las credenciales robadas de un admin para hacer lo que ese admin hace normalmente;
- una imagen maliciosa con un nombre corriente, desde tu registry habitual;
- datos leídos despacio, un secret por hora, por debajo de cualquier umbral de ráfaga;
- una identidad con un nombre que imita a un componente del sistema. El analizador excluye las identidades de controladores por prefijo, algo necesario para evitar miles de falsos positivos, pero que implica que una cuenta de servicio con un nombre que encaje con un prefijo excluido en
kube-systempodría pasar desapercibida. Revisa quién puede crear cuentas de servicio ahí.
Las líneas base ayudan: primer exec de una identidad en 30 días, primera solicitud desde una red nueva, un workload creado fuera del pipeline de despliegue. Esas comparaciones necesitan un historial que el analizador no guarda entre sesiones; tu SIEM, sí.
Leer un veredicto limpio
«Sin señales de compromiso» significa que ninguna regla coincidió en los datos aportados. Antes de aceptarlo, comprueba:
- ¿Cubre el rango temporal el periodo que preocupa, con margen?
- ¿Se incluyeron todas las fuentes del plano de control y se omitió algún archivo?
- ¿Registra la política los cuerpos de las escrituras de workloads y RBAC?
- En GKE y AKS, ¿se registraban las lecturas?
- ¿Hay evidencia independiente (alertas de runtime, factura cloud, comportamiento de los nodos) que contradiga el resultado?
Si las dudas persisten, recurre a alguien con experiencia en respuesta a incidentes y recoge evidencia de runtime antes de que se reciclen los nodos.
El mapa de evidencias
| Pregunta | Fuente principal |
|---|---|
| Quién cambió qué en el clúster y desde dónde | Audit log de Kubernetes |
| Qué se ejecutó dentro de un contenedor o en un nodo | Falco / EDR, logs de nodos, disco y memoria |
| Qué hizo la aplicación | Logs de contenedores, logs de aplicación |
| Quién obtuvo acceso cloud al clúster | CloudTrail / Cloud Audit Logs / registro de actividad de Azure |
| Adónde fueron los datos | Logs de flujo de VPC / NSG, logs del proxy de salida |
| Qué se suponía que debía estar desplegado | Historial de CI y GitOps, logs del registry |
FAQ
¿Registran los audit logs de Kubernetes los comandos ejecutados dentro de un contenedor?
Solo el comando inicial de un kubectl exec, que forma parte de la URI de la solicitud. Todo lo que se teclea después en la sesión, y cualquier proceso que lance la propia aplicación, es invisible para el API server y requiere herramientas de runtime.
Si el analizador no muestra señales de compromiso, ¿está limpio el clúster?
No necesariamente. Significa que ninguna regla coincidió en los logs aportados. Rangos temporales ausentes, una política de auditoría solo en Metadata, actividad en nodos o dentro de contenedores y atacantes que imitan el comportamiento normal pueden no dejar ninguna coincidencia.
¿Con qué conviene combinar los audit logs?
Detección de runtime en los nodos (Falco o un EDR), logs de nodos y contenedores, los logs de auditoría del plano de control del proveedor cloud, logs de flujo de red y el historial de despliegues de la CI o de GitOps.