Como proteger metadados de cluster

Visão geral

O GKE usa metadados de instância para configurar VMs de nós, mas alguns desses metadados são potencialmente sensíveis e devem ser protegidos de cargas de trabalho em execução no cluster.

Antes de começar

Prepare-se para a tarefa tomando as seguintes medidas:

  • Verifique se você ativou a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Verifique se o SDK do Cloud está instalado.
  • Defina o ID do projeto padrão:
    gcloud config set project [PROJECT_ID]
  • Se você estiver trabalhando com clusters zonais, defina a zona do Compute padrão:
    gcloud config set compute/zone [COMPUTE_ZONE]
  • Se você estiver trabalhando com clusters regionais, defina a região do Compute padrão:
    gcloud config set compute/region [COMPUTE_REGION]
  • Atualize gcloud para a versão mais recente:
    gcloud components update

Configurar conta de serviço de nó

Como as credenciais da conta de serviço de cada nó continuarão sendo expostas às cargas de trabalho, assegure-se de ter configurado uma conta de serviço com as permissões mínimas necessárias. Em seguida, anexe essa conta de serviço aos seus nós, para que um invasor não contorne as proteções de metadados do GKE usando a API do Compute Engine para acessar diretamente as instâncias do nó.

Não use uma conta de serviço que tenha a permissão compute.instances.get, o papel administrador da instância do Compute ou outras permissões semelhantes, já que esses escopos de acesso permitem que invasores em potencial recebam metadados de instância usando a API Compute Engine. A prática recomendada é restringir as permissões de uma VM de nó usando permissões de conta de serviço, e não escopos de acesso. Para mais informações, consulte a documentação das contas de serviço do Compute Engine.

Se você não tiver uma conta de serviço de nó, use os seguintes comandos para criar uma:

export NODE_SA_NAME=gke-node-sa
gcloud iam service-accounts create $NODE_SA_NAME \
  --display-name "Node Service Account"
export NODE_SA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \
  --filter='displayName:Node Service Account')

Para configurar a conta de serviço com os papéis e permissões necessários, execute os seguintes comandos. PROJECT é o ID do projeto:

export PROJECT=$(gcloud config get-value project)

gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/monitoring.metricWriter
gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/monitoring.viewer
gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/logging.logWriter

Além disso, se o cluster extrai imagens privadas do Registro do contêiner, adicione o papelstorage.objectViewer:

gcloud projects add-iam-policy-binding $PROJECT \
  --member serviceAccount:$NODE_SA_EMAIL \
  --role roles/storage.objectViewer

Desativação e transição de APIs de metadados legados

Os endpoints de servidor de metadados v1beta1 e v0.1 do Compute Engine foram suspensos e eles serão encerrados em breve. Verifique se você atualizou todas as solicitações para usar o endpoint v1.

O servidor de metadados de instância do Compute Engine exibe os endpoints legados v0.1 e v1beta1, que não aplicam cabeçalhos de consulta de metadados. Esse é um recurso nas APIs v1 que dificulta que um invasor em potencial recupere metadados de instância. A menos que seja especificamente necessário, recomendamos que você desative essas APIs legadas.

Observação: atualmente, APIs de metadados legados podem ser desabilitadas somente ao criar um novo cluster ou ao adicionar um novo pool de nós a um cluster atual..

A seção a seguir explica como:

  • Identifique quais nós estão acessando os endpoints com uso suspenso. Se algum nó estiver usando endpoints com uso suspenso, será necessário migrar esses nós.

  • Crie um novo cluster ou pool de nós com os endpoints do servidor de metadados legados desativados para esses nós identificados.

Como identificar nós usando endpoints do servidor de metadados legados

É possível usar a ferramenta check-legacy-endpoint-access para determinar qual nó do Kubernetes Engine usa endpoints do servidor de metadados legados. Quando aplicada em seu cluster, essa ferramenta registra todos as solicitações feitas pelos seus nós aos endpoints v0.1 e v1beta1 a cada cinco minutos. Essa ferramenta também pode ser usada para identificar, depurar e verificar o uso dos endpoints legados no Kubernetes Engine.

Para configurar a ferramenta check-legacy-endpoint access, conclua as seguintes etapas:

  1. Em cada um dos seus clusters, execute o seguinte comando:

    kubectl apply -f \
    https://raw.githubusercontent.com/GoogleCloudPlatform\
    /k8s-node-tools/master/check-legacy-endpoint-access/check-legacy-endpoint-access.yaml
  2. Consulte os registros coletados com informações de uso do endpoint legado. Para consultar os registros, execute o seguinte comando em cada cluster:

    kubectl -n kube-system logs -l \
    app=check-legacy-endpoint-access | grep "access count"

Você também pode ver os registros coletados no Stackdriver Logging.

  1. Acesse a página Stackdriver Logging > Registros (Visualizador de registros) no Console do Cloud:

    Acesse a página Visualizador de registros (em inglês)

  2. Aplique o seguinte filtro:

    resource.type="container"
    resource.labels.namespace_id="kube-system"
    logName:"/check-legacy-endpoint-access"

    Acesse a visualização filtrada

  3. Depois de identificar os nós, é necessário identificar os processos que estão usando esses endpoints. Para receber instruções sobre como identificar esses processos, consulte Como identificar os processos.

  4. Migre esses processos para usar o endpoint do servidor de metadados v1. Para instruções sobre como migrar os nós e as diferenças do Compute Engine nos endpoints, consulte Como fazer a migração para o endpoint de servidor de metadados v1.

  5. Remova o daemonset check-legacy-endpoint-access.

    kubectl delete check-legacy-endpoint-access 

Como criar um novo pool de nós com APIs de metadados legados desativadas

Depois de criar uma conta de serviço, será possível criar um novo pool de nós (ou um pool de nós padrão em um novo cluster) com APIs de metadados legados desativadas usando a ferramenta de linha de comando gcloud.

Para criar um novo pool de nós com APIs de metadados legados desativadas, use a sinalização --metadata disable-legacy-endpoints=true. Por exemplo:

gcloud container node-pools create [POOL_NAME] \
  --service-account=$NODE_SA_EMAIL \
  --metadata disable-legacy-endpoints=true

Um novo cluster pode ser criado com APIs de metadados legadas e desativadas no pool de nós padrão usando a mesma sinalização. Por exemplo:

gcloud container clusters create [CLUSTER_NAME] \
  --service-account=$NODE_SA_EMAIL \
  --metadata disable-legacy-endpoints=true

Como atualizar um cluster existente para desativar as APIs de metadados legados

Depois de criar um novo pool de nós com APIs de metadados legados e desativadas, é possível atualizar um cluster existente para usá-lo seguindo o guia de migração do pool de nós.

Como verificar se as APIs de metadados legados estão desativadas

Quando as APIs de metadados da instância legada são desativadas, as solicitações para os endpoints do servidor de metadados /0.1/ e /v1beta1/ retornam 403 Forbidden.

Para verificar se as APIs de metadados legados foram desativadas, execute um comando curl a partir de um pod (em inglês):

root@pod-name# curl -H 'Metadata-Flavor: Google' \
'http://metadata.google.internal/computeMetadata/v1/instance/attributes/disable-legacy-endpoints'
true
root@pod-name# curl 'http://metadata.google.internal/computeMetadata/v1beta1/instance/id'
... Error 403 (Forbidden) ... Legacy metadata endpoint accessed: /computeMetadata/v1beta1/instance/id Legacy metadata endpoints are disabled. Please use the /v1/ endpoint. ...

Ocultação de metadados

A ocultação de metadados do GKE protege alguns metadados do sistema potencialmente sensíveis das cargas de trabalho do usuário em execução no cluster.

No Kubernetes v1.9.3 e superior, é possível ativar a ocultação de metadados para impedir que os pods do usuário acessem determinados metadados de VM nos nós do cluster, como credenciais do Kubelet e informações de instância de VM. A ocultação de metadados protege especificamente o acesso a kube-env, que contém credenciais do Kubelet, e ao token de identidade da instância da VM.

Os firewalls de ocultação de metadados transitam de pods de usuários (não executados em HostNetwork) para o servidor de metadados do cluster, permitindo apenas consultas seguras. O firewall impede que os pods de usuário utilizem credenciais do Kubelet para ataques de escalonamento de privilégios ou utilizem a identidade de VM para ataques de escalonamento de instância.

Limitações

  • A ocultação de metadados protege apenas o acesso a kube-env e o token de identidade da instância do nó.
  • A ocultação de metadados não restringe o acesso à conta de serviço do nó.
  • A ocultação de metadados não restringe o acesso a outros metadados de instância relacionados.
  • A ocultação de metadados não restringe o acesso a outras APIs de metadados legadas.

Como criar um novo cluster ou pool de nós com ocultação de metadados

Depois de criar uma conta de serviço, use a ferramenta de linha de comando gcloud para gerar um novo cluster com a ocultação de metadados ativada.

Para criar um cluster com a ocultação de metadados ativada, execute o seguinte comando no shell ou na janela de terminal:

gcloud beta container clusters create [CLUSTER_NAME] \
  --workload-metadata-from-node=SECURE \
  --service-account=$NODE_SA_EMAIL \
  --metadata disable-legacy-endpoints=true \
  [additional parameters and flags omitted]

em que:

  • [CLUSTER_NAME] é o nome do cluster a ser criado.
  • --workload-metadata-from-node está definido como SECURE; definir a sinalização como EXPOSED ou UNSPECIFIED desativa a ocultação de metadados.

Verificar metadados do token de identidade ocultos da carga de trabalho do cluster

Ao ocultar metadados, não é possível solicitar uma assinatura por meio do token de identidade de instância do nó. Para verificar se as solicitações informam explicitamente os usuários de metadados ocultos, execute um comando curl a partir de um pod (em inglês):

root@pod-name# curl -H "Metadata-Flavor: Google" \
'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://www.example.com'
This metadata endpoint is concealed.