Seguridad en Kubernetes: los errores que más se explotan y cómo auditar un clúster
Por Kike Gandia · Co-Fundador y CEO, OSCP
Kubernetes no es inseguro, pero sus valores por defecto priorizan que todo funcione sobre que todo esté aislado: los pods se hablan entre sí sin restricciones, los secretos se guardan sin cifrar en etcd y el registro de auditoría no se activa solo. Si a eso se suman permisos RBAC amplios y pods con privilegios, una vulnerabilidad en una sola aplicación puede acabar en el control del clúster y, en un servicio gestionado, de parte de la cuenta cloud. En esta guía repasamos los errores que más se explotan, qué cambia en EKS, AKS y GKE, y cómo se audita un clúster tanto contra una línea base como desde el punto de vista de un atacante.
Por qué un clúster de Kubernetes es un objetivo distinto
Un clúster de Kubernetes es, ante todo, una API. Quien controla el API server controla todas las cargas de trabajo, todos los secretos y, a menudo, las credenciales cloud con las que trabajan los nodos. Por eso el objetivo de un atacante no suele ser la aplicación en sí, sino usarla como puerta de entrada al plano de control.
Hay tres puntos de partida habituales:
- Desde fuera: un API server, un panel de administración o el puerto del kubelet expuestos a internet con una autenticación débil o inexistente.
- Desde un contenedor comprometido: una vulnerabilidad de ejecución remota de código en una aplicación da una shell dentro de un pod. Desde ahí se prueba el token de la cuenta de servicio, la red interna, el servicio de metadatos del cloud y la posibilidad de escapar al nodo.
- Desde la cadena de despliegue: un kubeconfig en el portátil de un desarrollador o las credenciales del pipeline de CI/CD, que suelen tener permisos para desplegar cualquier cosa.
El caso que lo popularizó fue el de Tesla en 2018: según el equipo de investigación de RedLock, los atacantes entraron en una consola de Kubernetes que no tenía contraseña, encontraron en un pod credenciales de AWS con acceso a un bucket de S3 y usaron el clúster para minar criptomoneda.
Durante años la documentación oficial resumía la seguridad en cuatro capas, las «4C»: cloud, clúster, contenedor y código. La versión en inglés la organiza hoy por fases del ciclo de vida (desarrollo, distribución, despliegue y ejecución), pero la idea de fondo sigue valiendo: cada capa depende de la de debajo, y un clúster bien bastionado sobre una cuenta cloud débil no está seguro.
Los errores que más se explotan, de un vistazo
| Error | Por qué es grave | Cómo se detecta |
|---|---|---|
| RBAC excesivo | Cuentas de servicio o usuarios con permisos que equivalen a administrador del clúster | Revisión de roles y enlaces, análisis de quién puede hacer qué |
| Pods privilegiados o con acceso al host | Un contenedor comprometido escapa al nodo y, desde él, a otros pods | Pod Security Admission, políticas de admisión, CIS Benchmark |
| Red sin NetworkPolicies | Un pod comprometido alcanza bases de datos, APIs internas y el plano de control | Revisión de políticas y prueba de alcance desde un pod |
| Secretos sin cifrar o mal ubicados | Quien lee etcd, una copia de seguridad o un repositorio obtiene credenciales | Configuración del API server, revisión de manifiestos y repositorios |
| Acceso de los pods al rol cloud del nodo | Una shell en un pod se convierte en credenciales de la cuenta cloud | Prueba desde un pod contra el servicio de metadatos |
| Componentes expuestos | API server, paneles o kubelet accesibles sin la autenticación adecuada | Escaneo externo y revisión de la configuración |
| Componentes vulnerables o retirados | Un controlador de ingress o una imagen con fallos críticos da acceso al clúster | Inventario de versiones y escaneo de imágenes |
| Sin registro de auditoría | No hay forma de saber qué hizo un atacante ni de detectarlo a tiempo | Configuración del API server o del servicio gestionado |
Los siguientes apartados explican cada bloque y qué comprobar.
RBAC: los permisos que equivalen a ser administrador
El control de acceso basado en roles (RBAC) de Kubernetes es potente, pero algunos permisos que parecen acotados permiten escalar. La propia guía de buenas prácticas de RBAC del proyecto los enumera:
| Permiso | Por qué es peligroso |
|---|---|
| get, list o watch sobre secrets | Listar o vigilar secretos también revela su contenido, no solo sus nombres |
| Crear pods o recursos que los gestionan (deployments, jobs…) | Da acceso implícito a los secretos, ConfigMaps y cuentas de servicio del namespace; con un pod privilegiado se llega al nodo |
| Crear volúmenes persistentes | Permite montar rutas del nodo (hostPath) y leer su sistema de ficheros |
| get sobre nodes/proxy | No es de solo lectura: permite ejecutar comandos en los pods del nodo saltándose la auditoría y el control de admisión |
| Verbos escalate y bind | Permiten crear o enlazar roles con permisos que el usuario no tiene |
| Verbo impersonate | Permite actuar como otro usuario o cuenta de servicio |
| Aprobar solicitudes de certificado (CSR) | Permite emitir certificados de cliente con nombres arbitrarios, incluidos los de componentes del sistema |
| Crear tokens de cuentas de servicio | Permite obtener tokens de cuentas de servicio existentes, con sus permisos |
| Gestionar webhooks de admisión | Quien los controla puede leer y modificar los objetos que se crean en el clúster |
| Modificar namespaces | Cambiar sus etiquetas puede desactivar el nivel de Pod Security o alterar a qué aplican las políticas de red |
A eso se suman los errores de configuración más repetidos en las revisiones:
- cluster-admin enlazado a la cuenta de servicio de una aplicación o al usuario del pipeline de despliegue «para que funcione».
- Comodines en verbos o recursos (*), que conceden también lo que se añada en el futuro.
- Token de la cuenta de servicio montado en todos los pods, aunque la aplicación nunca llame al API server. Es el primer recurso que prueba quien obtiene una shell en un pod.
- Roles heredados de herramientas —operadores, paneles, agentes de monitorización— instalados con permisos amplios y nunca revisados.
La comprobación básica es preguntar al propio clúster qué puede hacer cada identidad, empezando por las cuentas de servicio de las aplicaciones expuestas a internet.
Seguridad de los pods: privilegios, Pod Security Standards y admisión
Un contenedor no es una máquina virtual: comparte el kernel con el nodo. Algunas opciones de configuración rompen el aislamiento que queda:
- privileged: true: el contenedor tiene prácticamente los mismos permisos que un proceso root del nodo.
- hostPath: monta directorios del nodo dentro del contenedor; según la ruta, permite leer credenciales del kubelet o escribir en el sistema.
- hostNetwork, hostPID o hostIPC: el contenedor ve la red, los procesos o la memoria compartida del nodo.
- Capacidades de Linux añadidas, como SYS_ADMIN, y la posibilidad de escalar privilegios dentro del contenedor.
- Ejecución como root sin necesidad.
Para impedirlo de forma sistemática, Kubernetes define tres niveles, los Pod Security Standards:
| Nivel | Qué permite | Cuándo usarlo |
|---|---|---|
| Privileged | Sin restricciones | Solo componentes de sistema que lo necesitan, como algunos agentes de red o almacenamiento |
| Baseline | Restricciones mínimas que impiden las escaladas de privilegios conocidas | Mínimo razonable para cualquier aplicación |
| Restricted | Restricciones fuertes, alineadas con las buenas prácticas actuales de bastionado de pods | Objetivo para las aplicaciones propias |
Se aplican con Pod Security Admission, estable desde Kubernetes 1.25, mediante etiquetas en cada namespace con tres modos: enforce (rechaza), audit (registra) y warn (avisa). Su predecesora, PodSecurityPolicy, se eliminó en esa misma versión: un clúster que la usaba y se actualizó sin sustituirla puede haber perdido sus controles sin que nadie lo notara. Para reglas más finas —registros de imágenes permitidos, etiquetas obligatorias, límites de recursos— se usan motores de políticas como Kyverno u OPA Gatekeeper.
Red: por defecto, todo habla con todo
La documentación oficial es explícita: por defecto, un pod no está aislado y acepta todas las conexiones de entrada, y lo mismo ocurre con la salida. Las NetworkPolicies cambian eso, con un matiz importante: solo funcionan si el plugin de red (CNI) del clúster las implementa. Crear una política en un clúster cuyo CNI no las soporta no tiene ningún efecto.
Sin políticas de red, un pod comprometido puede:
- Conectarse a las bases de datos, cachés y colas de cualquier namespace.
- Llamar a APIs internas que se diseñaron asumiendo que solo las usarían otros servicios de confianza.
- Alcanzar el servicio de metadatos del proveedor cloud y otros servicios de los nodos.
- Salir a internet para descargar herramientas o exfiltrar datos.
El patrón recomendado es denegar todo por defecto en cada namespace y abrir solo los flujos necesarios, incluida la salida: hacia el servicio de metadatos y hacia internet, la mayoría de las aplicaciones no necesitan llegar.
El controlador de ingress merece atención aparte, porque recibe tráfico de internet y suele tener permisos amplios. En marzo de 2025 el proyecto publicó CVE-2025-1974 en ingress-nginx, con una puntuación CVSS de 9,8: según el blog oficial de Kubernetes, cualquier cosa en la red de pods tenía muchas posibilidades de tomar el control del clúster sin credenciales, en parte porque ingress-nginx tiene por defecto acceso a todos los secretos. En noviembre de 2025 se anunció la retirada de ingress-nginx, que dejó de recibir mantenimiento en marzo de 2026: si tu clúster lo sigue usando, ya no recibirá parches de seguridad y conviene planificar la migración, por ejemplo a una implementación de Gateway API.
Secretos: base64 no es cifrado
El objeto Secret de Kubernetes da una falsa sensación de protección. La documentación oficial deja claros tres puntos:
- Por defecto, los secretos se guardan sin cifrar en etcd, el almacén de datos del API server. Quien acceda a etcd o a una copia de seguridad suya los lee.
- La codificación base64 no da confidencialidad. Solo los ofusca para que no se lean de un vistazo.
- Quien puede crear un pod en un namespace puede leer todos los secretos de ese namespace, aunque no tenga permiso directo sobre ellos: le basta con montarlos en un pod que controle.
Qué revisar:
| Aspecto | Qué comprobar |
|---|---|
| Cifrado en reposo | En clústeres propios, que el API server arranque con una configuración de cifrado (EncryptionConfiguration), idealmente con un proveedor KMS; en servicios gestionados, qué cifrado aplica el proveedor y si puedes usar tu propia clave |
| Acceso a secretos | Quién tiene get, list o watch sobre secrets y quién puede crear pods en cada namespace |
| Secretos fuera del clúster | Valores en claro en manifiestos, ficheros de Helm, repositorios Git o imágenes de contenedor |
| Variables de entorno | Secretos inyectados como variables, que acaban en volcados de error y herramientas de diagnóstico |
| Gestor externo | Si se usa un gestor de secretos del proveedor cloud o de terceros, con rotación, en lugar de copiar valores al clúster |
En la práctica, los secretos más expuestos no están en etcd, sino en el repositorio de despliegue: un fichero de valores con la contraseña de la base de datos, comprometido en Git hace dos años y nunca rotado.
Kubernetes gestionado: EKS, AKS y GKE
En un servicio gestionado, el proveedor se encarga del plano de control: el API server, etcd y su disponibilidad. Todo lo demás sigue siendo tuyo: la configuración de los nodos, RBAC, las cargas de trabajo, las políticas de red, los secretos y, sobre todo, el puente entre las identidades de Kubernetes y las del cloud.
Ese puente es el punto que más se explota. Un nodo tiene un rol o identidad cloud para hacer su trabajo; si un pod puede llegar al servicio de metadatos del nodo, puede obtener esas credenciales. La guía de buenas prácticas de EKS lo advierte expresamente y recomienda exigir IMDSv2 con un límite de saltos (hop limit) de 1 para que los pods no lleguen. Ojo con los valores por defecto: en los managed node groups el límite es 2, lo que deja pasar a los pods; EKS Auto Mode, en cambio, fuerza el límite de 1.
La alternativa correcta es dar a cada aplicación su propia identidad cloud, ligada a su cuenta de servicio de Kubernetes:
| Servicio | Identidad por carga de trabajo | Qué revisar |
|---|---|---|
| Amazon EKS | IAM Roles for Service Accounts (IRSA) o EKS Pod Identity | Acceso de los pods al servicio de metadatos del nodo y permisos de cada rol asociado |
| Azure AKS | Microsoft Entra Workload ID | Que no queden configuraciones de la antigua pod-managed identity, ya retirada |
| Google GKE | Workload Identity Federation for GKE | Que el servidor de metadatos de GKE esté activo, de modo que los pods no lleguen al de Compute Engine |
Otros dos detalles de EKS que aparecen a menudo en las revisiones: los logs del plano de control, incluido el de auditoría, no se envían a CloudWatch por defecto, y el endpoint del API server es público por defecto, protegido por IAM y RBAC. Ninguna de las dos cosas es un fallo en sí, pero las dos conviene decidirlas conscientemente.
Supervisión, versiones e imágenes
Tres áreas que no se ven hasta que hacen falta:
- Registro de auditoría. En un clúster autogestionado, si el API server no arranca con una política de auditoría (--audit-policy-file), no se registra ningún evento. En los servicios gestionados hay que activarlo y enviarlo a un destino donde alguien lo revise. Sin él, no hay forma de saber qué hizo un atacante con un token robado.
- Versiones. El proyecto mantiene las tres versiones menores más recientes, cada una durante unos 14 meses. Un clúster fuera de soporte deja de recibir parches de seguridad, y lo mismo ocurre con sus complementos: controladores de ingress, CNI, operadores y gráficos de Helm instalados hace años.
- Imágenes. La mayoría de las vulnerabilidades conocidas de un clúster no están en Kubernetes, sino en las imágenes que ejecuta. Lo razonable es usar imágenes base mínimas, escanearlas en el pipeline y en el registro, fijarlas por digest en lugar de por etiqueta y limitar con una política de admisión desde qué registros se pueden desplegar.
La seguridad del pipeline que construye y despliega esas imágenes es un tema propio: si un atacante controla el CI/CD, controla lo que se ejecuta en el clúster. Lo tratamos en el recurso sobre pentesting de pipelines CI/CD.
Cómo se audita un clúster de Kubernetes
Una auditoría completa combina dos miradas: la configuración contra una línea base y el comportamiento frente a un atacante.
| Prueba | Qué responde | Cómo se hace |
|---|---|---|
| Línea base CIS | ¿La configuración del plano de control, los nodos y las políticas sigue las recomendaciones? | CIS Kubernetes Benchmark (y sus variantes para EKS, AKS y GKE) con kube-bench |
| Postura del clúster | ¿Qué cargas de trabajo incumplen buenas prácticas? | Escáneres como Kubescape (proyecto en incubación de la CNCF) o Trivy, que también revisa imágenes |
| Análisis de RBAC | ¿Quién puede hacer qué y quién puede escalar? | Revisión de roles y enlaces, kubectl auth can-i por identidad, herramientas de grafo de permisos |
| Superficie externa | ¿Qué se ve desde internet? | Descubrimiento de API servers, paneles, puertos del kubelet, ingress y servicios LoadBalancer o NodePort |
| Pod comprometido | ¿Hasta dónde llega un atacante con una shell en una aplicación? | Desde un pod de prueba: token de la cuenta de servicio, red interna, metadatos del cloud, escape al nodo, secretos |
| Puente al cloud | ¿Qué consigue en la cuenta cloud quien controla un pod o un nodo? | Permisos efectivos de los roles de los nodos y de las identidades por carga de trabajo |
Las dos primeras filas se automatizan bien y deberían ejecutarse de forma continua. Las cuatro últimas son las que encuentran los caminos que acaban en un incidente, porque dependen de combinar hallazgos: una aplicación con un fallo, una cuenta de servicio con permisos de más, un pod que llega al servicio de metadatos y un rol de nodo que puede leer todos los buckets.
Una advertencia sobre herramientas: kube-hunter, muy citado en guías antiguas, ya no tiene desarrollo activo y su propio repositorio recomienda Trivy. Y ninguna herramienta sustituye a la prueba desde un pod comprometido, que es la que responde a la pregunta que importa.
FAQ
¿Kubernetes es inseguro por defecto?
No exactamente, pero sus valores por defecto priorizan la funcionalidad: los pods no están aislados en red, los secretos se guardan sin cifrar en etcd y el registro de auditoría no se activa solo. Un clúster recién creado es razonable para empezar a trabajar, no para producción con datos sensibles sin bastionarlo.
¿Los Secrets de Kubernetes están cifrados?
Por defecto, no: se guardan sin cifrar en etcd y la codificación base64 no aporta confidencialidad. Hay que activar el cifrado en reposo en el API server o comprobar qué ofrece el servicio gestionado, limitar quién puede leerlos o crear pods y, preferiblemente, usar un gestor de secretos externo con rotación.
¿Qué sustituye a PodSecurityPolicy?
Pod Security Admission, que aplica los Pod Security Standards (Privileged, Baseline y Restricted) mediante etiquetas en cada namespace y es estable desde Kubernetes 1.25, la misma versión en la que se eliminó PodSecurityPolicy. Para reglas más específicas se complementa con motores de políticas como Kyverno u OPA Gatekeeper.
Si usamos EKS, AKS o GKE, ¿la seguridad del clúster es cosa del proveedor?
Solo la del plano de control. RBAC, la configuración de los pods, las políticas de red, los secretos, las imágenes y la relación entre las identidades de Kubernetes y las del cloud siguen siendo responsabilidad tuya, y ahí es donde se producen la mayoría de los incidentes.
¿Basta con pasar kube-bench o un escáner de postura?
Es un buen punto de partida y conviene hacerlo de forma continua, pero no basta. Esas herramientas comparan la configuración con reglas; no comprueban qué puede hacer un atacante encadenando una aplicación vulnerable, una cuenta de servicio con permisos de más y el acceso al rol cloud del nodo. Para eso hace falta una prueba ofensiva desde un pod comprometido.
Seguimos usando ingress-nginx, ¿qué hacemos?
Planificar la migración cuanto antes. El proyecto se retiró en marzo de 2026 y ya no recibe parches de seguridad, después de haber tenido en 2025 una vulnerabilidad crítica que permitía tomar el control del clúster desde la red de pods. La alternativa recomendada por el proyecto es Gateway API, con alguna de sus implementaciones, u otro controlador de ingress mantenido.
Servicio relacionado
pentesting cloud, incluidos clústeres EKS, AKS y GKE
Contenido relacionado
- Los errores de configuración cloud más comunes
- Pentesting en AWS: qué se revisa y qué permite AWS
- CSPM vs pentesting cloud
- Pentesting de pipelines CI/CD
- DevSecOps: seguridad ofensiva en el desarrollo
- Hacking ético interno: el supuesto de un atacante dentro