Comece a usar a CLI do Google Cloud (GKE)

Este tutorial mostra como configurar e testar uma política de autorização binária que requer atestações. Este tipo de política protege a sua cadeia de abastecimento de software baseada em contentores, verificando se uma imagem de contentor tem uma atestação assinada antes de permitir a implementação da imagem.

No momento da implementação, a autorização binária usa atestadores para validar assinaturas digitais em atestações. As atestações são criadas por signatários, normalmente como parte de um pipeline de integração contínua (IC).

Neste tutorial, o cluster do GKE, as atestações e os atestadores estão todos localizados num único projeto. Uma configuração de projeto único é principalmente útil para testar ou experimentar o serviço. Para um exemplo mais real, consulte a configuração de vários projetos.

Os passos abaixo descrevem as tarefas que realiza na linha de comandos. Para seguir estes passos através da Google Cloud consola, consulte o artigo Começar a usar a Google Cloud consola.

Ative a Autorização binária

Defina o projeto predefinido

O primeiro passo é definir o Google Cloud projeto predefinido usado pelo comandogcloud:

PROJECT_ID=PROJECT_ID
gcloud config set project ${PROJECT_ID}

em que PROJECT_ID é o nome do seu projeto.

Ative as APIs necessárias

Ative as APIs para:

Artifact Registry

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

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

Crie o cluster

Crie um cluster do GKE com a autorização binária ativada. Este é o cluster onde quer que as imagens de contentores implementadas sejam executadas. Quando cria o cluster, passa a flag --binauthz-evaluation-mode=PROJECT_SINGLETON_POLICY_ENFORCE para o comando gcloud container clusters create.

Para criar o cluster, siga estes passos:

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

Aqui, cria um cluster denominado test-cluster na zona do GKE us-central1-a.

Configure o kubectl

Também tem de atualizar o ficheiro kubeconfig local para a sua instalação do kubectl. Isto fornece as credenciais e as informações do ponto final necessárias para aceder ao cluster no GKE.

Para atualizar o ficheiro kubeconfig local:

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

Veja a política predefinida

Uma política na Autorização binária é um conjunto de regras que regem a implementação de imagens de contentores. Pode ter uma política por projeto. Por predefinição, a política está configurada para permitir a implementação de todas as imagens de contentores.

A autorização binária permite-lhe exportar e importar um ficheiro de política no formato YAML. Este formato reflete a estrutura de uma política tal como é armazenada pelo serviço. Quando configura uma política através de comandos gcloud, edita este ficheiro.

Para ver a política predefinida, exporte o ficheiro YAML da política:

gcloud container binauthz policy export

Por predefinição, o ficheiro tem o seguinte conteúdo:

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

A regra predefinida está definida no nó defaultAdmissionRule. evaluationMode especifica que a política permite todas as tentativas de implementação de imagens. Neste tutorial, vai atualizar a regra predefinida para exigir atestações.

globalPolicyEvaluationMode Isenta as imagens do sistema geridas pela Google da aplicação da autorização binária.

Para adicionar uma imagem isenta à lista de autorizações, adicione o seguinte ao ficheiro de política:

admissionWhitelistPatterns:
  - namePattern: EXEMPT_IMAGE_PATH

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

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

Crie um atestador

Um atestador é a autoridade de validação que o aplicador da autorização binária usa no momento da implementação para decidir se permite que o GKE implemente a imagem de contentor assinada correspondente. O atestador contém a chave pública e é normalmente gerido por pessoal da sua organização responsável pela segurança da cadeia de fornecimento de software.

Para criar um atestador, tem de:

  • Crie uma nota na análise de artefactos para armazenar metadados fidedignos usados no processo de autorização
  • Crie o atestador na autorização binária e associe a nota que criou

Para este tutorial, tem um atestador denominado test-attestor e uma nota de análise do contentor denominada test-attestor-note. Num cenário real, pode ter qualquer número de atestadores, cada um representando uma parte que participa no processo de autorização de uma imagem de contentor.

Crie a nota de análise de artefactos

  1. Defina variáveis que armazenam o nome do atestador e a nota de análise de artefactos:

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

    Substituição:

    • test-attestor: nome do atestador à sua escolha.
    • attestor-note: o nome da nota do atestador à sua escolha.
  2. Crie um ficheiro JSON em /tmp/note_payload.json que descreva a nota de análise do contentor:

    cat > /tmp/note_payload.json << EOM
    {
      "name": "projects/${PROJECT_ID}/notes/${NOTE_ID}",
      "attestation": {
        "hint": {
          "human_readable_name": "Attestor Note"
        }
      }
    }
    EOM
    
  3. Crie a nota enviando um pedido HTTP para a API REST Artifact Analysis:

    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, 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 o atestador foi criado:

    gcloud container binauthz attestors list
    

O atestador que criou ainda não é utilizável sem um par de chaves associado, que cria mais tarde neste guia.

Gere um par de chaves

A autorização binária usa chaves criptográficas para validar a identidade dos signatários de forma segura. Isto garante que apenas é possível implementar imagens de contentores autorizadas. O par de chaves consiste numa chave privada e numa chave pública. O signatário usa a chave privada para assinar o resumo da imagem do contentor, produzindo uma assinatura que é, depois, armazenada numa atestação. A chave pública está armazenada no atestador. No momento da implementação, o aplicador da Autorização binária usa a chave pública do atestador para validar a assinatura na atestação antes de permitir a implementação do contentor.

Neste tutorial, vai usar o formato de infraestrutura de chave pública (X.509) (PKIX) para chaves criptográficas. Este tutorial usa o algoritmo de assinatura digital de curva elíptica (ECDSA) recomendado para gerar um par de chaves PKIX. Também pode usar chaves RSA ou PGP para assinar imagens.

Para mais informações sobre algoritmos de assinatura, consulte o artigo Finalidades e algoritmos das chaves.

As chaves geradas e armazenadas pelo Cloud Key Management Service (Cloud KMS) estão em conformidade com a norma PKIX. Consulte o artigo Criar atestadores com a CLI gcloud para mais informações sobre a utilização 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 conjunto de chaves, 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. Obtenha o ID da chave pública do atestador da seguinte forma:

    Pode ver o ID da chave pública em qualquer altura através do comando: gcloud container binauthz attestors describe <var>ATTESTOR_NAME</var>.

    Para guardar o ID da chave pública numa variável de ambiente, introduza 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 estes passos:

  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 que exportou ao atestador para que possa ser usada pela autorização binária para a validaçã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. Guarde o ID da chave pública.

    Para guardar o ID da chave pública, pode copiá-lo a partir do resultado do comando public-keys add acima. Para ver o ID da chave pública do atestador depois de o adicionar 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)')
    

Configure a política

Agora, pode configurar a sua política. Neste passo, exporta o ficheiro YAML da política para o seu sistema local e modifica a regra predefinida para que exija uma atestação por parte do atestador que definiu acima.

Para configurar a política, siga estes passos:

  1. Crie um novo ficheiro de política que permita imagens do sistema mantidas pela Google, defina evaluationMode como REQUIRE_ATTESTATION e adicione um nó denominado requireAttestationsBy que faça referência ao atestador que 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 ficheiro YAML da política para a Binary Authorization:

    gcloud container binauthz policy import /tmp/policy.yaml
    

Para mais informações sobre a configuração de uma política, consulte o artigo Configure uma política através da CLI gcloud.

Teste a política

Pode testar a política que configurou acima tentando implementar uma imagem de contentor de exemplo no cluster. A política bloqueia a implementação porque a atestação necessária não foi feita.

Para este tutorial, pode usar imagens de amostra do Artifact Registry. A imagem do Artifact Registry encontra-se no caminho us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0. O caminho contém uma imagem pública criada pela Google que contém uma aplicação de exemplo "Hello, World!".

Primeiro, tente implementar a imagem:

kubectl run hello-server --image us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0 --port 8080

Agora, valide se a implementaçã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 implementada:

No resources found.

Pode obter mais detalhes sobre a implementação:

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

Vê uma resposta semelhante à seguinte:

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

Neste resultado:

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

Certifique-se de que elimina a implementação para poder continuar para o passo seguinte:

kubectl delete deployment hello-server

Crie uma atestação

Uma atestação é um documento digital criado por um signatário que certifica que o GKE tem autorização para implementar a imagem de contentor associada. O processo de criação de uma atestação é, por vezes, denominado "assinatura de uma imagem". Um signatário pode ser uma pessoa ou, mais frequentemente, um processo automatizado que é executado quando uma imagem de contentor é criada. A assinatura é criada através da chave privada de um par de chaves. No momento da implementação, o agente de aplicação da Autorização binária usa a chave pública do atestador para validar a assinatura na atestação.

Neste tutorial, a sua atestação indica simplesmente que autoriza a imagem para implementação.

Para criar uma atestação, siga estes passos:

  1. Defina variáveis que armazenam o caminho do registo e o resumo da imagem:

    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 a atestação, faça o seguinte:

    PKIX Cloud KMS

    Para criar a atestação com 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 a atestação com a chave local, faça o seguinte:

    1. Gere o payload de atestação:

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

      O ficheiro JSON do payload tem o seguinte conteúdo:

      {
      "critical": {
        "identity": {
          "docker-reference": "us-docker.pkg.dev/google-samples/containers/gke/hello-app"
        },
        "image": {
          "docker-manifest-digest": "sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea
      882eb722c3be4"
        },
        "type": "Google cloud binauthz container signature"
      }
      }
      
    2. Para assinar a carga útil com a sua chave privada PKIX e gerar um ficheiro de assinatura, execute o seguinte comando:

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

      O ficheiro de assinatura é a versão assinada do ficheiro JSON de dados que criou anteriormente neste guia.

    3. Crie e valide a atestação:

      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 encontrou em Gere um par de chaves PKIX acima.

      A flag validate verifica se a atestação pode ser validada pelo atestador que configurou na sua política.

  3. Verifique se a atestação foi criada:

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

Para mais informações sobre a criação de atestações, consulte o artigo Criar atestações.

Volte a testar a política

Mais uma vez, teste a política implementando uma imagem de contentor de amostra no cluster. Desta vez, tem de implementar a imagem através do resumo, em vez de uma etiqueta como 1.0 ou latest, uma vez que a autorização binária usa o resumo para procurar atestações. Aqui, a autorização binária permite a implementação da imagem porque foi feita a atestação necessária.

Para implementar a imagem, siga estes passos:

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

Para verificar se a imagem foi implementada:

kubectl get pods

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

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