Aplica políticas de seguridad predefinidas a nivel de los Pods con PodSecurity


En esta página, se muestra cómo aplicar controles de seguridad predefinidos a nivel de los Pods en los clústeres de Google Kubernetes Engine (GKE) mediante el controlador de admisión PodSecurity.

Para obtener más información sobre cómo funciona PodSecurity, consulta Admisión de seguridad de pods.

Descripción general

PodSecurity es un controlador de admisión de Kubernetes que te permite aplicar estándares de seguridad de pods a los pods que se ejecutan en tus clústeres de GKE. Los estándares de seguridad de pods son políticas de seguridad predefinidas que abarcan las necesidades de alto nivel de la seguridad de pods en Kubernetes. Estas políticas van desde muy permisivas hasta muy restrictivas.

Puedes aplicar los siguientes estándares de seguridad de pods a los clústeres de GKE:

  • Privada: Una política sin restricciones que proporciona el nivel más amplio de permisos. Permite la elevación de privilegios conocidos.
  • Baseline: Una política que tiene una restricción mínima y permite la configuración de pod predeterminada y mínimamente especificada. Evita las elevaciones conocidas de privilegios.
  • Restringida: Una política altamente restrictiva que sigue las prácticas recomendadas de endurecimiento de Pods.

Puedes usar el controlador de admisión PodSecurity para aplicar los estándares de seguridad de pods en los siguientes modos:

  • Aplicación: Los incumplimientos de política rechazan la creación del pod. Se agrega un evento de auditoría al registro de auditoría.
  • Auditoría: Los incumplimientos de política activan la adición de un evento de auditoría al registro de auditoría. Se permite la creación de pods.
  • Advertencia: Los incumplimientos de política activan una advertencia para el usuario. Se permite la creación de pods.

El controlador de admisión PodSecurity incorpora estas políticas en la API de Kubernetes.

Si deseas crear y aplicar políticas de seguridad personalizadas a nivel del Pod, considera usar el controlador de admisión Gatekeeper en su lugar.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Kubernetes Engine de Google.
  • Habilitar la API de Kubernetes Engine de Google
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.

Requisitos

El controlador de admisión PodSecurity está disponible y habilitado de forma predeterminada en los clústeres que ejecutan las siguientes versiones de GKE:

  • Versión 1.25 o posterior: Estable
  • Versión 1.23 y 1.24: Beta

A fin de verificar si una versión de GKE está disponible y es la predeterminada para tu canal de versiones, consulta el Programa de actualizaciones.

Aplica estándares de seguridad de Pods con PodSecurity.

Para usar el controlador de admisión PodSecurity, debes aplicar estándares de seguridad de Pods específicos en modos específicos a espacios de nombres específicos. Puedes hacerlo mediante etiquetas de espacio de nombres. En este ejercicio, realizarás las siguientes actividades:

  • Crea dos espacios de nombres nuevos
  • Aplica políticas de seguridad a cada espacio de nombres
  • Prueba las políticas configuradas

En las siguientes versiones de GKE, GKE ignora las políticas que aplicas al espacio de nombres kube-system:

  • 1.23.6-gke.1900 y versiones posteriores
  • 1.24.0-gke.1200 y versiones posteriores

En versiones anteriores de GKE, evita aplicar políticas en kube-system.

Crea espacios de nombres nuevos

Crea espacios de nombres en el clúster:

kubectl create ns baseline-ns
kubectl create ns restricted-ns

Este comando crea los siguientes espacios de nombres:

  • baseline-ns: para cargas de trabajo permisivas
  • restricted-ns: para cargas de trabajo altamente restringidas

Usa etiquetas para aplicar políticas de seguridad

Aplica los siguientes estándares de seguridad de pods:

  • baseline: Aplicar a baseline-ns en el modo warn
  • restricted: Aplicar a restricted-ns en el modo enforce
kubectl label --overwrite ns baseline-ns pod-security.kubernetes.io/warn=baseline
kubectl label --overwrite ns restricted-ns pod-security.kubernetes.io/enforce=restricted

Estos comandos logran el siguiente resultado:

  • Se permiten las cargas de trabajo en el espacio de nombres baseline-ns que infringen la política baseline y el cliente muestra un mensaje de advertencia.
  • Las cargas de trabajo en el espacio de nombres restricted-ns que infringen la política restricted se rechazan y GKE agrega una entrada a los registros de auditoría.

Verifica que se hayan agregado las etiquetas:

kubectl get ns --show-labels

El resultado es similar a este:

baseline-ns       Active   74s   kubernetes.io/metadata.name=baseline-ns,pod-security.kubernetes.io/warn=baseline
restricted-ns     Active   18s   kubernetes.io/metadata.name=restricted-ns,pod-security.kubernetes.io/enforce=restricted
default           Active   57m   kubernetes.io/metadata.name=default
kube-public       Active   57m   kubernetes.io/metadata.name=kube-public
kube-system       Active   57m   kubernetes.io/metadata.name=kube-system

Prueba las políticas configuradas

Para verificar que el controlador de admisión PodSecurity funcione según lo previsto, implementa una carga de trabajo que infrinja la política baseline y restricted en ambos espacios de nombres. En el siguiente manifiesto de ejemplo, se implementa un contenedor nginx que permite la elevación de privilegios.

  1. Guarda el siguiente manifiesto como psa-workload.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        securityContext:
          privileged: true
    
  2. Aplica el manifiesto al espacio de nombres baseline-ns:

    kubectl apply -f psa-workload.yaml --namespace=baseline-ns
    

    El resultado es similar a este:

    Warning: would violate PodSecurity "baseline:latest": privileged (container "nginx" must not set securityContext.privileged=true)
    

    La política baseline permite que el Pod se implemente en el espacio de nombres.

  3. Verifica que el Pod se haya implementado correctamente:

    kubectl get pods --namespace=baseline-ns -l=app=nginx
    
  4. Aplica el manifiesto al espacio de nombres restricted-ns:

    kubectl apply -f psa-workload.yaml --namespace=restricted-ns
    

    El resultado es similar a este:

    Error from server (Forbidden): error when creating "workload.yaml": pods "nginx"
    is forbidden: violates PodSecurity "restricted:latest": allowPrivilegeEscalation
    != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false),
    unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]),
    runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true),
    seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type
    to "RuntimeDefault" or "Localhost")
    

    El Pod no se implementará en el espacio de nombres. Se agrega una entrada de auditoría al registro.

Visualiza los incumplimientos de políticas en los registros de auditoría

Los incumplimientos de política en los modos audit y enforce se registran en los registros de auditoría de tu clúster. Puedes ver estos registros con el Explorador de registros de la consola de Google Cloud.

  1. Ve al Explorador de registros en la consola de Google Cloud.

    Ir al Explorador de registros

  2. En el campo Consulta, especifica lo siguiente para recuperar los registros de auditoría del modo audit y enforce:

    resource.type="k8s_cluster"
    protoPayload.resourceName:"/pods/nginx"
    protoPayload.methodName="io.k8s.core.v1.pods.create"
    (labels."pod-security.kubernetes.io/audit-violations":"PodSecurity" OR protoPayload.response.reason="Forbidden")
    
  3. Haz clic en Ejecutar consulta.

  4. En la sección Resultados de la consulta, expande la entrada de registro Forbidden para inspeccionar los registros de rechazo del modo enforce. Las políticas son similares a las siguientes:

    {
      ...
      protoPayload: {
        @type: "type.googleapis.com/google.cloud.audit.AuditLog"
        authenticationInfo: {1}
        authorizationInfo: [1]
        methodName: "io.k8s.core.v1.pods.create"
        request: {6}
        requestMetadata: {2}
        resourceName: "core/v1/namespaces/restricted-ns/pods/nginx"
        response: {
          @type: "core.k8s.io/v1.Status"
          apiVersion: "v1"
          code: 403
          details: {2}
          kind: "Status"
          message: "pods "nginx" is forbidden: violates PodSecurity "restricted:latest": privileged
                  (container "nginx" must not set securityContext.privileged=true),
                  allowPrivilegeEscalation != false (container "nginx" must set
                  securityContext.allowPrivilegeEscalation=false), unrestricted capabilities
                  (container "nginx" must set securityContext.capabilities.drop=["ALL"]),
                  runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true),
                  seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type
                  to "RuntimeDefault" or "Localhost")"
          metadata: {0}
          reason: "Forbidden"
          status: "Failure"
          }
          serviceName: "k8s.io"
          status: {2}
        }
      receiveTimestamp: "2022-02-01T19:19:25.353235326Z"
      resource: {2}
      timestamp: "2022-02-01T19:19:21.469360Z"
    }
    
  5. Expande la entrada de registro audit-violations para inspeccionar los registros del modo audit. Los detalles son similares a los siguientes:

    {
      ...
      labels: {
        ...
        pod-security.kubernetes.io/audit-violations: "would violate PodSecurity "baseline:latest": privileged
                                                    (container "nginx" must not set securityContext.privileged=true)"
        pod-security.kubernetes.io/enforce-policy: "privileged:latest"
      }
      operation: {4}
      protoPayload: {10}
      receiveTimestamp: "2023-12-26T05:18:04.533631468Z"
      resource: {2}
      timestamp: "2023-12-26T05:17:36.102387Z"
    }
    

Limpia

Para evitar que se generen cargos en tu cuenta de Google Cloud, borra los espacios de nombres:

kubectl delete ns baseline-ns
kubectl delete ns restricted-ns

Alternativas a PodSecurity

Además de usar el controlador de admisión PodSecurity de Kubernetes integrado para aplicar los Estándares de seguridad de pods, también puedes usar Gatekeeper, un controlador de admisión basado en Open Policy Agent (OPA), para crear y aplicar controles de seguridad personalizados a nivel de Pod.

¿Qué sigue?