Introdução à Google Cloud CLI (GKE)


Neste tutorial, mostramos como configurar e testar uma política de autorização binária que requer atestados. Esse tipo de política protege sua cadeia de suprimentos de software baseada em contêiner verificando se uma imagem de contêiner tem um atestado assinado antes de permitir a implantação da imagem.

No momento da implantação, a autorização binária usa atestadores para verificar assinaturas digitais em atestados. Os atestados são criados por signatários, geralmente como parte de um pipeline de integração contínua (CI).

Neste tutorial, o cluster do GKE, os atestados e os atestadores estão localizados em um único projeto. Uma configuração de projeto único é muito útil para testar ou testar o serviço. Para ver um exemplo mais real, consulte configuração de vários projetos.

As etapas abaixo descrevem as tarefas que você executa na linha de comando. Para seguir essas etapas usando o Console do Google Cloud, consulte Introdução ao Console do Google Cloud.

Objetivos

Neste tutorial, você aprenderá a realizar as seguintes tarefas:

  • Criar um cluster do Google Kubernetes Engine (GKE) com autorização binária ativada
  • Criar um atestador que o aplicador de autorização binária usa para verificar a assinatura em um atestado
  • Configurar uma política que exija um atestado
  • Criar um par de chaves criptográficas para assinar atestados e depois verificá-los
  • Assinar um resumo de imagem de contêiner, criando uma assinatura
  • Criar um atestado usando a assinatura
  • Testar a política implantando uma imagem de contêiner no GKE

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Antes de começar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Install the Google Cloud CLI.
  5. To initialize the gcloud CLI, run the following command:

    gcloud init
  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  7. Make sure that billing is enabled for your Google Cloud project.

  8. Install the Google Cloud CLI.
  9. To initialize the gcloud CLI, run the following command:

    gcloud init
  10. Instale kubectl para interagir com o GKE.

Ativar autorização binária

Defina o projeto padrão.

A primeira etapa é definir o projeto padrão do Google Cloud usado pelo comando gcloud:

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

PROJECT_ID é o nome do projeto.

Ativar APIs obrigatórias

Ativar APIs para:

Container Registry

gcloud --project=${PROJECT_ID} \
    services enable\
    container.googleapis.com\
    containerregistry.googleapis.com\
    binaryauthorization.googleapis.com

Artifact Registry

gcloud --project=${PROJECT_ID} \
    services enable\
    container.googleapis.com\
    artifactregistry.googleapis.com\
    binaryauthorization.googleapis.com

Criar um cluster com a autorização binária ativada

Criar o cluster

Criar um cluster do GKE com a autorização binária ativada Este é o cluster em que você quer executar as imagens de contêiner implantadas. Ao criar o cluster, você passa a sinalização --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE para o comando gcloud container clusters create.

Para criar o cluster, siga estas etapas:

gcloud container clusters create \
    --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE \
    --zone us-central1-a \
    test-cluster

Aqui, você cria um cluster chamado test-cluster na zona us-central1-a do GKE.

Configurar kubectl

Também é necessário atualizar o arquivo kubeconfig local para a instalação do kubectl. Isso fornece as credenciais e as informações de endpoint necessárias para acessar o cluster no GKE.

Para atualizar o arquivo kubeconfig local:

gcloud container clusters get-credentials \
    --zone us-central1-a \
    test-cluster

Ver a política padrão

Uma política na autorização binária é um conjunto de regras que regem a implantação de imagens de contêiner. Você pode ter uma política por projeto. Por padrão, a política é configurada para permitir que todas as imagens de contêiner sejam implantadas.

A autorização binária permite exportar e importar um arquivo de política no formato YAML. Esse formato reflete a estrutura de uma política conforme ela é armazenada pelo serviço. Ao configurar uma política usando comandos gcloud, você edita esse arquivo.

Para ver a política padrão, exporte o arquivo YAML da política:

gcloud container binauthz policy export

Por padrão, o arquivo tem o seguinte conteúdo:

defaultAdmissionRule:
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
  evaluationMode: ALWAYS_ALLOW
globalPolicyEvaluationMode: ENABLE
name: projects/PROJECT_ID/policy

A regra padrão é definida no nó defaultAdmissionRule. evaluationMode especifica que a política permite todas as tentativas de implantação de imagem. Neste tutorial, você atualizará a regra padrão para exigir atestados.

globalPolicyEvaluationMode isenta as imagens do sistema gerenciadas pelo Google da aplicação da autorização binária.

Para adicionar uma imagem isenta à lista de permissões, inclua o seguinte no arquivo de política:

admissionWhitelistPatterns:
  - namePattern: EXEMPT_IMAGE_PATH

Substitua EXEMPT_IMAGE_PATH pelo caminho para a imagem a ser isentada. Para isentar outras imagens, adicione outras entradas - namePattern. Saiba mais sobre admissionWhitelistPatterns.

Para mais informações sobre a estrutura de uma política, consulte a Referência do YAML de políticas.

Crie um atestador

Um atestador é a autoridade de verificação que o aplicador de autorização binária usa no momento da implantação para decidir se o GKE implantará a imagem do contêiner assinado correspondente. O atestador contém a chave pública e normalmente é gerenciado pela equipe da sua organização responsável pela segurança da cadeia de suprimentos de software.

Para criar um atestador, você precisa:

  • Crie uma nota no Artifact Analysis para armazenar metadados confiáveis usados no processo de autorização
  • Criar o atestador em autorização binária e associar a nota que você criou

Para este tutorial, você tem um atestador chamado test-attestor e uma nota do Container Analysis chamada test-attestor-note. Em um cenário real, você pode ter qualquer número de atestadores, cada um representando uma parte que participa do processo de autorização para uma imagem de contêiner.

Criar nota do Artifact Analysis

  1. Defina variáveis que armazenam o nome do atestador e da nota do Artifact Analysis:

    ATTESTOR_NAME=test-attestor
    NOTE_ID=test-attestor-note
    

    Substitua:

    • test-attestor: nome do atestador de sua escolha.
    • attestor-note: nome da nota do atestador de sua escolha.
  2. Crie um arquivo JSON em /tmp/note_payload.json que descreva a nota do Container Analysis:

    cat > /tmp/note_payload.json << EOM
    {
      "name": "projects/${PROJECT_ID}/notes/${NOTE_ID}",
      "attestation": {
        "hint": {
          "human_readable_name": "Attestor Note"
        }
      }
    }
    EOM
    
  3. Envie uma solicitação HTTP para a API REST do Artifact Analysis para criar a nota:

    curl -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
        --data-binary @/tmp/note_payload.json  \
        "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"
    
  4. Verifique se a nota foi criada:

    curl \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}"
    

Crie o atestador

Agora, você pode criar o atestador:

  1. Crie o atestador na autorização binária:

    gcloud container binauthz attestors create ${ATTESTOR_NAME} \
    --attestation-authority-note=${NOTE_ID} \
    --attestation-authority-note-project=${PROJECT_ID}
    
  2. Verifique se ele foi criado:

    gcloud container binauthz attestors list
    

O atestador que você criou ainda não pode ser usado sem um par de chaves PKIX associado, criado abaixo.

Gerar um par de chaves

A autorização binária usa chaves criptográficas para verificar com segurança a identidade dos assinantes. Isso garante que somente imagens de contêiner autorizadas possam ser implantadas. O par de chaves consiste em uma chave privada e uma chave pública. O signer usa a chave privada para assinar o resumo da imagem do contêiner, produzindo uma assinatura que é armazenada em um atestado. A chave pública é armazenada no atestador. No momento da implantação, o implementador de autorização binária usa a chave pública do atestador para verificar a assinatura no atestado antes de permitir a implantação do contêiner.

Neste tutorial, você usará o formato Public-Key Infrastructure (X.509) (PKIX) para chaves criptográficas. Este tutorial usa o Algoritmo de assinatura digital de curva elíptica (ECDSA, na sigla em inglês) recomendado para gerar um par de chaves PKIX. Também é possível usar chaves RSA ou PGP para assinatura.

Algoritmos e finalidades de chave para mais informações sobre algoritmos de assinatura.

As chaves geradas e armazenadas pelo Cloud Key Management Service (Cloud KMS) são compatíveis com o PKIX. Consulte Como criar atestadores usando a CLI gcloud para mais informações sobre o uso de chaves PKIX e do Cloud KMS.

PKIX (Cloud KMS)

Para criar o par de chaves no Cloud KMS, faça o seguinte:

  1. Configure as variáveis de ambiente necessárias para criar o par de chaves.

    KMS_KEY_PROJECT_ID=${PROJECT_ID}
    KMS_KEYRING_NAME=my-binauthz-keyring
    KMS_KEY_NAME=my-binauthz-kms-key-name
    KMS_KEY_LOCATION=global
    KMS_KEY_PURPOSE=asymmetric-signing
    KMS_KEY_ALGORITHM=ec-sign-p256-sha256
    KMS_PROTECTION_LEVEL=software
    KMS_KEY_VERSION=1
    
  2. Para criar o keyring, execute o seguinte comando:

    gcloud kms keyrings create ${KMS_KEYRING_NAME} \
      --location ${KMS_KEY_LOCATION}
    
  3. Para criar a chave, execute o seguinte comando:

    gcloud kms keys create ${KMS_KEY_NAME} \
      --location ${KMS_KEY_LOCATION} \
      --keyring ${KMS_KEYRING_NAME}  \
      --purpose ${KMS_KEY_PURPOSE} \
      --default-algorithm ${KMS_KEY_ALGORITHM} \
      --protection-level ${KMS_PROTECTION_LEVEL}
    
  4. Para adicionar a chave pública ao atestador, execute o seguinte comando:

    gcloud --project="${PROJECT_ID}" \
        container binauthz attestors public-keys add \
        --attestor="${ATTESTOR_NAME}" \
        --keyversion-project="${KMS_KEY_PROJECT_ID}" \
        --keyversion-location="${KMS_KEY_LOCATION}" \
        --keyversion-keyring="${KMS_KEYRING_NAME}" \
        --keyversion-key="${KMS_KEY_NAME}" \
        --keyversion="${KMS_KEY_VERSION}"
    
  5. Consiga o ID da chave pública do atestador da seguinte maneira:

    É possível ver seu ID de chave pública a qualquer momento usando o comando: gcloud container binauthz attestors describe <var>ATTESTOR_NAME</var>.

    Para salvar o ID da chave pública em uma variável de ambiente, digite este comando:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
    --format='value(userOwnedGrafeasNote.publicKeys[0].id)' --project ${PROJECT_ID})
    

PKIX (chave local)

Para gerar um par de chaves PKIX, siga estas etapas:

  1. Crie a chave privada:

    PRIVATE_KEY_FILE="/tmp/ec_private.pem"
    openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
    
  2. Extraia a chave pública da chave privada:

    PUBLIC_KEY_FILE="/tmp/ec_public.pem"
    openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
    
  3. Adicione a chave pública ao atestador.

    Agora, adicione a chave pública exportada ao atestador para que ela possa ser usada pela autorização binária para verificação de identidade:

    gcloud --project="${PROJECT_ID}" \
        beta container binauthz attestors public-keys add \
        --attestor="${ATTESTOR_NAME}" \
        --pkix-public-key-file=${PUBLIC_KEY_FILE} \
        --pkix-public-key-algorithm=ecdsa-p256-sha256
    
  4. Salve o código da chave pública.

    Para salvar o ID da chave pública, é possível copiá-lo da saída de public-keys add acima. Para ver o código da chave pública do atestador depois de adicioná-lo ao atestador, use gcloud container binauthz attestors describe ${ATTESTOR_NAME}:

    PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME} \
      --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
    

Configurar a política

Agora, você pode configurar sua política. Nesta etapa, você exporta o arquivo YAML da política para o sistema local e modifica a regra padrão para que exija um atestado pelo atestador definido acima.

Para configurar a política, siga estas etapas:

  1. Criar um novo arquivo de política que permita Imagens do sistema mantidas pelo Google , define o evaluationMode para REQUIRE_ATTESTATION e adiciona um nó chamado requireAttestationsBy que faz referência ao atestador que você criou:

    cat > /tmp/policy.yaml << EOM
        globalPolicyEvaluationMode: ENABLE
        defaultAdmissionRule:
          evaluationMode: REQUIRE_ATTESTATION
          enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
          requireAttestationsBy:
            - projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME}
        name: projects/${PROJECT_ID}/policy
    EOM
    
  2. Importe o arquivo YAML da política para a autorização binária:

    gcloud container binauthz policy import /tmp/policy.yaml
    

Para mais informações sobre como configurar uma política, consulte Configurar uma política usando a CLI gcloud.

Testar a política

Para testar a política configurada acima, tente implantar uma imagem de contêiner de amostra no cluster. A política bloqueará a implantação porque o atestado necessário não foi feito.

Neste tutorial, é possível usar imagens de amostra do Container Registry e do Artifact Registry. A imagem do Container Registry está localizada no caminho gcr.io/google-samples/hello-app:1.0. A imagem do Artifact Registry está localizada no caminho us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0. Os dois caminhos contêm imagem pública criada pelo Google que contém um aplicativo de amostra "Hello, World!".

Primeiro, tente implantar a imagem:

kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080

Agora verifique se a implantação foi bloqueada pela autorização binária:

kubectl get pods

O comando imprime a seguinte mensagem, que indica que a imagem não foi implantada:

No resources found.

Veja mais detalhes sobre a implantação:

kubectl get event --template \
'{{range.items}}{{"\033[0;36m"}}{{.reason}}:{{"\033[0m"}}\{{.message}}{{"\n"}}{{end}}'

Você verá uma resposta semelhante a esta:

FailedCreate: Error creating: pods POD_NAME is forbidden: admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image IMAGE_NAME denied by Binary Authorization default admission rule. Image IMAGE_NAME denied by attestor ATTESTOR_NAME: No attestations found

Nesta saída:

  • POD_NAME: o nome do pod.
  • IMAGE_NAME: o nome da imagem.
  • ATTESTOR_NAME: o nome do atestador.

Exclua a implantação para seguir para a próxima etapa:

kubectl delete deployment hello-server

Criar um atestado

Um atestado é um documento digital criado por um signatário que certifica que o GKE tem permissão para implantar a imagem de contêiner associada. O processo de criação de um atestado às vezes é chamado de "assinatura de imagem". Um signatário pode ser uma pessoa ou, mais frequentemente, um processo automatizado executado quando uma imagem de contêiner é criada. A assinatura é criada usando a chave privada de um par de chaves. No momento da implantação, o aplicador de autorização binária usa a chave pública do Attestor para verificar a assinatura no atestado.

Neste tutorial, seu atestado simplesmente declara que você autoriza a imagem para implantação.

Para criar um atestado, siga estas etapas:

  1. Defina variáveis que armazenem o caminho do registro e o resumo da imagem:

    Container Registry

    IMAGE_PATH="gcr.io/google-samples/hello-app"
    IMAGE_DIGEST="sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4"
    IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
    

    Artifact Registry

    IMAGE_PATH="us-docker.pkg.dev/google-samples/containers/gke/hello-app"
    IMAGE_DIGEST="sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567"
    IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
    
  2. Para criar o atestado, faça o seguinte:

    PKIX (Cloud KMS)

    Para criar o atestado usando a chave do Cloud KMS, execute o seguinte comando:

    gcloud beta container binauthz attestations sign-and-create \
        --project="${PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="${ATTESTOR_NAME}" \
        --attestor-project="${PROJECT_ID}" \
        --keyversion-project="${KMS_KEY_PROJECT_ID}" \
        --keyversion-location="${KMS_KEY_LOCATION}" \
        --keyversion-keyring="${KMS_KEYRING_NAME}" \
        --keyversion-key="${KMS_KEY_NAME}" \
        --keyversion="${KMS_KEY_VERSION}"
    

    PKIX (chave local)

    Para criar o atestado usando uma chave local, faça o seguinte:

    1. Gere o payload do atestado:

      gcloud container binauthz create-signature-payload \
      --artifact-url=${IMAGE_TO_ATTEST} > /tmp/generated_payload.json
      

      O arquivo JSON de payload tem o seguinte conteúdo:

      {
      "critical": {
        "identity": {
          "docker-reference": "gcr.io/google-samples/hello-app"
        },
        "image": {
          "docker-manifest-digest": "sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea
      882eb722c3be4"
        },
        "type": "Google cloud binauthz container signature"
      }
      }
      
    2. Para assinar o payload com sua chave privada PKIX e gerar um arquivo de assinatura, execute o seguinte comando:

      openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signature
      

      O arquivo de assinatura é a versão assinada do payload JSON que você criou anteriormente neste guia.

    3. Crie e valide o atestado:

      gcloud container binauthz attestations create \
        --project="${PROJECT_ID}" \
        --artifact-url="${IMAGE_TO_ATTEST}" \
        --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME}" \
        --signature-file=/tmp/ec_signature \
        --public-key-id="${PUBLIC_KEY_ID}" \
        --validate
      

      Substitua PUBLIC_KEY_ID pelo ID da chave pública que você encontrou em Gerar um par de chaves PKIX acima.

      A sinalização validate verifica se o atestado pode ser verificado pelo atestador que você configurou na política.

  3. Verifique se o atestado foi criado:

    gcloud container binauthz attestations list \
        --attestor=$ATTESTOR_NAME --attestor-project=$PROJECT_ID
    

Para mais informações sobre como criar atestados, consulte Como criar atestados.

Testar a política outra vez

Novamente, teste a política implantando uma imagem de contêiner de amostra no cluster. Desta vez, você precisa implantar a imagem usando o resumo em vez de uma tag, como 1.0 ou latest, já que a autorização binária usará o resumo para procurar atestados. Aqui, a autorização binária permite que a imagem seja implantada porque o atestado necessário foi feito.

Para implantar a imagem, siga estas etapas:

kubectl run hello-server --image ${IMAGE_TO_ATTEST} --port 8080

Para verificar se a imagem foi implantada:

kubectl get pods

O comando imprime uma mensagem semelhante à seguinte, que indica que a implantação foi bem-sucedida:

NAME                            READY     STATUS    RESTARTS   AGE
hello-server-579859fb5b-h2k8s   1/1       Running   0          1m

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Exclua o cluster que você criou no GKE:

gcloud container clusters delete \
    --zone=us-central1-a \
    test-cluster

A seguir