Acceso de contenedor de seguridad a los recursos mediante características de seguridad integradas de Linux
En este artículo, aprenderá a proteger el acceso de contenedores a los recursos de las cargas de trabajo de Azure Kubernetes Service (AKS).
Información general
Por el mismo motivo que debería conceder a los usuarios o a los grupos el menor número de privilegios necesarios, también debería limitar los contenedores a solo las acciones y procesos necesarios. Para minimizar el riesgo de ataques, evite configurar las aplicaciones y los contenedores que requieren elevación de privilegios o acceso a raíz.
Puede usar contextos de seguridad de pod de Kubernetes integrados para definir más permisos, como el usuario o grupo para ejecutarse como, las funcionalidades de Linux que se van a exponer o establecer allowPrivilegeEscalation: false
en el manifiesto de pod. Para más recomendaciones, consulte Protección del acceso del pod a los recursos.
Para un control aún más detallado de las acciones de los contenedores, puede usar las características de seguridad incorporadas de Linux como AppArmor y seccomp.
- Defina las características de seguridad de Linux en el nivel de nodo.
- Implemente las características mediante un manifiesto de pod.
Las características de seguridad integradas de Linux solo están disponibles en los pods y los nodos de Linux.
Nota:
Actualmente, los entornos de Kubernetes no están completamente seguros ante el uso de varios inquilinos hostiles. Otras características de seguridad, como Microsoft Defender para contenedores, AppArmor, seccomp, Pod Security Admission o RBAC para Kubernetes para nodos, bloquean eficazmente las vulnerabilidades de seguridad.
Para una verdadera seguridad al ejecutar cargas de trabajo multiinquilino hostiles, solo debe confiar en un hipervisor. El dominio de seguridad de Kubernetes se convierte en todo el clúster, no en un nodo específico.
En el caso de estos tipos de cargas de trabajo multiinquilino hostiles, debe usar clústeres que estén físicamente aislados.
AppArmor
Para limitar las acciones de los contenedores, puede usar el módulo de seguridad del kernel de Linux denominado AppArmor. AppArmor está disponible como parte del SO del nodo de AKS subyacente del sistema operativo y está habilitado de forma predeterminada. Puede crear perfiles de AppArmor para restringir acciones como leer, escribir o ejecutar, o funciones del sistema como montar sistemas de archivos. Los perfiles de AppArmor predeterminados restringen el acceso a diferentes ubicaciones de /proc
y /sys
, y proporcionan un medio para aislar lógicamente los contenedores desde el nodo subyacente. AppArmor funciona para cualquier aplicación que se ejecuta en Linux, no solo para los pods de Kubernetes.
Para ver AppArmor en acción, en el ejemplo siguiente se crea un perfil que impide la escritura en archivos.
Acceda mediante SSH a un nodo de AKS.
Cree un archivo denominado deny-write.profile.
Copie y pegue el siguiente contenido:
#include <tunables/global> profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { #include <abstractions/base> file, # Deny all file writes. deny /** w, }
Los perfiles de AppArmor se agregan con el comando apparmor_parser
.
Agregue el perfil a AppArmor.
Especifique el nombre del perfil creado en el paso anterior:
sudo apparmor_parser deny-write.profile
Si el perfil se analiza y se aplica correctamente a AppArmor, no verá ninguna salida y volverá al símbolo del sistema.
Desde la máquina local, cree un manifiesto de pod denominado aks-apparmor.yaml. Este manifiesto:
- Define una anotación para
container.apparmor.security.beta.kubernetes
. - Hace referencia al perfil deny-write creado en los pasos anteriores.
apiVersion: v1 kind: Pod metadata: name: hello-apparmor annotations: container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write spec: containers: - name: hello image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
- Define una anotación para
Con el pod implementado, ejecute el comando siguiente y compruebe que el pod hello-apparmor muestra un estado En ejecución:
kubectl get pods NAME READY STATUS RESTARTS AGE aks-ssh 1/1 Running 0 4m2s hello-apparmor 0/1 Running 0 50s
Para más información sobre AppArmor, consulte los perfiles de AppArmor en Kubernetes.
Informática segura (seccomp)
Si bien AppArmor funciona con cualquier aplicación de Linux, seccomp (secure computing) funciona en el nivel de proceso. Seccomp también es un módulo de seguridad del kernel de Linux, y es compatible de forma nativa con el tiempo de ejecución de containerd
que utilizan los nodos de AKS. Con seccomp, puede limitar las llamadas del sistema de un contenedor. Seccomp establece una capa adicional de protección contra vulnerabilidades comunes de llamadas del sistema explotadas por actores malintencionados y permite especificar un perfil predeterminado para todas las cargas de trabajo del nodo.
Configuración de un perfil de seccomp predeterminado (versión preliminar)
Puede aplicar perfiles de seccomp predeterminados mediante configuraciones de nodo personalizadas al crear un nuevo grupo de nodos de Linux. Hay dos valores admitidos en AKS: RuntimeDefault
y Unconfined
. Algunas cargas de trabajo pueden requerir un número menor de restricciones de syscall que otras. Esto significa que pueden producir errores durante el tiempo de ejecución con el perfil 'RuntimeDefault'. Para mitigar este error, puede especificar el perfil Unconfined
. Si la carga de trabajo requiere un perfil personalizado, consulte Configuración de un perfil de seccomp personalizado.
Limitaciones
- SeccompDefault no es un parámetro compatible para los grupos de nodos de Windows.
- SeccompDefault está disponible a partir de la API 2024-09-02-preview.
Importante
Las características en versión preliminar de AKS están disponibles como opción de participación y autoservicio. Las versiones preliminares se proporcionan "tal cual" y "como están disponibles", y están excluidas de los Acuerdos de nivel de servicio y garantía limitada. Las versiones preliminares de AKS reciben cobertura parcial del soporte al cliente en la medida de lo posible. Por lo tanto, estas características no están diseñadas para su uso en producción. Para más información, consulte los siguientes artículos de soporte:
Registro de la marca de característica KubeletDefaultSeccompProfilePreview
Registre la marca de características de
KubeletDefaultSeccompProfilePreview
mediante el comandoaz feature register
.az feature register --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
Tarda unos minutos en que el estado muestre Registrado.
Comprobar el estado del registro mediante el comando
az feature show
.az feature show --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
Cuando aparezca el estado Registrado, actualice el registro del proveedor de recursos Microsoft.ContainerService mediante el comando
az provider register
.az provider register --namespace Microsoft.ContainerService
Restricción de las llamadas del sistema del contenedor con seccomp
1. Siga los pasos para aplicar un perfil de seccomp en la configuración de kubelet especificando "seccompDefault": "RuntimeDefault"
.
RuntimeDefault
usa el perfil de seccomp predeterminado del contenedor, lo que restringe determinadas llamadas del sistema para mejorar la seguridad. Se producirá un error en las llamadas del sistema restringidas. Para más información, consulte el perfil seccomp predeterminado de containerD.
2. Compruebe que se aplicó la configuración .
Puede confirmar que la configuración se ha aplicado a los nodos mediante la conexión al host y la comprobación de que los cambios de configuración se han realizado en el sistema de archivos.
3. Solución de errores de carga de trabajo.
Cuando SeccompDefault está habilitado, el perfil de seccomp predeterminado del entorno de ejecución del contenedor se usa de forma predeterminada para todas las cargas de trabajo programadas en el nodo. Esto puede provocar un error en las cargas de trabajo debido a llamadas de syscall bloqueadas. Si se ha producido un error de carga de trabajo, es posible que vea errores como:
- La carga de trabajo existe inesperadamente después de habilitar la característica, con el error "permiso denegado".
- Los mensajes de error de Seccomp también se pueden ver en auditado o syslog reemplazando SCMP_ACT_ERRNO por SCMP_ACT_LOG en el perfil predeterminado.
Si experimenta los errores anteriores, se recomienda cambiar el perfil de seccomp a Unconfined
. Unconfined
no aplica restricciones a las llamadas sys, lo que permite todas las llamadas del sistema, lo que reduce la seguridad.
Configuración de un perfil de seccomp personalizado
Con un perfil de seccomp personalizado, puede tener un control más granular sobre las llamadas de sys restringidas. Adopte el procedimiento recomendado de conceder al contenedor el permiso mínimo solo para ejecutarlo mediante:
- La definición que filtra qué acciones se permiten o deniegan.
- La anotación dentro de un manifiesto YAML de pod para asociarlo al filtro de seccomp.
Para ver seccomp en acción, cree un filtro que evite el cambio de permisos en un archivo.
Acceda mediante SSH a un nodo de AKS.
Cree un filtro de seccomp denominado /var/lib/kubelet/seccomp/prevent-chmod.
Copie y pegue el siguiente contenido:
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "name": "chmod", "action": "SCMP_ACT_ERRNO" }, { "name": "fchmodat", "action": "SCMP_ACT_ERRNO" }, { "name": "chmodat", "action": "SCMP_ACT_ERRNO" } ] }
En la versión 1.19 y versiones posteriores, debe configurar:
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "names": ["chmod","fchmodat","chmodat"], "action": "SCMP_ACT_ERRNO" } ] }
En la máquina local, cree un manifiesto de pod denominado aks-seccomp.yaml y pegue el contenido siguiente. Este manifiesto:
- Define una anotación para
seccomp.security.alpha.kubernetes.io
. - Hace referencia al filtro prevent-chmod que se creó en el paso anterior.
apiVersion: v1 kind: Pod metadata: name: chmod-prevented annotations: seccomp.security.alpha.kubernetes.io/pod: localhost/prevent-chmod spec: containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: Never
En la versión 1.19 y versiones posteriores, debe configurar:
apiVersion: v1 kind: Pod metadata: name: chmod-prevented spec: securityContext: seccompProfile: type: Localhost localhostProfile: prevent-chmod containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: Never
- Define una anotación para
Implemente el pod de ejemplo con el comando kubectl apply:
kubectl apply -f ./aks-seccomp.yaml
Consulte el estado de los pod mediante el comando kubectl get pods.
- El pod indica un error.
- El filtro seccomp impide que se ejecute el comando
chmod
, tal como se muestra en la salida del ejemplo:
kubectl get pods NAME READY STATUS RESTARTS AGE chmod-prevented 0/1 Error 0 7s
Opciones de perfil de seguridad de Seccomp
Los perfiles de seguridad de Seccomp son un conjunto de llamadas syscall definidas permitidas o restringidas. La mayoría de los entornos de ejecución de contenedor tienen un perfil de seccomp predeterminado similar si no es el mismo que el que usa Docker. Para obtener más información sobre los perfiles disponibles, consulte Perfiles de seccomp predeterminados de Docker o containerD.
AKS usa el perfil de seccomp predeterminado containerD para RuntimeDefault al configurar seccomp mediante la configuración de nodo personalizada.
Llamadas de syscall significativas bloqueadas por perfil predeterminado
Tanto Docker como containerD mantienen listas de permitidos de llamadas seguras de syscalls. En esta tabla se enumeran las llamadas de sistema significativas (pero no todas) que están bloqueadas de forma eficaz porque no están en la lista de permitidos. Si la carga de trabajo requiere alguna de las llamadas de syscall bloqueadas, no use el perfil de seccomp RuntimeDefault
.
Cuando se realizan cambios en Docker y containerD, AKS actualiza su configuración predeterminada para que coincida. Las actualizaciones de esta lista pueden provocar un error en la carga de trabajo. Para obtener actualizaciones de versión, consulte las notas de la versión de AKS.
Llamada syscall bloqueada | Descripción |
---|---|
acct |
Syscall de contabilidad que podría permitir que los contenedores deshabiliten sus propios límites de recursos o contabilidad de procesos. También está cerrado por CAP_SYS_PACCT . |
add_key |
Impedir que los contenedores usen el keyring de kernel, que no tiene espacio de nombres. |
bpf |
Deniegue la carga de programas bpf potencialmente persistentes en kernel, que ya está controlada por CAP_SYS_ADMIN . |
clock_adjtime |
La hora y la fecha no tienen espacio de nombres. También está cerrado por CAP_SYS_TIME . |
clock_settime |
La hora y la fecha no tienen espacio de nombres. También está cerrado por CAP_SYS_TIME . |
clone |
Denegar la clonación de nuevos espacios de nombres. También se ha cerrado por marcas CAP_SYS_ADMIN for CLONE_* , excepto CLONE_NEWUSER . |
create_module |
Denegar la manipulación y las funciones en los módulos de kernel. Obsoleto. También está cerrado por CAP_SYS_MODULE . |
delete_module |
Denegar la manipulación y las funciones en los módulos de kernel. También está cerrado por CAP_SYS_MODULE . |
finit_module |
Denegar la manipulación y las funciones en los módulos de kernel. También está cerrado por CAP_SYS_MODULE . |
get_kernel_syms |
Denegar la recuperación de símbolos de módulo y kernel exportados. Obsoleto. |
get_mempolicy |
Syscall que modifica la memoria del kernel y la configuración de NUMA. Ya está cerrado por CAP_SYS_NICE . |
init_module |
Denegar la manipulación y las funciones en los módulos de kernel. También está cerrado por CAP_SYS_MODULE . |
ioperm |
Impedir que los contenedores modifiquen los niveles de privilegios de E/S del kernel. Ya está cerrado por CAP_SYS_RAWIO . |
iopl |
Impedir que los contenedores modifiquen los niveles de privilegios de E/S del kernel. Ya está cerrado por CAP_SYS_RAWIO . |
kcmp |
Restrinja las funcionalidades de inspección de procesos, ya bloqueadas quitando CAP_SYS_PTRACE . |
kexec_file_load |
Syscall hermana de kexec_load que hace lo mismo, argumentos ligeramente diferentes. También está cerrado por CAP_SYS_BOOT . |
kexec_load |
Denegar la carga de un nuevo kernel para su ejecución posterior. También está cerrado por CAP_SYS_BOOT . |
keyctl |
Impedir que los contenedores usen el keyring de kernel, que no tiene espacio de nombres. |
lookup_dcookie |
Seguimiento o generación de perfiles de syscall, que podría filtrar información sobre el host. También está cerrado por CAP_SYS_ADMIN . |
mbind |
Syscall que modifica la memoria del kernel y la configuración de NUMA. Ya está cerrado por CAP_SYS_NICE . |
mount |
Deniegue el montaje, ya cerrado por CAP_SYS_ADMIN . |
move_pages |
Syscall que modifica la memoria del kernel y la configuración de NUMA. |
nfsservctl |
Denegar la interacción con el demonio nfs del kernel. Obsoleto desde Linux 3.1. |
open_by_handle_at |
Causa de un error de contenedor antiguo. También está cerrado por CAP_DAC_READ_SEARCH . |
perf_event_open |
Seguimiento o generación de perfiles de syscall, que podría filtrar información sobre el host. |
personality |
Impedir que el contenedor habilite la emulación de BSD. No es intrínsecamente peligroso, pero poco probado, potencial para las vulnerabilidades de kernel. |
pivot_root |
Denegar pivot_root, debe ser una operación con privilegios. |
process_vm_readv |
Restrinja las funcionalidades de inspección de procesos, ya bloqueadas quitando CAP_SYS_PTRACE . |
process_vm_writev |
Restrinja las funcionalidades de inspección de procesos, ya bloqueadas quitando CAP_SYS_PTRACE . |
ptrace |
Llamada syscall de seguimiento y generación de perfiles. Bloqueado en las versiones del kernel de Linux anteriores a la versión 4.8 para evitar la omisión de seccomp. Los procesos arbitrarios de seguimiento o generación de perfiles ya están bloqueados quitando CAP_SYS_PTRACE, ya que podría perder información en el host. |
query_module |
Denegar la manipulación y las funciones en los módulos de kernel. Obsoleto. |
quotactl |
Syscall de cuota que podría permitir que los contenedores deshabiliten sus propios límites de recursos o la contabilidad de procesos. También está cerrado por CAP_SYS_ADMIN . |
reboot |
No permita que los contenedores reinicien el host. También está cerrado por CAP_SYS_BOOT . |
request_key |
Impedir que los contenedores usen el keyring de kernel, que no tiene espacio de nombres. |
set_mempolicy |
Syscall que modifica la memoria del kernel y la configuración de NUMA. Ya está cerrado por CAP_SYS_NICE . |
setns |
Denegar la asociación de un subproceso con un espacio de nombres. También está cerrado por CAP_SYS_ADMIN . |
settimeofday |
La hora y la fecha no tienen espacio de nombres. También está cerrado por CAP_SYS_TIME . |
stime |
La hora y la fecha no tienen espacio de nombres. También está cerrado por CAP_SYS_TIME . |
swapon |
Denegar el inicio o detención del intercambio a archivo o dispositivo. También está cerrado por CAP_SYS_ADMIN . |
swapoff |
Denegar el inicio o detención del intercambio a archivo o dispositivo. También está cerrado por CAP_SYS_ADMIN . |
sysfs |
Syscall obsoleta. |
_sysctl |
Obsoleto, reemplazado por /proc/sys. |
umount |
Debe ser una operación con privilegios. También está cerrado por CAP_SYS_ADMIN . |
umount2 |
Debe ser una operación con privilegios. También está cerrado por CAP_SYS_ADMIN . |
unshare |
Denegar la clonación de nuevos espacios de nombres para procesos. También se ha cerrado por CAP_SYS_ADMIN , con la excepción de unshare --user. |
uselib |
La llamada de syscall anterior relacionada con las bibliotecas compartidas, sin usar durante mucho tiempo. |
userfaultfd |
Control de errores de página de espacio de usuarios, en gran medida necesario para la migración de procesos. |
ustat |
Syscall obsoleta. |
vm86 |
En la máquina virtual en modo real de kernel x86. También está cerrado por CAP_SYS_ADMIN . |
vm86old |
En la máquina virtual en modo real de kernel x86. También está cerrado por CAP_SYS_ADMIN . |
Pasos siguientes
Para los procedimientos recomendados asociados, consulte Procedimientos recomendados para la seguridad de clústeres y las actualizaciones en AKS y Procedimientos recomendados para la seguridad de pod en AKS.
Azure Kubernetes Service