Sysdig
Learn Cloud Native

Sign up to receive our newsletter

Seguridad del clúster de Kubernetes, componente por componente

Si está familiarizado con Kubernetes, sabrá que no es una única herramienta, sino un conjunto de distintos tipos de servicios y recursos, como un servidor de API, agentes de nodo, tiempos de ejecución de containers, etc.

Cada uno de los componentes dentro de un clúster de Kubernetes está expuesto a diferentes tipos de amenazas de seguridad y requiere diferentes configuraciones de seguridad. En algunos casos, es posible aplicar la misma técnica de seguridad a varios componentes. Por ejemplo, se puede utilizar el control de acceso basado en roles para gestionar los permisos de varios tipos de recursos en Kubernetes.

Sin embargo, algunos componentes tienen requisitos de seguridad únicos y requieren, por tanto, soluciones de seguridad también únicas. La seguridad del servidor de la API es diferente de la seguridad de los nodos, por ejemplo. Para proteger un clúster de Kubernetes, es preciso conocer y abordar las posibles amenazas de seguridad de cada componente.

Teniendo esto presente, a continuación explicaremos cómo proteger un clúster Kubernetes asegurando cada uno de sus distintos componentes.

Cómo proteger un clúster de Kubernetes

  1. Protección del servidor de la API de Kubernetes

El servidor de la API de Kubernetes, kube-apiserver, es el corazón de su clúster de Kubernetes. El servidor de la API es el que otorga las solicitudes de acceso o mantiene las workloads ejecutándose, por ejemplo.

La principal herramienta para proteger el servidor de la API en Kubernetes es el marco de control de acceso basado en roles de Kubernetes (Role-Based Access Control o RBAC). Con las políticas RBAC puede definir usuarios y cuentas de servicios, y luego asignar permisos que permitan a estos realizar ciertas acciones utilizando la API de Kubernetes.

Por ejemplo, puede crear un rol RBAC que permita a un recurso obtener, ver y listar pods en el namespace predeterminado de Kubernetes. Un ejemplo de rol podría ser:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
  - apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

A continuación, habría que asociar el rol con un usuario o grupo de servicios en Kubernetes creando un RoleBinding o un ClusterRoleBinding con un comando como:

kubectl create rolebinding podreader-binding --user=john

Este RoleBinding da al usuario “john” los permisos para obtener, ver y listar los pods que se definen en el rol anterior.

Controladores de admisión y seguridad de la API de Kubernetes

Con los controladores de admisión puede proporcionar una segunda capa de defensa para la API de Kubernetes y, por extensión, para todo su clúster de Kubernetes. Un controlador de admisión es básicamente un código que intercepta las solicitudes a la API de Kubernetes después de que la API haya autenticado y autorizado una solicitud, pero antes de que la ejecute.

Los controladores de admisión se pueden utilizar, por ejemplo, para limitar el volumen de recursos que un objeto puede solicitar a la API o para impedir la ejecución de determinados comandos aunque las políticas RBAC y los contextos de seguridad los permitan.

Uso de registros de auditoría para mejorar la seguridad

Un tercer recurso para ayudar a prevenir problemas de seguridad relacionados con la API de Kubernetes son los registros de auditoría. Los registros de auditoría son un elemento opcional de Kubernetes que permite registrar y rastrear las solicitudes a medida que el servidor de la API las procesa.

Al crear registros de auditoría y analizarlos continuamente con una herramienta como Falco, recibirá alertas automáticas cuando un usuario o servicio realice solicitudes sospechosas como, por ejemplo, intentar acceder repetidamente a recursos a los que el usuario o el servicio no está autorizado.

  1. Protección y copia de seguridad de Etcd 

etcd es un almacén de clave-valor que Kubernetes utiliza de forma predeterminada para almacenar todos los datos de configuración de su clúster.

Kubernetes no ofrece ninguna herramienta nativa para asegurar etcd, por lo que debe asegurarse de habilitar la seguridad del transporte. Consulte la documentación de etcd para más información.

Para garantizar la seguridad del clúster, también es recomendable que se asegure de hacer una copia de seguridad de etcd utilizando el comando etcdctl snapshot save. Aun cuando ejecute Kubernetes en un lugar donde confíe plenamente en la fiabilidad de etcd, las copias de seguridad de etcd le protegen contra el ransomware u otros ataques que intenten deshabilitar su acceso a los datos de configuración críticos almacenados en etcd.

Por último, una de las prácticas recomendadas cuando se trabaja con etcd es evitar el almacenamiento de datos secretos sensibles, como contraseñas y claves de acceso, en etcd. La mayoría de las distribuciones de Kubernetes almacenan los secretos en etcd de forma predeterminada, aunque es preferible que utilice un gestor de secretos externo.

  1. Protección de nodos maestros 

Un nodo maestro de Kubernetes es el nodo que aloja el servidor de la API de Kubernetes, el programador, el controlador y etcd, es decir, todos los servicios esenciales que enlazan y gestionan un clúster de Kubernetes. Algunos clústeres de Kubernetes pueden ejecutar varios nodos maestros para aumentar la disponibilidad del clúster, en cuyo caso cada maestro ejecuta instancias redundantes de los servicios centrales de Kubernetes.

Dado el papel central que desempeñan los nodos maestros en el clúster, protegerlos es fundamental para la seguridad de todo el clúster. Hay varias mejores prácticas para proteger los nodos maestros:

  • Aprovisionar los nodos maestros con una distribución de Linux minimalista, como Alpine Linux. Evitar instalar aplicaciones o bibliotecas adicionales en el nodo a menos que sean estrictamente necesarias. 
  • Utilizar políticas RBAC para restringir las acciones que se pueden realizar en los nodos. Cuanto menos acceso e información sobre sus nodos tengan los atacantes, más seguros serán los nodos.
  • Utilizar marcos de aplicación como SELinux, AppArmor y seccomp para restringir los controles de acceso a nivel del núcleo en el maestro. Estos marcos ayudarán a prevenir la escalada de un evento de seguridad al hacer más difícil que un proceso malicioso acceda a los recursos del núcleo o interfiera con otros procesos.
  • Supervisar continuamente los archivos de registro de los nodos para detectar signos de actividad sospechosa.
  1. Protección de los nodos de trabajo y restricción de los permisos de Kubelet y Kube-Proxy

La función principal de los nodos de trabajo es alojar containers o pods que se están ejecutando. Cada nodo de trabajo se comunica con el resto del clúster a través de kubelet, un agente que se ejecuta localmente en cada nodo de trabajo. Los nodos de trabajo también utilizan un servicio llamado kube-proxy para gestionar las comunicaciones de red de los pods que están alojados en los nodos de trabajo.

Los nodos de trabajo en Kubernetes están pensados para que sean intercambiables. Si un nodo falla, Kubernetes reasignará automáticamente los pods del nodo a otros nodos. En este sentido, la protección de los nodos de trabajo no es tan crítica como la de los nodos maestros, ya que el hecho de que algunos nodos de trabajo dejen de funcionar por problemas relacionados con la seguridad no supone una amenaza grave para el clúster en su conjunto.

Sin embargo, si un atacante consigue comprometer un nodo de trabajo, posiblemente podrá acceder a los pods alojados en esos nodos. Por esa razón, es importante adoptar medidas para proteger los nodos de trabajo como parte del proceso general de seguridad del clúster.

Todas las mejores prácticas que recomendamos anteriormente para proteger los nodos maestros también son aplicables a los nodos de trabajo. Asimismo, contemple la posibilidad de restringir los permisos otorgados a kubelet y kube-proxy para limitar los posibles daños que podría causar un atacante si logra escapar de un container y penetrar en el nodo de trabajo que lo aloja.

  1. Escaneo continuo de las imágenes de containers

Las imágenes de containers, que definen los recursos necesarios para ejecutar los containers, no forman parte de Kubernetes en sí, pero son un elemento esencial de la mayoría de los clústeres de Kubernetes, por lo que no deben pasarse por alto al proteger el clúster.

La clave para proteger las imágenes de containers es escanearlas continuamente. También puede minimizar los problemas de seguridad asociados a los containers de la siguiente manera:

  • Utilice únicamente imágenes de fuentes de confianza. Evite la tentación de sacar imágenes de un registro aleatorio solo porque es más cómodo.
  • Evite el uso de la etiqueta “latest” al extraer containers. En su lugar, opte por una versión específica. De este modo sabrá exactamente qué versión del container se está ejecutando y qué vulnerabilidades de seguridad pueden afectarlo.
  • Adopte un enfoque minimalista para diseñar imágenes de containers. En vez de intentar empaquetar múltiples recursos en una sola imagen, cree imágenes diferentes para cada funcionalidad que necesite implementar.
  1. Container Runtime Security

El tiempo de ejecución de containers es el servicio que realmente ejecuta los containers. Kubernetes soporta varios tiempos de ejecución. En general, las diferencias entre los tiempos de ejecución no suelen ser importantes en la práctica actualmente, ya que prácticamente todos los tiempos de ejecución son capaces de ejecutar la mayoría de los containers.

Un fallo de seguridad en su software de tiempo de ejecución de containers puede permitir a los atacantes ejecutar toda una serie de exploits. Por ejemplo, en 2019, los desarrolladores descubrieron una importante vulnerabilidad en el tiempo de ejecución de Docker que permitió que los containers obtuvieran acceso de nivel raíz al host.

Kubernetes por sí mismo no monitoriza el tiempo de ejecución de sus containers en busca de vulnerabilidades ni lo alerta de las brechas que dichas vulnerabilidades puedan provocar. Esto significa que para proteger los tiempos de ejecución necesitará herramientas externas que incluyan:

  • Marcos de aplicación, como SELinux y AppArmor, que le permiten restringir las acciones que puede realizar un container malicioso. Si se configuran correctamente, estos marcos proporcionan una segunda capa de defensa en caso de que un atacante explote una vulnerabilidad de seguridad en el tiempo de ejecución del container para realizar acciones que no deberían estar permitidas.
  • Herramientas de auditoría, como Falco, que supervisan continuamente los registros de auditoría y otros flujos de datos del entorno de ejecución de sus containers y le alertan cuando detectan un comportamiento que pueda indicar una brecha. Además de ser capaces de detectar distintas amenazas de seguridad aparte de las relacionadas con los tiempos de ejecución de los containers, las herramientas de auditoría son el principal medio para identificar las brechas originadas por una vulnerabilidad a nivel de tiempo de ejecución.
  • A menos que sea estrictamente necesario, utilice los contextos de seguridad de Kubernetes para evitar que los containers se ejecuten en modo privilegiado y para restringir los recursos a los que pueden acceder. Si bien los contextos de seguridad no evitan directamente las vulnerabilidades en tiempo de ejecución de containers, sí proporcionan una capa adicional de defensa que puede mitigar el impacto de una brecha en tiempo de ejecución.

Un enfoque holístico de la seguridad del clúster de Kubernetes

Sería estupendo que hubiera algún “truco” con el que se pudieran proteger permanentemente todos los componentes de Kubernetes. Pero no lo hay. La seguridad de Kubernetes es tan compleja como su propia arquitectura. Aunque ciertas prácticas a nivel de clúster, como la auditoría y la monitorización, proporcionan una amplia protección contra algunos tipos de amenazas, también es necesario desplegar recursos de seguridad que protejan los distintos componentes individuales del clúster de Kubernetes, desde el servidor de la API y los nodos de trabajo y maestros, a etcd y otros.