Protección del clúster con directivas de seguridad de pod en Azure Kubernetes Service (AKS) (versión preliminar)

Importante

La característica de directivas de seguridad de pods quedó en desuso el 1 de agosto de 2023 y se quitó de las versiones 1.25 y posteriores de AKS.

Se recomienda migrar al controlador de admisión de seguridad de pod o a Azure Policy para mantenerse en el soporte de Azure. La admisión de seguridad de pods es una solución de directiva integrada para implementaciones de clúster único. Si busca una directiva de nivel empresarial, Azure Policy es una mejor opción.

Antes de empezar

  • Este artículo supone que ya tiene un clúster de AKS. Si necesita un clúster de AKS, cree uno mediante la CLI de Azure, Azure PowerShell o Azure Portal.
  • Es preciso que esté instalada y configurada la versión 2.0.61 de la CLI de Azure u otra versión posterior. Ejecute az --version para encontrar la versión. Si necesita instalarla o actualizarla, consulte Instalación de la CLI de Azure.

Instalación de la extensión de la CLI de Azure aks-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 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:

  1. Instale la extensión aks-preview mediante el comando az extension add.

    az extension add --name aks-preview
    
  2. Actualiza a la última versión de la extensión mediante el comando az extension update.

    az extension update --name aks-preview
    

Registro de la marca de característica PodSecurityPolicyPreview

  1. Registre la marca de características de PodSecurityPolicyPreview mediante el comando az feature register.

    az feature register --namespace "Microsoft.ContainerService" --name "PodSecurityPolicyPreview"
    

    Tarda unos minutos en que el estado muestre Registrado.

  2. Comprobar el estado del registro mediante el comando az feature show.

    az feature show --namespace "Microsoft.ContainerService" --name "PodSecurityPolicyPreview"
    
  3. 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
    

Introducción a las directivas de seguridad de pod

En los clústeres de Kubernetes se usa un controlador de admisión para interceptar las solicitudes al servidor de API cuando se va a crear un recurso. El controlador de admisión puede validar la solicitud del recurso con un conjunto de reglas, o mutar el recurso para cambiar los parámetros de implementación.

PodSecurityPolicy es un controlador de admisión que valida si una especificación de pod cumple los requisitos definidos. Estos pueden incluir el límite del uso de contenedores con privilegios, del acceso a ciertos tipos de almacenamiento, o del usuario o grupo que puede ejecutar el contenedor. Al intentar implementar un recurso donde las especificaciones de pod no cumplan los requisitos descritos en la directiva de seguridad de pod, la solicitud se deniega. Esta capacidad para controlar qué pods se pueden programar en el clúster de AKS evita algunos puntos vulnerables de seguridad o elevaciones de privilegios.

Al habilitar la directiva de seguridad de pod en el clúster de AKS, se aplican algunas directivas predeterminadas. Estas directivas permiten de forma inmediata definir qué pods que se pueden programar. Sin embargo, puede encontrarse con problemas al implementar los pods hasta que defina sus propias directivas. El método recomendado es el siguiente:

  1. Cree un clúster de AKS.
  2. Definición de directivas de seguridad de pod propias.
  3. Habilitación de la característica de directiva de seguridad de pod.

El comportamiento cambia entre la directiva de seguridad de pod y Azure Policy

Escenario Directiva de seguridad de pod Azure Policy
Instalación Habilitar la característica de directiva de seguridad de pod Habilitar el complemento de Azure Policy
Implementar directivas Implementar el recurso de la directiva de seguridad de pod Asigne las directivas de Azure al ámbito de la suscripción o del grupo de recursos. El complemento de Azure Policy es necesario para las aplicaciones de recursos de Kubernetes.
Directivas predeterminadas Cuando la directiva de seguridad de pod está habilitada en AKS, se aplican las directivas predeterminadas Con privilegios y Sin restricciones. No se aplica ninguna directiva predeterminada al habilitar el complemento de Azure Policy. Debe habilitar explícitamente las directivas en Azure Policy.
Quién puede crear y asignar directivas El administrador del clúster crea un recurso de directiva de seguridad de pod Los usuarios deben tener un rol mínimo con permisos de "propietario" o "colaborador de directiva de recursos" en el grupo de recursos del clúster de AKS. - Mediante la API, los usuarios pueden asignar directivas en el ámbito del recurso del clúster de AKS. El usuario debe tener permisos mínimos de "propietario" o "colaborador de directiva de recursos" en el recurso del clúster de AKS. - En Azure Portal, las directivas se pueden asignar en el nivel de grupo de administración, suscripción o grupo de recursos.
Autorizar directivas Los usuarios y las cuentas de servicio requieren permisos explícitos para usar las directivas de seguridad de pod. No se requiere ninguna asignación adicional para autorizar directivas. Una vez que se han asignado las directivas en Azure, todos los usuarios del clúster pueden usar estas directivas.
Aplicabilidad de las directivas El usuario administrador está exento del cumplimiento de las directivas de seguridad de pod. Todos los usuarios (administrador y no administrador) ven las mismas directivas. No hay una diferenciación especial basada en los usuarios. La aplicación de las directivas se puede excluir en el nivel de espacio de nombres.
Ámbito de la directiva Las directivas de seguridad de pod no tienen espacios de nombres Las plantillas de restricción usadas por Azure Policy no tienen espacios de nombres.
Acción de denegación/auditoría/mutación Las directivas de seguridad de pod solo admiten acciones de denegación. La mutación se puede realizar con valores predeterminados en las solicitudes de creación. La validación se puede realizar durante las solicitudes de actualización. Azure Policy admite las acciones de denegación y de auditoría. La mutación no se admite aún.
Cumplimiento de la directiva de seguridad de pod No hay visibilidad del cumplimiento de los pods que existían antes de habilitar la directiva de seguridad de pod. Los pods no compatibles creados después de habilitar las directivas de seguridad de pod se deniegan. Los pods no compatibles que existían antes de aplicar las directivas de Azure se mostrarían en infracciones de directivas. Los pods no compatibles creados después de habilitar las directivas de Azure se deniegan si las directivas se establecen con efecto de denegación.
Cómo ver las directivas del clúster kubectl get psp kubectl get constrainttemplate : devuelve todas las directivas.
Directiva de seguridad de pod estándar: con privilegios De forma predeterminada, se crea un recurso de directiva de seguridad de pod con privilegios al habilitar la característica. El modo con privilegios no implica ninguna restricción, por tanto, es equivalente a no tener ninguna asignación de Azure Policy.
Directiva de seguridad de pod estándar: línea de base/predeterminada El usuario instala un recurso de línea de base de la directiva de seguridad de pod. Azure Policy proporciona una iniciativa de línea de base integrada que se asigna a la directiva de seguridad de pod de línea de base.
Directiva de seguridad de pod estándar: restringida El usuario instala un recurso restringido de la directiva de seguridad de pod. Azure Policy proporciona una iniciativa restringida integrada que se asigna a la directiva de seguridad de pod de restringida.

Habilitación de una directiva de seguridad de pod en un clúster de AKS

Nota

Para el uso en el mundo real, no habilite la directiva de seguridad de pod hasta que haya definido sus propias directivas personalizadas. En este artículo se habilita la directiva de seguridad de pod como primer paso para mostrar cómo las directivas predeterminadas limitan la implementación de pods.

  • Habilite la directiva de seguridad del pod mediante el comando az aks update.

    az aks update \
        --resource-group myResourceGroup \
        --name myAKSCluster \
        --enable-pod-security-policy
    

Directivas predeterminadas de AKS

Cuando se habilita la directiva de seguridad pod, AKS crea una directiva predeterminada denominada privileged. No modifique ni elimine la directiva predeterminada. En su lugar, cree sus propias directivas que definan la configuración que desee controlar. Primero echemos un vistazo a qué son estas directivas predeterminadas y a cómo afectan a la implementación de pods.

  1. Vea las directivas disponibles mediante el comando kubectl get psp.

    kubectl get psp
    

    El resultado será similar al siguiente ejemplo:

    NAME         PRIV    CAPS   SELINUX    RUNASUSER          FSGROUP     SUPGROUP    READONLYROOTFS   VOLUMES
    privileged   true    *      RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            *     configMap,emptyDir,projected,secret,downwardAPI,persistentVolumeClaim
    

    La directiva de seguridad de pod provileged se aplica a cualquier usuario que se autentique en el clúster de AKS. Esta asignación se controla mediante ClusterRoles y ClusterRoleBindings.

  2. Busque el enlace default:privileged: en el espacio de nombres kube-system mediante el comando kubectl get rolebindings.

    kubectl get rolebindings default:privileged -n kube-system -o yaml
    

    Como se muestra en el siguiente ejemplo condensado, psp:privilegedClusterRole se asigna a cualquier usuario system:authenticated. Esta capacidad proporciona un nivel básico de privilegio sin tener directivas propias definidas.

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      [...]
      name: default:privileged
      [...]
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: psp:privileged
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: Group
      name: system:masters
    

Es importante entender cómo interactúan estas directivas predeterminadas con las solicitudes de usuario para programar los pods antes de empezar a crear directivas de seguridad de pod propias. En las siguientes secciones programaremos algunos pods para ver estas directivas predeterminadas en acción.

Creación de un usuario de prueba en un clúster de AKS

Al usar el comando az aks get-credentials, las credenciales del administrador para el clúster de AKS se agregan a la configuración de kubectl de manera predeterminada. El usuario administrador está exento del cumplimiento de las directivas de seguridad de pod. Si usa la integración de Microsoft Entra para los clústeres de AKS, podría iniciar sesión con las credenciales de un usuario que no sea administrador para ver el cumplimiento de directivas en acción.

  1. Cree un espacio de nombres de ejemplo denominado psp-aks para probar los recursos con el comando kubectl create namespace.

    kubectl create namespace psp-aks
    
  2. Cree una cuenta de servicio denominada nonadmin-user mediante el comando kubectl create serviceaccount.

    kubectl create serviceaccount --namespace psp-aks nonadmin-user
    
  3. Cree un RoleBinding para nonadmin-user con el fin de realizar acciones básicas en el espacio de nombres mediante el comando kubectl create rolebinding.

    kubectl create rolebinding \
        --namespace psp-aks \
        psp-aks-editor \
        --clusterrole=edit \
        --serviceaccount=psp-aks:nonadmin-user
    

Creación de comandos de alias para los usuarios administrador y no administrador

Al usar kubectl, puede resaltar las diferencias entre el usuario administrador normal y el usuario que no es administrador mediante la creación de dos alias de línea de comandos:

  1. El alias kubectl-admin es para el usuario administrador normal, cuyo ámbito se extiende al espacio de nombres psp-aks.
  2. El alias kubectl nonadminuser es para el usuario no administrador creado en el paso anterior, para el espacio de nombres psp-aks.
  • Cree los dos alias con los siguientes comandos.

    alias kubectl-admin='kubectl --namespace psp-aks'
    alias kubectl-nonadminuser='kubectl --as=system:serviceaccount:psp-aks:nonadmin-user --namespace psp-aks'
    

Prueba de la creación de un pod con privilegios

Vamos a probar lo que sucede cuando se programa un pod con el contexto de seguridad de privileged: true. Este contexto de seguridad eleva los privilegios del pod. La directiva de seguridad de AKS con privilegios predeterminada debe denegar esta solicitud.

  1. Cree un archivo denominado nginx-privileged.yaml y pegue el contenido del siguiente manifiesto de YAML.

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-privileged
    spec:
      containers:
        - name: nginx-privileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.14.2-alpine
          securityContext:
            privileged: true
    
  2. Cree el pod con el comando kubectl apply y especifique el nombre de su manifiesto de YAML.

    kubectl-nonadminuser apply -f nginx-privileged.yaml
    

    En la salida de ejemplo siguiente se muestra que el pod no se pudo programar:

    Error from server (Forbidden): error when creating "nginx-privileged.yaml": pods "nginx-privileged" is forbidden: unable to validate against any pod security policy: []
    

    Dado que el pod no llega a la fase de programación, no hay recursos que eliminar para continuar.

Prueba de la creación de un pod sin privilegios

En el ejemplo anterior, la especificación del pod solicitaba el escalado de privilegios. Esta solicitud la deniega la directiva de seguridad de pod privilege predeterminada, por lo que no se puede programar el pod. Vamos a probar ahora a ejecutar ese mismo pod NGINX sin la solicitud de elevación de privilegios.

  1. Cree un archivo denominado nginx-unprivileged.yaml y pegue el contenido del siguiente manifiesto de YAML.

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-unprivileged
    spec:
      containers:
        - name: nginx-unprivileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.14.2-alpine
    
  2. Cree el pod con el comando kubectl apply y especifique el nombre de su manifiesto de YAML.

    kubectl-nonadminuser apply -f nginx-unprivileged.yaml
    

    En la salida de ejemplo siguiente se muestra que el pod no se pudo programar:

    Error from server (Forbidden): error when creating "nginx-unprivileged.yaml": pods "nginx-unprivileged" is forbidden: unable to validate against any pod security policy: []
    

    Dado que el pod no llega a la fase de programación, no hay recursos que eliminar para continuar.

Creación de prueba de un pod con un contexto de usuario específico

En el ejemplo anterior la imagen de contenedor intentó automáticamente utilizar la raíz para enlazar NGINX al puerto 80. Esta solicitud la denegó la directiva de seguridad de pod privilege predeterminada, por lo que no se puede iniciar el pod. Probemos ahora a ejecutar ese mismo pod NGINX con un contexto de usuario específico, como runAsUser: 2000.

  1. Cree un archivo denominado nginx-unprivileged-nonroot.yaml y pegue el siguiente manifiesto de YAML.

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-unprivileged-nonroot
    spec:
      containers:
        - name: nginx-unprivileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.14.2-alpine
          securityContext:
            runAsUser: 2000
    
  2. Cree el pod con el comando kubectl apply y especifique el nombre de su manifiesto de YAML.

    kubectl-nonadminuser apply -f nginx-unprivileged-nonroot.yaml
    

    En la salida de ejemplo siguiente se muestra que el pod no se pudo programar:

    Error from server (Forbidden): error when creating "nginx-unprivileged-nonroot.yaml": pods "nginx-unprivileged-nonroot" is forbidden: unable to validate against any pod security policy: []
    

    Dado que el pod no llega a la fase de programación, no hay recursos que eliminar para continuar.

Creación de una directiva de seguridad de pod personalizada

Ahora que hemos visto el comportamiento de las directivas de seguridad de pod predeterminadas, vamos a proporcionar una forma para que el usuario no administrador pueda programar pods.

Vamos a crear una directiva para rechazar los pods que soliciten acceso con privilegios. Otras opciones, como runAsUser o los volúmenes permitidos, no se restringen explícitamente. Este tipo de directiva deniega una solicitud de acceso con privilegios, pero permite al clúster ejecutar los pods solicitados.

  1. Cree un archivo denominado psp-deny-privileged.yaml y pegue el siguiente manifiesto de YAML.

    apiVersion: policy/v1beta1
    kind: PodSecurityPolicy
    metadata:
      name: psp-deny-privileged
    spec:
      privileged: false
      seLinux:
        rule: RunAsAny
      supplementalGroups:
        rule: RunAsAny
      runAsUser:
        rule: RunAsAny
      fsGroup:
        rule: RunAsAny
      volumes:
     - '*'
    
  2. Cree la directiva con el comando kubectl apply y especifique el nombre de su manifiesto de YAML.

    kubectl apply -f psp-deny-privileged.yaml
    
  3. Vea las directivas disponibles mediante el comando kubectl get psp.

    kubectl get psp
    

    En el siguiente ejemplo, compare la directiva psp-deny-privileged con el valor de la directiva privilege predeterminada que aplicó en los ejemplos anteriores para crear un pod. Su directiva solo deniega el uso del escalado PRIV. No hay ninguna restricción para el usuario o grupo relativa a la directiva psp-deny-privileged.

    NAME                  PRIV    CAPS   SELINUX    RUNASUSER          FSGROUP     SUPGROUP    READONLYROOTFS   VOLUMES
    privileged            true    *      RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            *
    psp-deny-privileged   false          RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            *          
    

Permiso par que la cuenta de usuario use la directiva de seguridad de pod personalizada

En el paso anterior ha creado una directiva de seguridad de pod para rechazar los pods que soliciten acceso con privilegios. Para permitir el uso de la directiva, cree un rol o ClusterRole. Asocie uno de estos roles mediante RoleBinding o ClusterRoleBinding. Para este ejemplo, crearemos un ClusterRole que le permita usar la directiva psp-deny-privileged que creó en el paso anterior.

  1. Cree un archivo denominado psp-deny-privileged-clusterrole.yaml y pegue el siguiente manifiesto de YAML.

    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: psp-deny-privileged-clusterrole
    rules:
    - apiGroups:
      - extensions
       resources:
      - podsecuritypolicies
       resourceNames:
      - psp-deny-privileged
       verbs:
      - use
    
  2. Cree el ClusterRole mediante el comando kubectl apply y especifique el nombre de su manifiesto de YAML.

    kubectl apply -f psp-deny-privileged-clusterrole.yaml
    
  3. Cree un archivo denominado psp-deny-privileged-clusterrolebinding.yaml y pegue el siguiente manifiesto de YAML.

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: psp-deny-privileged-clusterrolebinding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: psp-deny-privileged-clusterrole
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: Group
      name: system:serviceaccounts
    
  4. Cree un ClusterRoleBinding mediante el comando kubectl apply y especifique el nombre del manifiesto de YAML.

    kubectl apply -f psp-deny-privileged-clusterrolebinding.yaml
    

Nota

En el primer paso de este artículo se ha habilitado la característica de directiva de seguridad de pod en el clúster de AKS. El método recomendado era habilitar solo la característica de directiva de seguridad de pod una vez definidas las directivas propias. Esta es la fase en la que habilitaría la característica de directiva de seguridad de pod. Se han definido una o varias directivas personalizadas y las cuentas de usuario se han asociado a esas directivas. Ahora puede habilitar la característica de directiva de seguridad de pod sin problemas y reducir los problemas causados por las directivas predeterminadas.

Segunda prueba de creación de un pod sin privilegios

Con la directiva de seguridad de pod personalizada aplicado y un enlace para la cuenta de usuario para que use la directiva, vamos a intentar volver a crear un pod sin privilegios.

En este ejemplo se muestra cómo crear directivas de seguridad de pod personalizadas para definir el acceso al clúster de AKS para distintos usuarios o grupos. Las directivas de AKS predeterminadas proporcionan controles estrictos sobre lo que los pods pueden ejecutar, por lo tanto, cree sus propias directivas personalizadas para definir las restricciones que necesite correctamente.

  1. Use el manifiesto nginx-privileged.yaml para crear el pod mediante el comando kubectl apply.

    kubectl-nonadminuser apply -f nginx-unprivileged.yaml
    
  2. Compruebe el estado del pod con el comando kubectl get pods.

    kubectl-nonadminuser get pods
    

    En la salida de ejemplo siguiente se muestra que el pod se ha programado correctamente y está en ejecución:

    NAME                 READY   STATUS    RESTARTS   AGE
    nginx-unprivileged   1/1     Running   0          7m14s
    
  3. Elimine el pod NGIX sin privilegios mediante el comando kubectl delete y especifique el nombre del manifiesto de YAML.

    kubectl-nonadminuser delete -f nginx-unprivileged.yaml
    

Limpieza de recursos

  1. Deshabilite la directiva de seguridad de pod con el comando az aks update.

    az aks update \
        --resource-group myResourceGroup \
        --name myAKSCluster \
        --disable-pod-security-policy
    
  2. Elimine ClusterRole y ClusterRoleBinding con el comando kubectl delete.

    kubectl delete -f psp-deny-privileged-clusterrole.yaml
    
  3. Elimine ClusterRoleBinding con el comando kubectl delete.

    kubectl delete -f psp-deny-privileged-clusterrolebinding.yaml
    
  4. Elimine la directiva de seguridad mediante el comando kubectl delete y especifique el nombre del manifiesto de YAML.

    kubectl delete -f psp-deny-privileged.yaml
    
  5. Elimine el espacio de nombres psp-aks mediante el comando kubectl delete.

    kubectl delete namespace psp-aks
    

Pasos siguientes

En este artículo se ha explicado cómo crear una directiva de seguridad de pod para evitar el acceso con privilegios. Las directivas pueden aplicar muchas características, como el tipo de volumen o el usuario RunAs. Para más información sobre las opciones disponibles, consulte los documentos de referencia de la directiva de seguridad de pod de Kubernetes.

Para más información sobre la limitación del tráfico del pod, consulte Protección del tráfico entre pods mediante directivas de red en Azure Kubernetes Service (AKS).