Aplicar políticas de segurança predefinidas no nível do pod usando o PodSecurity


Nesta página, mostramos como aplicar controles predefinidos de segurança no nível do pod nos clusters do Google Kubernetes Engine (GKE) usando o controlador de admissão PodSecurity.

Para mais informações sobre como o PodSecurity funciona, consulte Admissão de segurança do pod.

Visão geral

PodSecurity é um controlador de admissão do Kubernetes que permite aplicar os padrões de segurança de pods aos pods em execução nos clusters do GKE. Os padrões de segurança de pods são políticas de segurança predefinidas que abrangem as necessidades de alto nível de segurança do pod no Kubernetes. Essas políticas variam de altamente permissivas a altamente restritivas.

É possível aplicar os seguintes padrões de segurança de pods aos clusters do GKE:

  • Privilegiado: uma política irrestrita que fornece o nível mais amplo de permissões. Permite encaminhamentos de privilégios conhecidos.
  • Linha de base: uma política minimamente restritiva que permite a configuração de pods padrão minimamente especificada. Evita encaminhamentos de privilégios conhecidos.
  • Restrito: uma política altamente restritiva que segue as práticas recomendadas de escape de pods.

É possível usar o controlador de admissão PodSecurity para aplicar os padrões de segurança do pod dos seguintes modos:

  • Aplicação: as violações de política rejeitam a criação de pods. Um evento de auditoria é adicionado ao registro de auditoria.
  • Auditoria: as violações de política acionam a adição de um evento de auditoria ao registro de auditoria. A criação de pods é permitida.
  • Aviso: as violações da política acionam um aviso direcionado ao usuário. A criação de pods é permitida.

O controlador de admissão PodSecurity incorpora essas políticas na API Kubernetes.

Se você quiser criar e aplicar políticas de segurança personalizadas no nível do pod, use o controlador de admissão do Gatekeeper.

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ativar a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Se você quiser usar a Google Cloud CLI para essa tarefa, instale e, em seguida, inicialize a CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando gcloud components update.

Requisitos

O controlador de admissão PodSecurity está disponível e é ativado por padrão em clusters que executam as seguintes versões do GKE:

  • Versão 1.25 ou posterior: estável
  • Versão 1.23 e 1.24: Beta

Para verificar se uma versão do GKE está disponível e se é a versão padrão do seu canal de lançamento, consulte a Programação de lançamentos.

Aplicar padrões de segurança de pods usando PodSecurity

Para usar o controlador de admissão PodSecurity, aplique padrões de segurança de pods específicos em modos específicos a namespaces específicos. Para isso, use rótulos de namespace. Neste exercício, você vai:

  • Criar dois namespaces novos
  • Aplicar políticas de segurança a cada namespace
  • Testar as políticas configuradas

Nas seguintes versões do GKE, o GKE ignora as políticas aplicadas ao namespace kube-system:

  • 1.23.6-gke.1900 e mais recente
  • 1.24.0-gke.1200 e mais recente

Em versões anteriores do GKE, evite a aplicação de políticas em kube-system.

Criar namespaces

Crie namespaces no cluster:

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

Esse comando cria os seguintes namespaces:

  • baseline-ns: para cargas de trabalho permissivas
  • restricted-ns: para cargas de trabalho altamente restritas

Usar rótulos para aplicar políticas de segurança

Aplique os seguintes padrões de segurança de pods:

  • baseline: aplica-se a baseline-ns no modo warn
  • restricted: aplica-se a restricted-ns no 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

Esses comandos resultam em:

  • Cargas de trabalho no namespace baseline-ns que violam a política baseline são permitidas, e o cliente exibe uma mensagem de aviso.
  • As cargas de trabalho no namespace restricted-ns que violam a política restricted são rejeitadas, e o GKE adiciona uma entrada aos registros de auditoria.

Verifique se os rótulos foram adicionados:

kubectl get ns --show-labels

A saída será assim:

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

Testar as políticas configuradas

Para verificar se o controlador de admissão PodSecurity funciona conforme o esperado, implante uma carga de trabalho que viole a política baseline e restricted nos dois namespaces. O manifesto de exemplo a seguir implanta um contêiner nginx que permite o escalonamento de privilégios.

  1. Salve o seguinte manifesto como psa-workload.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        securityContext:
          privileged: true
    
  2. Aplique o manifesto ao namespace baseline-ns:

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

    A saída será assim:

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

    A política baseline permite que o pod seja implantado no namespace.

  3. Verifique se o pod foi implantado:

    kubectl get pods --namespace=baseline-ns -l=app=nginx
    
  4. Aplique o manifesto ao namespace restricted-ns:

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

    A saída será assim:

    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")
    

    O pod não será implantado no namespace. Uma entrada de auditoria é adicionada ao registro.

Ver violações da política nos registros de auditoria

As violações de política nos modos audit e enforce são registradas nos registros de auditoria do cluster. É possível ver esses registros usando o Explorador de registros no Console do Google Cloud.

  1. Acesse a página do Explorador de registros no console do Google Cloud:

    Acessar o Explorador de registros

  2. No campo Consulta, especifique o seguinte para recuperar os registros de auditoria do modo audit e 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. Clique em Executar consulta.

  4. Na seção Resultados da consulta, expanda a entrada de registro Forbidden para inspecionar os registros de rejeição do modo enforce. Os detalhes são semelhantes aos seguintes:

    {
      ...
      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. Expanda a entrada de registro audit-violations para inspecionar registros do modo audit. Os detalhes são semelhantes aos seguintes:

    {
      ...
      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"
    }
    

Limpar

Para evitar cobranças na conta do Google Cloud, exclua os namespaces:

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

Alternativas a PodSecurity

Além de usar o controlador de admissão integrado PodSecurity do Kubernetes para aplicar os padrões de segurança de pods, também é possível usar o Gatekeeper, um controlador de admissão baseado no Open Policy Agent (OPA) para criar e aplicar controles de segurança personalizados no nível do pod.

A seguir