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

Advertencia

La característica descrita en este documento, directiva de seguridad de pods (versión preliminar), comenzará a dejar de usar la versión 1.21 de Kubernetes, con su eliminación en la versión 1.25. A medida que Kubernetes Upstream alcanza este hito, la comunidad de Kubernetes trabajará para documentar alternativas viables. El anuncio de desuso anterior se hizo en el momento en que no había una opción viable para los clientes. Ahora que la comunidad Kubernetes está trabajando en una alternativa, ya no es necesario deshacerse por adelantado de Kubernetes.

Una vez que la directiva de seguridad de pod (versión preliminar) haya quedado en desuso, deberá deshabilitar la característica en todos los clústeres existentes que la incluyan para realizar futuras actualizaciones de clústeres y seguir recibiendo el soporte técnico de Azure.

Para mejorar la seguridad del clúster de AKS, puede limitar los pods que se pueden programar. Los pods que soliciten recursos que no permita no podrán ejecutarse en el clúster de AKS. Defina este acceso mediante directivas de seguridad de pod. En este artículo se muestra cómo usar las directivas de seguridad de pod para limitar la implementación de pods en AKS.

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:

Antes de empezar

En este artículo se supone que ya tiene un clúster de AKS. Si necesita un clúster de AKS, consulte el inicio rápido de AKS mediante la CLI de Azure o mediante 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, vea Instalación de la CLI de Azure.

Instalación de la extensión aks-preview de la CLI

Para usar directivas de seguridad de pod, necesitará la versión 0.4.1 de la extensión de la CLI aks-preview o una posterior. Instale la extensión de la CLI de Azure aks-preview con el comando az extension add y, a continuación, busque las actualizaciones disponibles con el comando az extension update:

# Install the aks-preview extension
az extension add --name aks-preview

# Update the extension to make sure you have the latest version installed
az extension update --name aks-preview

Registro del proveedor de características de la directiva de seguridad de pod

Este documento y esta característica quedarán en desuso el 15 de octubre de 2020.

Para crear o actualizar un clúster de AKS para que use directivas de seguridad de pod, habilite primero una marca de características en su suscripción. Para registrar la marca de características PodSecurityPolicyPreview, use el comando az feature register tal como se muestra en el siguiente ejemplo:

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

Tarda unos minutos en que el estado muestre Registrado. Puede comprobar el estado de registro con el comando az feature list:

az feature list -o table --query "[?contains(name, 'Microsoft.ContainerService/PodSecurityPolicyPreview')].{Name:name,State:properties.state}"

Cuando todo esté listo, actualice el registro del proveedor de recursos Microsoft.ContainerService con 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 predeterminadas proporcionan una experiencia de fábrica para definir qué pods que se puede programar. Sin embargo, los usuarios del clúster pueden encontrarse con problemas al implementar los pods hasta que defina sus propias directivas. El método recomendado es el siguiente:

  • Creación de un clúster de AKS
  • Definición de directivas de seguridad de pod propias
  • Habilitación de la característica de directiva de seguridad de pod

Para mostrar cómo las directivas predeterminadas limitan la implementación de pods, en este artículo primero se habilita la característica de las directivas de seguridad de pod y después se crea una directiva personalizada.

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

A continuación se muestra un resumen de los cambios de comportamiento 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 (administradores y no administradores) ven las mismas directivas. No hay ninguna grafía 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 todavía no se admite, pero está planeada.
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

Puede habilitar o deshabilitar la directiva de seguridad de pod mediante el comando az aks update. En el siguiente ejemplo se habilita la directiva de seguridad de pod en el clúster denominado myAKSCluster del grupo de recursos myResourceGroup.

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 predeterminadas limitan la implementación de pods.

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.

Para ver las directivas disponibles, use el comando kubectl get psp, tal como se muestra en el siguiente ejemplo.

$ kubectl get psp

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. Use el comando kubectl get rolebindings y busque el enlace default:privileged: en el espacio de nombres kube-system:

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

Como se muestra en la siguiente salida reducida, el valor de ClusterRole psp:privileged 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

De forma predeterminada, al usar el comando az aks get-credentials, las credenciales del administrador del clúster de AKS se agregan a la configuración de kubectl. El usuario administrador está exento del cumplimiento de las directivas de seguridad de pod. Si usa la integración de Azure Active Directory para los clústeres de AKS, podría iniciar sesión con las credenciales de un usuario sin derechos de administrador para ver el cumplimiento de directivas en acción. En este artículo vamos a crear y a usar una cuenta de usuario de prueba en el clúster de AKS.

Cree un espacio de nombres de ejemplo denominado psp-aks para probar los recursos con el comando kubectl create namespace. A continuación, cree una cuenta de servicio denominada nonadmin-user con el comando kubectl create serviceaccount:

kubectl create namespace psp-aks
kubectl create serviceaccount --namespace psp-aks nonadmin-user

Ahora cree un RoleBinding para nonadmin-user para que realice 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

Para resaltar la diferencia entre el usuario de administrador normal al usar kubectl y el usuario sin derechos de administrador que creó en los pasos anteriores, cree dos alias de la línea de comandos:

  • El alias kubectl-admin es para el usuario administrador normal, para el espacio de nombres psp-aks.
  • El alias kubectl nonadminuser es para el usuario no administrador creado en el paso anterior, para el espacio de nombres psp-aks.

Cree estos dos alias tal y como se muestra en 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 primero lo que sucede cuando se programa un pod con el contexto de seguridad privileged: true. Este contexto de seguridad eleva los privilegios del pod. En la sección anterior donde se mostraban las directivas de seguridad de pod predeterminadas de AKS, la directiva privilege debería denegar esta solicitud.

Cree un archivo denominado nginx-privileged.yaml y pegue el 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

Cree el pod mediante el comando kubectl apply y especifique el nombre del manifiesto de YAML:

kubectl-nonadminuser apply -f nginx-privileged.yaml

El pod no se puede programar, como se muestra en la salida del ejemplo siguiente:

$ kubectl-nonadminuser apply -f nginx-privileged.yaml

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

El pod no llega a la fase de programación, por lo que 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.

Cree un archivo denominado nginx-unprivileged.yaml y pegue el 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

Cree el pod mediante el comando kubectl apply y especifique el nombre del manifiesto de YAML:

kubectl-nonadminuser apply -f nginx-unprivileged.yaml

El pod no se puede programar, como se muestra en la salida del ejemplo siguiente:

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

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

El pod no llega a la fase de programación, por lo que 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. Vamos a probar ahora a ejecutar ese mismo pod NGINX con un contexto de usuario específico, como runAsUser: 2000.

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

Cree el pod mediante el comando kubectl apply y especifique el nombre del manifiesto de YAML:

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

El pod no se puede programar, como se muestra en la salida del ejemplo siguiente:

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

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: []

El pod no llega a la fase de programación, por lo que 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.

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:
  - '*'

Cree la directiva mediante el comando kubectl apply y especifique el nombre del manifiesto de YAML:

kubectl apply -f psp-deny-privileged.yaml

Para ver las directivas disponibles, use el comando kubectl get psp, tal como se muestra 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.

$ kubectl get psp

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, cree un ClusterRole que le permita usar la directiva psp-deny-privileged que creó en el paso anterior. 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

Cree el ClusterRole mediante el comando kubectl apply y especifique el nombre del manifiesto de YAML:

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

Ahora cree un ClusterRoleBinding para usar el ClusterRole que creó en el paso anterior. 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

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. Use el mismo manifiesto nginx-privileged.yaml para crear el pod mediante el comando kubectl apply:

kubectl-nonadminuser apply -f nginx-unprivileged.yaml

Se ha programado correctamente el pod. Al activar el estado del pod mediante el comando kubectl get pods, el pod tiene el estado En ejecución:

$ kubectl-nonadminuser get pods

NAME                 READY   STATUS    RESTARTS   AGE
nginx-unprivileged   1/1     Running   0          7m14s

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.

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

Par deshabilitar la directiva de seguridad de pod, use el comando az aks update de nuevo. En el siguiente ejemplo se deshabilita la directiva de seguridad de pod en el clúster denominado myAKSCluster del grupo de recursos myResourceGroup:

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

A continuación, elimine ClusterRole y ClusterRoleBinding:

kubectl delete -f psp-deny-privileged-clusterrolebinding.yaml
kubectl delete -f psp-deny-privileged-clusterrole.yaml

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

Por último, elimine el espacio de nombres psp-aks:

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. Hay una gran cantidad de características que puede aplicar una directiva, 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).