Sysdig
Learn Cloud Native

Sign up to receive our newsletter

Por qué y cómo proteger los pods con contextos de seguridad de Kubernetes

¿Cómo puede asegurarse de que cada uno de los recursos de Kubernetes tenga los permisos que necesita, evitando al mismo tiempo una configuración demasiado permisiva? O dicho de otro modo, ¿cómo puede definir permisos de forma granular siguiendo el principio de mínimo privilegio?

La respuesta es el contexto de seguridad de Kubernetes. El contexto de seguridad es una herramienta que permite a los administradores definir parámetros relacionados con la seguridad recurso por recurso. Esto permite asignar a cada recurso los permisos específicos que necesita para acceder a los recursos en el servidor anfitrión y denegar el acceso a aquellos que no son indispensables.

En este artículo le presentamos una descripción general del contexto de seguridad de Kubernetes, incluyendo cómo funciona, cómo definir un contexto de seguridad y qué limitaciones hay que tener en cuenta al trabajar con el contexto de seguridad en Kubernetes.

¿Qué es el contexto de seguridad de Kubernetes?

En Kubernetes, un contexto de seguridad define los privilegios específicos para cada pod o container. Puede utilizar el contexto de seguridad para otorgar permisos a los containers o pods, como el derecho a acceder a un archivo externo o a ejecutarse en modo privilegiado.

Contextos de seguridad internos  y externos

El contexto de seguridad de Kubernetes es un poco complicado en el sentido de que algunas de las reglas que se pueden definir se implementan internamente a través de Kubernetes, mientras que otras se integran con herramientas de contexto de seguridad externas, a saber: AppArmor y SELinux.

Así pues, el contexto de seguridad de Kubernetes se puede ver como una forma de definir ciertos permisos para los pods y containers, así como de integrar Kubernetes con herramientas de seguridad externas que se ejecutan en el host en lugar de en el propio Kubernetes.

Contextos de seguridad vs. RBAC

El contexto de seguridad es similar, aunque diferente, al control de acceso basado en roles de Kubernetes o RBAC. Las principales diferencias son las siguientes:

  • Ámbito de recursos: El RBAC puede aplicarse a diversos recursos de Kubernetes, como pods, nodos e incluso clústeres completos. El contexto de seguridad asigna permisos solo a pods.
  • Acciones: RBAC puede otorgar una serie de permisos basados en “verbos” que los administradores pueden definir en las políticas de RBAC. El contexto de seguridad es más restrictivo, ya que solo permite a los administradores asignar tipos específicos de funciones predeterminadas, como la ejecución en modo privilegiado (aunque los contextos de seguridad son más flexibles si se definen reglas utilizando SELinux o AppArmor).
  • Extensibilidad: Como se ha señalado anteriormente, los contextos de seguridad pueden ampliarse mediante integraciones con marcos externos, incluidos SELinux y AppArmor. El RBAC de Kubernetes no puede utilizar herramientas externas para definir políticas.

Por lo tanto, considere el contexto de seguridad como una forma de definir otros tipos de permisos de seguridad para containers y pods que RBAC no puede gestionar. Para la mayoría de los entornos de Kubernetes, es recomendable utilizar el contexto de seguridad y el RBAC al mismo tiempo, ya que se complementan entre sí.

Contextos de seguridad vs. Pod Security Policies (políticas de seguridad de pod)

Muchas de las reglas de seguridad que se puede definir con los contextos de seguridad también se pueden configurar a través de las políticas de seguridad de pod, que son una herramienta diferente.

¿Por qué Kubernetes ofrece soporte tanto para los contextos de seguridad como para las políticas de seguridad de pod? La respuesta es que los contextos de seguridad son básicamente un sustituto de las políticas de seguridad de pod. Las políticas de seguridad de pod, que pueden utilizarse para configurar los permisos de todos los pods que se ejecutan en un clúster, proporcionan un control menos granular que los contextos de seguridad, que pueden aplicarse a pods individuales.

A partir de la versión 1.21 de Kubernetes, las políticas de seguridad de pod se consideran obsoletas, aunque por ahora siguen siendo compatibles. Las políticas de seguridad de pod se eliminarán por completo con Kubernetes 1.25. A partir de ese momento, se ignorarán las políticas de seguridad de pod que se definan.

Cómo utilizar el contexto de seguridad de Kubernetes

El uso del contexto de seguridad en Kubernetes es sencillo (especialmente si trabaja solo con el contexto de seguridad interno y no se integra con SELinux o AppArmor). Basta con que incluya un bloque de código de contexto de seguridad en el fichero de despliegue que se crea al desplegar un pod.

Por ejemplo, el siguiente bloque indica a Kubernetes que ejecute un pod con un ID de usuario de 1000. También asigna un ID de grupo de 2000 a todos los containers del pod:

Spec:
securityContext:
runAsUser: 1000
fsGroup: 2000

A diferencia del RBAC, el contexto de seguridad no requiere que defina varios tipos de archivos (como Roles y RoleBindings) para aplicar una regla de seguridad. Solo tiene que añadir el código de contexto de seguridad necesario cuando cree un despliegue, y Kubernetes aplicará automáticamente las reglas a partir de ahí.

Para obtener una descripción completa de los tipos de permisos que puede asignar (o denegar) con el contexto de seguridad, consulte la documentación de Kubernetes. Además de los permisos relacionados con los ID de usuario y grupo, para la mayoría de los administradores resultan valiosos los parámetros que permiten que el pod o el container se ejecuten en modo privilegiado. Un container que se ejecuta en modo privilegiado tiene prácticamente los mismos derechos de acceso a los recursos a nivel de núcleo en el host que un proceso que se ejecuta como root, por lo que lo normal es que no permita el modo privilegiado. En su lugar, defina los permisos de forma granular, por ejemplo, permitiendo que el container o el pod se vinculen con un determinado puerto o ejecuten ciertos binarios externos, al tiempo que deniega el acceso a los recursos fuera del container.

Cómo trabajar con contextos de seguridad externos

Aplicar el contexto de seguridad basado en herramientas externas como SELinux y AppArmor requiere un poco más de trabajo. Estos son los pasos básicos.

Cargar el módulo SELinux o AppArmor

En primer lugar, debe asegurarse de que el módulo de núcleo asociado con el marco que está utilizando (SELinux o AppArmor) está instalado y cargado en el nodo o nodos que alojarán sus containers o pods.

Dado que en la mayoría de los casos Kubernetes asigna automáticamente los pods o containers a los nodos, no sabrá de antemano qué nodo alojará qué container o pod. Por consiguiente, necesitará instalar AppArmor o SELinux en cada nodo de su clúster si quiere definir contextos de seguridad a través de uno de estos marcos.

Cargar un perfil

Después de cargar los módulos, deberá cargar el perfil de AppArmor o SELinux que va a utilizar para definir los permisos. Por ejemplo, el siguiente perfil de AppArmor impide la escritura en archivos:

#include <tunables/global>
p
rofile k8s-apparmor-example-deny-write flags=(attach_disconnected)
{
#include <abstractions/base>
file,
# Deny all file writes.
deny /** w,
}

Guarde el perfil en el sistema de archivos del nodo en una ubicación que Kubernetes pueda leer.

Como probablemente no sepa qué nodo ejecutará qué containers o pods, también aquí tendrá que cargar el perfil en cada nodo de su clúster. Si desea saber cómo hacerlo de manera eficiente (es decir, evitando tener que conectar con SSH a cada nodo y aplicar los perfiles manualmente), consulte la documentación de Kubernetes sobre perfiles de nodo.

Aplicar el perfil en Kubernetes

Por último, añada un bloque de contexto de seguridad a su fichero de despliegue que le indique a Kubernetes que haga referencia al perfil de contexto de seguridad externo y lo aplique al despliegue:

apiVersion: v1
kind: Pod
metadata:
name: apparmor-demo
annotations:
container.apparmor.security.beta.kubernetes.io/hello: /path/to/policy-file

Aplique su implementación con:

kubectl create -f ./deployment.yml

Ahora, Kubernetes aplicará la política que usted ha configurado a través de AppArmor o SELinux igual que si se tratara de un contexto de seguridad que usted configura directamente en un fichero de despliegue.

Limitaciones de los contextos de seguridad

El contexto de seguridad de Kubernetes es una potente herramienta para definir ciertos tipos de permisos de forma granular. Sin embargo, actualmente está sujeto a algunas limitaciones importantes.

No es compatible con Windows

Por un lado, la herramienta de contexto de seguridad actualmente solo maneja privilegios y permisos que son válidos en un servidor basado en Linux. Si ejecuta containers de Windows en Kubernetes, los contextos de seguridad no le resultarán útiles.

Está limitado a la seguridad a nivel de pod/container

El contexto de seguridad solo puede definir permisos para pods o containers. No puede controlar los privilegios en otras capas de su pila.

Es cierto que la mayoría de las reglas que puede aplicar con los contextos de seguridad solo tendrían sentido cuando se aplican a containers o pods. Por ejemplo, no tendría sentido decirle a un nodo que se ejecute en modo sin privilegios.

Sin embargo, lo que importa aquí es que el contexto de seguridad es una herramienta que aborda los problemas de seguridad únicamente a nivel de pods o containers, por lo que necesitará otras herramientas (como RBAC) para proteger nodos, usuarios, cuentas de servicios y similares.

Es una función en evolución

Los contextos de seguridad son una función relativamente nueva para Kubernetes que sigue desarrollándose. Algunos parámetros (como fsGroupChangePolicy, que se introdujo con la versión beta en Kubernetes 1.20) aún no son totalmente compatibles, y es probable que aparezcan más definiciones en el futuro.

Por tanto, aunque ya se pueden utilizar los contextos de seguridad en los clústeres de producción, es importante seguir de cerca la evolución de esta función, ya que ciertos tipos de definiciones pueden cambiar en las próximas versiones.

Herramientas ineficientes

Como hemos señalado, una de las principales limitaciones de algunos contextos de seguridad (en concreto, los que utilizan perfiles SELinux o AppArmor) es que requieren el despliegue de recursos externos en cada nodo de su clúster. Aunque hay formas de automatizar este proceso, el simple hecho de configurar la automatización requiere bastante trabajo. También el despliegue podría resultar complicado si tiene nodos que ejecutan diferentes distribuciones de Linux, en cuyo caso podría tener que personalizar su configuración de AppArmor o SELinux para cada distribución.

Es de esperar que en el futuro aparezcan herramientas que simplifiquen el despliegue de perfiles de políticas en los distintos nodos. Pero por el momento, no subestime el trabajo y esfuerzo que le llevará configurar los nodos.

A pesar de estas limitaciones, los contextos de seguridad son un recurso importante para subsanar las posibles deficiencias de control de acceso en los clústeres de Kubernetes. Aunque su alcance es limitado y no son una solución completa de control de acceso por sí mismos, conviene aprovechar los contextos de seguridad como un modo de reforzar la seguridad general de su clúster.