25 de Enero de 2022
La unidad mínima de abstracción que nos ofrece Kubernetes para ejecutar aplicaciones se denomina Pod, y está influenciada principalmente por los contenedores; encuadrando conceptos como inmutabilidad, escalabilidad, agilidad, flexibilidad y portabilidad, entre otros.
Estos Pods se crean y se ejecutan en el contexto de un nodo worker, que se traduce básicamente en una máquina virtual o cualquier dispositivo con capacidades de cómputo y almacenamiento.
Con el fin de securizar las aplicaciones que ejecutan en la plataforma, Kubernetes ofrece dos estrategias, en forma nativa, cuyo principal propósito es implementar un modelo robusto y controlado de seguridad tanto en la creación como así también en la ejecución y utilización de recursos.
- Una de ellas existe sólo en el contexto de ejecución de un Pod, y su principal propósito es limitar las capacidades que tiene un Pod sobre la infraestructura donde reside. Ésta se denomina Security Context.
- Por otro lado, Kubernetes también ofrece validaciones a la hora de crear o actualizar un Pod, en donde se pueden especificar ciertos requerimientos que el manifiesto debe cumplir para crear o no el recurso. Éste caso se conoce como PodSecurityPolicy.
Desafortunadamente, PodSecurityPolicy se encuentra deprecado desde la versión 1.21, y será completamente eliminado a partir de la versión 1.25.
A causa de esta modificación, el Kubernetes Auth Special Interest Group, particularmente involucrado en estas cuestiones, ideó un nuevo estándar de seguridad para hacer frente a estas necesidades denominado Pod Security Standards (PSS), acompañado de una estrategia de implementación mediante controles de admisión denominada Pod Security Admission (PSA).
A continuación, se describirán estas estrategias con un nivel más de detalle.
Security Contexts
Kubernetes ofrece la posibilidad de manejar los mismos estándares de seguridad que ofrece Linux, como así también hereda y escala las utilidades de Docker, tales como el ID de usuario y las capacidades de Linux que se pueden agregar o eliminar del contenedor.
Algunas de las características ofrecidas son:
- Discretionary Access Control: permisos para acceder a objetos (UID o GID).
- Security Enhanced Linux (SELinux)
- Modos privilegiados y no privilegiados de ejecución.
- Capacidades de Linux
- AppArmor: Perfiles que restringen las capacidades de programas en firma individual.
- Seccomp: Filtra llamadas de sistema de un proceso.
- AllowPrivilegeEscalation: Controla si un proceso puede obtener más privilegios que su proceso principal
- readOnlyRootFilesystem: Monta el file sistem como sólo lectura.
Todas éstas funcionalidades se configuran mediante los SecurityContexts como parte de las especificaciones de un Pod y su/s contenedor/es, y el objetivo es controlar el accionar del mismo en tiempo de ejecución.
Veamos algunos ejemplos:
En este caso, el Pod de la imagen debe ejecutar en modo no privilegiado, utilizando el usuario de Linux con UID 1001. En éste último caso, el contexto se define a nivel de contenedor dentro del Pod y nuevamente configura un UID específico de ejecución así también como una capacidad particular de Linux a incorporar. De acuerdo a la definición formal que brinda Kubernetes, el PSS “define tres políticas distintas para cubrir ampliamente el espectro de seguridad. Éstas políticas son acumulables y van desde altamente permisivas hasta altamente restrictivas.” Éstas políticas se definen de la siguiente manera: Ahora bien, estas políticas de seguridad definen tres perfiles de ejecución de Pods, ordenados por niveles de privilegio vs restricción de acceso. Para implementar estos controles definidos por el PSS, el control de admisión PSA opera en tres modos: Éstos modos, junto con el perfil o restriccion que atacan, son configurados a nivel de Kubernetes Namespace, para lo cual se utilizarán labels o etiquetas, como se ve en el siguiente ejemplo: Éste sería un escenario de extrema seguridad, donde se fuerza el rechazo de Pods que no cumplan con las políticas mas severas, así como también se audita y se notifica al usuario para tomar acción en forma inmediata. Para el siguiente escenario: No se presenta un nivel de rechazo fuerte (sólo debería cumplir con políticas de base), pero si se notifica cualquier otra restricción fuerte que no se cumpla. Qué sucede en el caso donde en el Namespace haya Pods existentes creados con anterioridad, previo a configurar el control de admisión? El comportamiento de los modos audit y warn será sin dudas similar, notificando al log de auditoría y al usuario cuando las políticas no puedan ser validadas con éxito. Acá se pueden visualizar los mensajes de warning correspondientes: Por otro lado, el modo enforce, no podrá eliminar Pods que ya hayan sido creados. Qué otra opción tenemos para controlar políticas de seguridad en el cluster a nivel Pods? Si no existiese la limitación de usar herramientas nativas a Kubernetes, se podría elegir entre un abanico de posibilidades que ofrece la comunidad y permiten reemplazar, o bien complementar los niveles de seguridad vistos recientemente. Éstas herramientas, denominadas Policy-as-code (PaC), proveen recursos extras para guiar a usuarios al uso correcto del cluster, así como a prevenir comportamientos inadecuados. Al igual que PSA, PaC se basa en Kubernetes Dynamic Admission Controllers, los cuales interceptan las peticiones que arriban al Kubernetes API Server, pudiendo validar o transformar información en base a políticas escritas y almacenadas como código. Esta tranformación o mutación sucede en forma previa a que se realicen cambios a nivel cluster, por lo que lo convierte el lugar óptimo. Existen varias soluciones de código abierto basadas en PaC disponibles para Kubernetes, entre las que se encuentran: No importa cuál herramienta sea elegida para implementar un modelo de seguridad eficiente y robusto en Kubernetes, incluso muchas de ellas pueden ofrecer funcionalidades complejas si se utilizan en forma compuesta. Lo que sí resulta de suma importancia, es tener claro qué se necesita hacer, entender cuáles son los objetivos a nivel seguridad para setear expectativas acordes, e identificar buenas prácticas en el proceso. A continuación, algunas recomendaciones mínimas recopiladas a partir de la experiencia, que guiarán a una correcta definición de un modelo de seguridad de base en aplicaciones distribuidas que corren en Kubernetes:Pod Security Standards (PSS) and Pod Security Admission (PSA)
apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
labels:
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/warn: restrictedapiVersion: v1
kind: Namespace
metadata:
name: my-namespace
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/warn: restrictedWarning: existing pods in namespace “my-namespace” violate the new PodSecurity enforce level “restricted:latest”Warning: test-688f68dc87-htm8x: allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfilenamespace/my-namespace configured
Policy-as-Code
Conclusión



Federico Catinello,
Solution Architect & SRE



Autor:
Federico Catinello,