Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo, aprenderá a proteger el acceso de contenedores a los recursos de las cargas de trabajo de Azure Kubernetes Service (AKS) mediante los espacios de nombres de usuario, AppArmor y las características de seguridad integradas de Linux.
Información general sobre la seguridad del acceso al contenedor
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 mejorar el aislamiento del host y reducir el movimiento lateral en Linux, puede usar espacios de nombres de usuario. 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. Estas características le ayudan a limitar las acciones que los contenedores pueden realizar mediante la definición de características de seguridad de Linux en el nivel de nodo y su implementación a través de 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, espacios de nombres de usuario, Pod Security Admission o Control de acceso basado en roles de Kubernetes (RBAC) para nodos, bloquean eficazmente los exploits.
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.
Requisitos previos para espacios de nombres de usuario
- Un clúster de AKS existente Si no dispone de un clúster, cree uno mediante Azure CLI, Azure PowerShell o el Azure Portal.
- Versión mínima de Kubernetes 1.33 para el plano de control y los nodos de trabajo. Si no usa la versión 1.33 o posterior de Kubernetes, debe actualizar la versión de Kubernetes.
- Nodos de trabajo que ejecutan Azure Linux 3.0 o Ubuntu 24.04 para asegurarse de que cumple los requisitos mínimos de pila para habilitar espacios de nombres de usuario. Si necesita actualizar la versión del sistema operativo (SO), consulte Actualización de la versión del sistema operativo.
Limitaciones de los espacios de nombres de usuario
- La característica de espacios de nombres de usuario es para el kernel de Linux y no es compatible con los grupos de nodos de Windows.
- Consulte la documentación de Kubernetes sobre espacios de nombres de usuario para cualquier otra limitación.
Información general sobre los espacios de nombres de usuario
Los pods de Linux se ejecutan con varios espacios de nombres de forma predeterminada: espacios de nombres de red para aislar la identidad de red y un espacio de nombres PID para aislar los procesos. Un espacio de nombres de usuario (user_namespace) aísla a los usuarios dentro del contenedor de los usuarios del host. También limita el ámbito de las funcionalidades y las interacciones del pod con el resto del sistema.
Los uid y los gid dentro del contenedor se asignan a usuarios sin privilegios en el host, por lo que toda la interacción con el resto del host se produce como esos uid y gid sin privilegios. Por ejemplo, la raíz dentro del contenedor (UID 0) se puede asignar al usuario 65536 en el host. Kubernetes crea la asignación para garantizar que no se superpone con otros pods mediante espacios de nombres de usuario en el sistema.
La implementación de Kubernetes tiene algunas ventajas clave. Para obtener más información, consulte la documentación de Espacios de Nombres de Usuario de Kubernetes.
Habilitar espacios de nombres de usuario
Cree un archivo denominado
mypod.yamly cópielo en el siguiente código manifiesto. Para usar espacios de nombres de usuario, YAML debe tener el campohostUsers: false.apiVersion: v1 kind: Pod metadata: name: userns spec: hostUsers: false containers: - name: shell command: ["sleep", "infinity"] image: debianImplemente la aplicación mediante el comando
kubectl applyy especifique el nombre del manifiesto de YAML.kubectl apply -f mypod.yamlCompruebe el estado de los pods implementados con el comando
kubectl get pods.kubectl get podsEjecute en el pod usando el comando
kubectl exec.kubectl exec -ti userns -- bashDentro del pod, compruebe
/proc/self/uid_mapcon el comando siguiente:cat /proc/self/uid_mapLa salida debe tener 65536 en la última columna. Por ejemplo:
0 833617920 65536Esta salida indica que la raíz dentro del contenedor (UID 0) se asigna al usuario 65536 en el host.
Vulnerabilidades y exposiciones comunes (CVEs) mitigadas por espacios de nombres de usuario
En la tabla siguiente se describen algunas vulnerabilidades y exposiciones comunes (ECV) que se mitigan parcialmente o totalmente mediante user_namespaces:
| CVE | Puntuación de gravedad | Nivel de gravedad |
|---|---|---|
| CVE-2019-5736 | 8.6 | High |
| CVE 2024-21262 | 8.6 | High |
| CVE 2022-0492 | 7,8 | High |
| CVE-2021-25741 | 8.1 / 8.8 | Alto/Alto |
| CVE-2017-1002101 | 9.6 / 8.8 | Crítico/Alto |
Tenga en cuenta que esta lista no es exhaustiva. Para más información, consulte Kubernetes v1.33: Espacios de nombres de usuario habilitados de forma predeterminada.
Requisitos previos de AppArmor
- Un clúster de AKS existente Si no dispone de un clúster, cree uno mediante Azure CLI, Azure PowerShell o el Azure Portal.
Nota:
Azure Linux 3.0 admite AppArmor a partir del lanzamiento de VHD del 7 de noviembre de 2025.
Introducción a 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 sistema operativo (SO) del nodo de AKS subyacente y está habilitado de forma predeterminada. Puede crear perfiles de AppArmor que restrinjan las acciones de lectura, escritura o ejecución, o funciones del sistema como el montaje de 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.
Nota:
Antes de Kubernetes v1.30, AppArmor se especificó mediante anotaciones. A partir de la versión 1.30, AppArmor se especifica a través del campo securityContext de la especificación del pod. Para más información, consulte la documentación de AppArmor de Kubernetes.
Asegurar los pods con AppArmor
Puede especificar perfiles de AppArmor en el nivel de pod o contenedor. El perfil de AppArmor del contenedor tiene prioridad sobre el perfil de AppArmor del pod. Si no se especifica ninguno, el contenedor se ejecuta sin restricciones. Para más información sobre los perfiles de AppArmor, consulte la documentación de Kubernetes sobre la protección de un pod con AppArmor.
Configuración de un perfil personalizado de AppArmor
En el ejemplo siguiente se crea un perfil que impide la escritura en archivos desde un contenedor.
Acceda mediante SSH a un nodo de AKS.
Cree un archivo denominado deny-write.profile 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, }Cargue el perfil de AppArmor en el nodo.
# This example assumes that node names match host names, and are reachable via SSH. NODES=($( kubectl get node -o jsonpath='{.items[*].status.addresses[?(.type == "Hostname")].address}' )) for NODE in ${NODES[*]}; do ssh $NODE 'sudo apparmor_parser -q <<EOF #include <tunables/global> profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { #include <abstractions/base> file, # Deny all file writes. deny /** w, } EOF' done
Despliega un pod con el perfil personalizado de AppArmor
Implemente un pod "Hello AppArmor" con el perfil de denegación de escritura.
apiVersion: v1 kind: Pod metadata: name: hello-apparmor spec: securityContext: appArmorProfile: type: Localhost localhostProfile: k8s-apparmor-example-deny-write containers: - name: hello image: busybox:1.28 command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]Aplique el manifiesto del pod mediante el comando
kubectl apply.kubectl apply -f hello-apparmor.yamlEjecute el comando exec en el pod y compruebe que el contenedor se está ejecutando con el perfil de AppArmor.
kubectl exec hello-apparmor -- cat /proc/1/attr/currentLa salida debe mostrar el perfil de AppArmor en uso. Por ejemplo:
k8s-apparmor-example-deny-write (enforce)
Requisitos previos de Seccomp
- Un clúster de AKS existente Si no dispone de un clúster, cree uno mediante Azure CLI, Azure PowerShell o el Azure Portal.
- Debe registrar la marca de características
KubeletDefaultSeccompProfilePreviewpara usar perfiles de seccomp predeterminados en los grupos de nodos.
Registro de la marca de característica KubeletDefaultSeccompProfilePreview
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 la 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:
Registre la marca de características de
KubeletDefaultSeccompProfilePreviewmediante 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
Limitaciones de Seccomp
- AKS solo admite los perfiles de seccomp predeterminados (
RuntimeDefaultyUnconfined). No se admiten perfiles de seccomp personalizados. -
SeccompDefaultno es un parámetro admitido para los grupos de nodos de Windows.
Introducción a los perfiles de seccomp predeterminados (versión preliminar)
Aunque AppArmor funciona para cualquier aplicación Linux, seccomp (o informática segura) funciona en el nivel de proceso. Seccomp también es un módulo de seguridad de kernel de Linux. El containerd tiempo de ejecución usado por los nodos de AKS proporciona compatibilidad nativa con seccomp. 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.
Puede aplicar perfiles de seccomp predeterminados mediante configuraciones de nodo personalizadas al crear un nuevo grupo de nodos de Linux. AKS admite los RuntimeDefault valores 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.
Restringir las llamadas al sistema de contenedores con seccomp
-
Siga los pasos para aplicar un perfil de seccomp en la configuración de kubelet especificando
"seccompDefault": "RuntimeDefault". - Conéctese al host.
- Compruebe que la configuración se aplicó a los nodos.
Resolución de errores de carga de trabajo con seccomp
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, lo que podría provocar un error en las cargas de trabajo debido a llamadas de syscall bloqueadas. Si se produce un error de carga de trabajo, es posible que vea errores como:
- La tarea se cierra inesperadamente después de activar la función, 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 estos errores, se recomienda cambiar el perfil de seccomp a Unconfined.
Unconfined no aplica restricciones a las llamadas sys, lo que permite ejecutar todas las llamadas del sistema.
Resumen de perfiles de seccomp personalizados
Con un perfil de seccomp personalizado, tiene un control más pormenorizado sobre las llamadas al sistema restringidas para los contenedores. Puede crear sus propios perfiles de seccomp mediante:
- Usar filtros para especificar qué acciones se van a permitir o denegar.
- La anotación dentro de un manifiesto YAML de pod para asociarlo al filtro de seccomp.
Nota:
Para obtener ayuda con la solución de problemas del perfil de seccomp, consulte Solución de problemas de configuración de perfiles de seccomp en Azure Kubernetes Service (AKS).
Configuración de un perfil de seccomp personalizado
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.ioy hace referencia al filtro prevent-chmod existente.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: NeverEn 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: NeverImplemente el pod de ejemplo mediante el
kubectl applycomando :kubectl apply -f ./aks-seccomp.yamlVea el estado del pod mediante el
kubectl get podscomando .kubectl get podsEn la salida, debería ver que el pod notifica un error. El filtro seccomp impide que se ejecute el comando
chmod, tal como se muestra en la salida del ejemplo: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 los perfiles de seccomp predeterminados de Docker o contenedor .
AKS usa el perfil de seccomp predeterminado containerd para RuntimeDefault cuando configuras 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 al sistema. Cuando se realizan cambios en Docker y containerd, AKS actualiza la configuración predeterminada para que esté alineada. 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.
En la tabla siguiente se enumeran las llamadas al sistema importantes que están bloqueadas porque no están en la lista de permitidos. Esta lista no es exhaustiva. Si la carga de trabajo requiere alguna de las syscalls bloqueadas, no use el perfil de seccomp RuntimeDefault.
| Llamada syscall bloqueada | Descripción |
|---|---|
acct |
Syscall de contabilidad, que podría permitir a los contenedores deshabilitar sus propios límites de recursos o la 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 se bloquean al eliminar CAP_SYS_PTRACE, ya que podría filtrar 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 a los contenedores deshabilitar 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 está controlado por CAP_SYS_ADMIN (excepto 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. |
Contenido relacionado
Para más información sobre cómo proteger el clúster de AKS, consulte los artículos siguientes: