Aplicar la seguridad de pods y contenedores
Comprender los estándares de seguridad de los pods
Kubernetes define tres estándares de seguridad para pods que describen niveles de seguridad cada vez más estrictos para la configuración de los pods. El controlador de Admisión de seguridad de pods (PSA), integrado en Kubernetes desde la versión 1.25, aplica estos estándares a nivel de espacio de nombres. Cada estándar define un conjunto de campos permitidos y prohibidos en las especificaciones de pod:
- Con privilegios: sin restricciones. Está reservado para los espacios de nombres del sistema y de la infraestructura que requieren acceso completo al host, como los espacios de nombres que ejecutan agentes de nodo o controladores de almacenamiento. No aplique este perfil a las cargas de trabajo de la aplicación.
-
Línea base: impide las escalaciones de privilegios conocidas. Este perfil bloquea los contenedores con privilegios,
hostPID,hostIPC,hostNetworky la mayoría de los montajes de volumenhostPath. Proporciona una posición de seguridad mínima sin interrumpir la mayoría de las aplicaciones en contenedores. -
Restringido: muy restringido. Aplica todas las restricciones de referencia y, además, requiere la ejecución como usuario no root, prohíbe la elevación de privilegios, obliga a usar un
seccompProfiley limita los tipos de volumen. Se recomienda para cargas de trabajo de aplicaciones y la mayoría de las implementaciones de producción.
Aplicar estándares de seguridad de Pod a los espacios de nombres
Los estándares de seguridad de Pod se implementan mediante etiquetas del espacio de nombres. Cada etiqueta especifica un perfil y un modo de cumplimiento. Hay tres modos de cumplimiento disponibles:
- enforce: los pods que infringen la directiva se rechazan en la admisión.
- warn: los pods que infringen la directiva se permiten, pero el usuario recibe una advertencia de la API en el momento de aplicarlos.
- audit: los pods que infringen la directiva se permiten y la infracción se registra en el registro de auditoría.
Aplique el perfil restringido a un espacio de nombres de aplicación:
kubectl label namespace retail-app \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/audit=restricted
La aplicación conjunta de estos tres modos le permite garantizar el cumplimiento en el momento de la admisión, mostrar advertencias visibles para los desarrolladores en el momento de la aplicación y disponer de un registro de auditoría de cualquier infracción que llegue al clúster.
Tip
Habilite los modos warn y audit en entornos de ensayo antes de hacerlos obligatorios en producción. Esto expone las cargas de trabajo que generarían un error en el estándar restringido y le permite corregirlas antes de que la directiva bloquee las implementaciones.
Configurar contextos de seguridad en las especificaciones del pod
Los estándares de seguridad para pods establecen restricciones de seguridad a nivel de espacio de nombres. Los contextos de seguridad especifican la configuración de seguridad para contenedores individuales. Una especificación de pod que define explícitamente la configuración del contexto de seguridad es más fácil de auditar, más portable entre clústeres y menos probable que produzca un error inesperado cuando cambien las directivas de nivel de espacio de nombres.
La siguiente especificación del pod demuestra los ajustes clave del contexto de seguridad para una carga de trabajo de producción:
apiVersion: v1
kind: Pod
metadata:
name: retail-api
namespace: retail-app
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: contoso.azurecr.io/retail-api:latest
securityContext:
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
Esta configuración aplica los siguientes comportamientos:
-
runAsNonRoot: el contenedor debe ejecutarse como un usuario que no searoot. El controlador de admisión rechaza el pod si el usuario predeterminado de la imagen es root y no se especifica ningún
runAsUser. - runAsUser: 1000: establece un UID específico. Use un UID distinto de cero que coincida con un usuario no privado definido en la imagen de contenedor.
- readOnlyRootFilesystem: monta el sistema de archivos raíz del contenedor como de solo lectura. Esto evita que los procesos en peligro escriban en disco o modifiquen archivos binarios de aplicación.
-
allowPrivilegeEscalation: false: impide que cualquier proceso del contenedor adquiera más privilegios de los que tenía al iniciarse, incluidos los binarios
setuido las capacidades de Linux. - capabilities.drop: ALL: quita todas las funcionalidades de Linux. Agregue solo las funcionalidades específicas que requiere la aplicación en lugar de heredar el conjunto de funcionalidades predeterminado.
- seccompProfile.type: RuntimeDefault: Aplica el perfil seccomp predeterminado del entorno de ejecución del contenedor, que restringe las llamadas al sistema que el contenedor puede realizar al kernel.
Mejora del aislamiento del host con espacios de nombres de usuario
De forma predeterminada, el usuario raíz dentro de un contenedor (UID 0) se asigna al usuario raíz en el nodo host (también UID 0). Una fuga del contenedor (un proceso que traspasa el límite de aislamiento del contenedor) otorga al atacante acceso root en el nodo. Los espacios de nombres de usuario desacoplan los UID de contenedor de los UID de host.
Cuando los espacios de nombres de usuario están habilitados y un pod se activa, el usuario root dentro del contenedor se asigna a un UID sin privilegios en el host. Incluso si una vulnerabilidad permite que un proceso escape al contenedor, no tiene privilegios en el nodo. Habilite los espacios de nombres de usuario para un pod estableciendo hostUsers: false en la especificación del pod:
spec:
hostUsers: false
Se trata de una mejora significativa de defensa en profundidad para las cargas de trabajo que procesan datos que no son de confianza o controlan datos de orígenes externos.
Aplicación de perfiles de AppArmor para el control de acceso obligatorio
AppArmor es un módulo de kernel de Linux que aplica el control de acceso obligatorio para los procesos. A diferencia de las funcionalidades de Linux, que restringen qué sistema llama a un proceso, AppArmor restringe los recursos a los que un proceso puede acceder por ruta de acceso: archivos, sockets de red y otros objetos del sistema.
Los nodos de AKS incluyen AppArmor. Aplique un perfil para cada pod mediante una anotación del pod:
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/api: runtime/default
El runtime/default perfil restringe el acceso a las rutas de acceso fuera del sistema de archivos del contenedor. Para cargas de trabajo de mayor seguridad, cargue un perfil personalizado en el nodo y haga referencia a él por nombre en la anotación.
Gracias a la aplicación de los estándares de seguridad de pods a nivel de espacio de nombres, a los contextos de seguridad que definen restricciones a nivel de contenedor y a la implementación de medidas de refuerzo opcionales mediante espacios de nombres de usuario y AppArmor, cada carga de trabajo del clúster de Contoso Retail cuenta con un perfil de seguridad definido de forma explícita y auditable.