Como bloquear implantações com autenticação binária

1. Introdução

A autorização binária é um controle de segurança de tempo de implantação que garante que apenas imagens de contêineres confiáveis sejam implantadas no Google Kubernetes Engine (GKE) ou no Cloud Run. Com esse controle, é possível solicitar que todas as imagens sejam assinadas por autoridades confiáveis durante o processo de desenvolvimento e, depois disso, aplicar a validação da assinatura ao implantar. Ao aplicar a validação, você assume maior controle sobre o ambiente de contêineres e garante que apenas imagens verificadas sejam integradas ao processo de criação e lançamento.

O diagrama a seguir mostra os componentes em uma configuração de autorização binária/Cloud Build:

Pipeline de atestado da autorização binária do Cloud Build.**Figura 1.**Pipeline do Cloud Build que cria um atestado de autorização binária.

Nesse pipeline:

  1. O código para criar a imagem do contêiner é enviado para um repositório de origem, como o Cloud Source Repositories.
  2. A ferramenta de integração contínua (CI, na sigla em inglês), o Cloud Build cria e testa o contêiner.
  3. A criação envia a imagem do contêiner para o Container Registry ou outro registro que armazena as imagens criadas.
  4. O Cloud Key Management Service, que fornece gerenciamento de chaves para o par de chaves criptográficas, assina a imagem do contêiner. Depois, a assinatura resultante é armazenada em um atestado recém-criado.
  5. No momento da implantação, o atestador verifica o atestado usando a chave pública do par de chaves. A autorização binária aplica a política ao exigir atestados assinados para implantar a imagem do contêiner.

Neste laboratório, você vai se concentrar nas ferramentas e técnicas para proteger artefatos implantados. Este laboratório se concentra em artefatos (contêineres) depois que eles foram criados, mas não implantados em nenhum ambiente específico.

O que você vai aprender

  • Assinatura de imagens
  • Políticas de controle de admissão
  • Assinatura de imagens digitalizadas
  • Autorização de imagens assinadas
  • imagens não assinadas bloqueadas

2. Configuração e requisitos

Configuração de ambiente personalizada

  1. Faça login no Console do Google Cloud e crie um novo projeto ou reutilize um existente. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • O Nome do projeto é o nome de exibição para os participantes do projeto. É uma string de caracteres não usada pelas APIs do Google É possível atualizar o local a qualquer momento.
  • O ID do projeto precisa ser exclusivo em todos os projetos do Google Cloud e não pode ser mudado após a definição. O console do Cloud gera automaticamente uma string exclusiva. Em geral, não importa o que seja. Na maioria dos codelabs, é necessário fazer referência ao ID do projeto, normalmente identificado como PROJECT_ID. Se você não gostar do ID gerado, crie outro aleatório. Se preferir, teste o seu e confira se ele está disponível. Ele não pode ser mudado após essa etapa e permanece durante o projeto.
  • Para sua informação, há um terceiro valor, um Número do projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
  1. Em seguida, ative o faturamento no console do Cloud para usar os recursos/APIs do Cloud. A execução deste codelab não será muito cara, se tiver algum custo. Para desligar os recursos e evitar cobranças além deste tutorial, exclua os recursos criados ou o projeto inteiro. Novos usuários do Google Cloud estão qualificados para o programa de US$ 300 de avaliação sem custos.

Configuração do ambiente

No Cloud Shell, defina o ID e o número do projeto. Salve-as como variáveis PROJECT_ID e PROJECT_ID.

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID \
    --format='value(projectNumber)')

Ativar serviços

Ative todos os serviços necessários:

gcloud services enable \
  cloudkms.googleapis.com \
  cloudbuild.googleapis.com \
  container.googleapis.com \
  containerregistry.googleapis.com \
  artifactregistry.googleapis.com \
  containerscanning.googleapis.com \
  ondemandscanning.googleapis.com \
  binaryauthorization.googleapis.com 

Criar repositório do Artifact Registry

Neste laboratório, você vai usar o Artifact Registry para armazenar e verificar suas imagens. Crie o repositório com o seguinte comando.

gcloud artifacts repositories create artifact-scanning-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Docker repository"

Configure o Docker para usar suas credenciais do gcloud ao acessar o Artifact Registry.

gcloud auth configure-docker us-central1-docker.pkg.dev

Crie e acesse um diretório de trabalho

mkdir vuln-scan && cd vuln-scan

Definir uma imagem de amostra

Crie um arquivo chamado Dockerfile com o conteúdo a seguir.

cat > ./Dockerfile << EOF
from python:3.8-slim  

# App
WORKDIR /app
COPY . ./

RUN pip3 install Flask==2.1.0
RUN pip3 install gunicorn==20.1.0

CMD exec gunicorn --bind :\$PORT --workers 1 --threads 8 main:app

EOF

Crie um arquivo chamado main.py com o seguinte conteúdo:

cat > ./main.py << EOF
import os
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    name = os.environ.get("NAME", "Worlds")
    return "Hello {}!".format(name)

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
EOF

Criar e enviar a imagem para o RA

Use o Cloud Build para criar e enviar automaticamente seu contêiner para o Artifact Registry.

gcloud builds submit . -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image

3. assinatura de imagens

O que é um atestador

Atestador

  • Essa pessoa/processo é responsável por um elo na cadeia de confiança do sistema.
  • O atestador tem uma chave criptográfica e assina uma imagem se ela passar pelo processo de aprovação.
  • O criador de políticas determina a política de forma abstrata e de alto nível, enquanto o atestador é responsável por aplicar concretamente algum aspecto da política.
  • Pode ser uma pessoa real, como um testador de controle de qualidade ou um gerente, ou um bot em um sistema de CI.
  • A segurança do sistema depende da confiabilidade dele, por isso é importante que as chaves privadas sejam mantidas em segurança.

Cada um desses papéis pode representar uma pessoa ou uma equipe na sua organização. Em um ambiente de produção, esses papéis provavelmente seriam gerenciados por projetos separados do Google Cloud Platform (GCP), e o acesso aos recursos seria compartilhado entre eles de forma limitada usando o Cloud IAM.

a37eb2ed54b9c2eb.png

Os atestadores na Autorização Binária são implementados na API Cloud Container Analysis, por isso é importante descrever como isso funciona antes de prosseguir. A API Container Analysis foi projetada para permitir que você associe metadados a imagens de contêiner específicas.

Por exemplo, uma nota pode ser criada para rastrear a vulnerabilidade Heartbleed. Os fornecedores de segurança criariam verificadores para testar as imagens de contêiner em busca da vulnerabilidade e criariam uma ocorrência associada a cada contêiner comprometido.

208aa5ebc53ff2b3.png

Além de rastrear vulnerabilidades, o Container Analysis foi projetado para ser uma API de metadados genérica. A autorização binária usa o Container Analysis para associar assinaturas às imagens de contêiner que estão sendo verificadas**.** Uma nota do Container Analysis é usada para representar um único atestador, e as ocorrências são criadas e associadas a cada contêiner que o atestador aprovou.

A API Binary Authorization usa os conceitos de "atestadores" e "atestados", mas eles são implementados usando as observações e ocorrências correspondentes na API Container Analysis.

63a701bd0057ea17.png

Criar uma nota de atestador

Uma nota de atestador é simplesmente um pequeno conjunto de dados que funciona como um rótulo para o tipo de assinatura que está sendo aplicado. Por exemplo, uma nota pode indicar uma verificação de vulnerabilidade, enquanto outra pode ser usada para aprovação de QA. A nota será referida durante o processo de assinatura.

919f997db0ffb881.png

Criar uma nota

cat > ./vulnz_note.json << EOM
{
  "attestation": {
    "hint": {
      "human_readable_name": "Container Vulnerabilities attestation authority"
    }
  }
}
EOM

Armazene a nota

NOTE_ID=vulnz_note

curl -vvv -X POST \
    -H "Content-Type: application/json"  \
    -H "Authorization: Bearer $(gcloud auth print-access-token)"  \
    --data-binary @./vulnz_note.json  \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/?noteId=${NOTE_ID}"

Verifique a nota

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

Sua nota agora está salva na API Container Analysis.

Como criar um atestador

Os atestadores são usados para realizar o processo real de assinatura de imagem e anexarão uma ocorrência da nota à imagem para verificação posterior. Para usar o atestador, você também precisa registrar a nota na Autorização Binária:

ed05d438c79b654d.png

Criar atestador

ATTESTOR_ID=vulnz-attestor

gcloud container binauthz attestors create $ATTESTOR_ID \
    --attestation-authority-note=$NOTE_ID \
    --attestation-authority-note-project=${PROJECT_ID}

Verificar atestador

gcloud container binauthz attestors list

A última linha indica NUM_PUBLIC_KEYS: 0. Você vai fornecer as chaves em uma etapa posterior.

O Cloud Build cria automaticamente o atestador built-by-cloud-build no seu projeto quando você executa um build que gera imagens. O comando acima retorna dois atestadores: vulnz-attestor e built-by-cloud-build. Depois que as imagens são criadas, o Cloud Build assina e cria atestados automaticamente.

Como adicionar um papel do IAM

A conta de serviço da Autorização Binária precisa ter direitos para visualizar as anotações de atestado. Forneça o acesso com a seguinte chamada de API:

PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}"  --format="value(projectNumber)")

BINAUTHZ_SA_EMAIL="service-${PROJECT_NUMBER}@gcp-sa-binaryauthorization.iam.gserviceaccount.com"


cat > ./iam_request.json << EOM
{
  'resource': 'projects/${PROJECT_ID}/notes/${NOTE_ID}',
  'policy': {
    'bindings': [
      {
        'role': 'roles/containeranalysis.notes.occurrences.viewer',
        'members': [
          'serviceAccount:${BINAUTHZ_SA_EMAIL}'
        ]
      }
    ]
  }
}
EOM

Use o arquivo para criar a política do IAM

curl -X POST  \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    --data-binary @./iam_request.json \
    "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/notes/${NOTE_ID}:setIamPolicy"

Adicionar uma chave do KMS

1e3af7c177f7a311.png

Antes de usar esse atestador, sua autoridade precisa criar um par de chaves criptográficas que possa ser usado para assinar imagens de contêiner. Isso pode ser feito com o Google Cloud Key Management Service (KMS).

Primeiro, adicione algumas variáveis de ambiente para descrever a nova chave

KEY_LOCATION=global
KEYRING=binauthz-keys
KEY_NAME=codelab-key
KEY_VERSION=1

Crie um keyring para armazenar um conjunto de chaves

gcloud kms keyrings create "${KEYRING}" --location="${KEY_LOCATION}"

Crie um novo par de chaves de assinatura assimétricas para o atestador

gcloud kms keys create "${KEY_NAME}" \
    --keyring="${KEYRING}" --location="${KEY_LOCATION}" \
    --purpose asymmetric-signing   \
    --default-algorithm="ec-sign-p256-sha256"

A chave vai aparecer na página do KMS no console do Google Cloud.

Agora, associe a chave ao atestador usando o comando binauthz do gcloud:

gcloud beta container binauthz attestors public-keys add  \
    --attestor="${ATTESTOR_ID}"  \
    --keyversion-project="${PROJECT_ID}"  \
    --keyversion-location="${KEY_LOCATION}" \
    --keyversion-keyring="${KEYRING}" \
    --keyversion-key="${KEY_NAME}" \
    --keyversion="${KEY_VERSION}"

Se você exibir a lista de autoridades novamente, verá uma chave registrada:

gcloud container binauthz attestors list

Como criar um atestado assinado

Neste ponto, você já configurou os recursos que permitem assinar imagens. Use o atestador que você criou anteriormente para assinar a imagem de contêiner com a qual você tem trabalhado.

858d7e6feeb6f159.png

Um atestado precisa incluir uma assinatura criptográfica para declarar que o atestador verificou uma imagem de contêiner específica e que ela é segura para ser executada no cluster. Para especificar qual imagem de contêiner atestar, determine o resumo dela.

CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image

DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:latest \
    --format='get(image_summary.digest)')

Agora você pode usar a gcloud para criar sua atestação. O comando recebe os detalhes da chave que você quer usar para assinar e a imagem do contêiner específica que você quer aprovar

gcloud beta container binauthz attestations sign-and-create  \
    --artifact-url="${CONTAINER_PATH}@${DIGEST}" \
    --attestor="${ATTESTOR_ID}" \
    --attestor-project="${PROJECT_ID}" \
    --keyversion-project="${PROJECT_ID}" \
    --keyversion-location="${KEY_LOCATION}" \
    --keyversion-keyring="${KEYRING}" \
    --keyversion-key="${KEY_NAME}" \
    --keyversion="${KEY_VERSION}"

Em termos de Container Analysis, isso vai criar uma nova ocorrência e anexá-la à nota do seu atestador. Para garantir que tudo funcionou como esperado, liste suas atestações

gcloud container binauthz attestations list \
   --attestor=$ATTESTOR_ID --attestor-project=${PROJECT_ID}

4. Políticas de controle de admissão

A Autorização Binária é um recurso do GKE e do Cloud Run que permite validar regras antes que uma imagem de contêiner possa ser executada. A validação é executada em qualquer solicitação para executar uma imagem, seja de um pipeline de CI/CD confiável ou de um usuário tentando implantar uma imagem manualmente. Com esse recurso, você protege seus ambientes de execução de forma mais eficaz do que apenas verificações de pipeline de CI/CD.

Para entender essa capacidade, você vai modificar a política padrão do GKE para aplicar uma regra de autorização rigorosa.

Criar o cluster do GKE

Criar um cluster (GKE) com a Autorização Binária ativada:

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

Permita que o Cloud Build faça a implantação nesse cluster:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/container.developer"

Política "Permitir tudo"

Primeiro, verifique o estado da política padrão e sua capacidade de implantar qualquer imagem

  1. Analisar a política atual
gcloud container binauthz policy export
  1. Observe que a política de aplicação está definida como ALWAYS_ALLOW

evaluationMode: ALWAYS_ALLOW

  1. Implante a amostra para verificar se é possível implantar alguma coisa
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. Verificar se a implantação funcionou
kubectl get pods

Você vai ver a seguinte saída:

161db370d99ffb13.png

  1. Excluir implantação
kubectl delete pod hello-server

Política "Negar tudo"

Agora atualize a política para proibir todas as imagens.

  1. Exporte a política atual para um arquivo editável
gcloud container binauthz policy export  > policy.yaml
  1. Alterar a política

Em um editor de texto, mude o "evaluationMode" de ALWAYS_ALLOW para ALWAYS_DENY.

edit policy.yaml

O arquivo YAML da política será exibido da seguinte maneira:

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

Essa política é relativamente simples. A linha globalPolicyEvaluationMode declara que esta política estende a política global definida pelo Google. Isso permite que todos os contêineres oficiais do GKE sejam executados por padrão. Além disso, a política declara uma defaultAdmissionRule que afirma que todos os outros pods serão rejeitados. A regra de admissão inclui uma linha enforcementMode, que declara que todos os pods que não estiverem em conformidade com essa regra devem ser impedidos de serem executados no cluster.

Para instruções sobre como criar políticas mais complexas, consulte a documentação da Autorização Binária.

657752497e59378c.png

  1. Abra o terminal, aplique a nova política e aguarde alguns segundos para que a mudança seja propagada.
gcloud container binauthz policy import policy.yaml
  1. Tente implantar uma carga de trabalho de amostra
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
  1. A implantação falha com a seguinte mensagem:
Error from server (VIOLATES_POLICY): admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image gcr.io/google-samples/hello-app:1.0 denied by Binary Authorization default admission rule. Denied by always_deny admission rule

Reverter a política para permitir tudo

Antes de passar para a próxima seção, reverta as mudanças na política.

  1. Alterar a política

Em um editor de texto, mude o evaluationMode de ALWAYS_DENY para ALWAYS_ALLOW.

edit policy.yaml

O arquivo YAML da política será exibido da seguinte maneira:

globalPolicyEvaluationMode: ENABLE
defaultAdmissionRule:
  evaluationMode: ALWAYS_ALLOW
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
name: projects/PROJECT_ID/policy
  1. Aplicar a política revertida
gcloud container binauthz policy import policy.yaml

5. Assinatura de imagens digitalizadas

Você ativou a assinatura de imagens e usou o atestador manualmente para assinar sua imagem de amostra. Na prática, você precisa aplicar atestações durante processos automatizados, como pipelines de CI/CD.

Nesta seção, você vai configurar o Cloud Build para atestar imagens automaticamente.

Papéis

Adicione o papel Visualizador de atestador de autorização binária à conta de serviço do Cloud Build:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/binaryauthorization.attestorsViewer

Adicione o papel Signatário/Verificador de CryptoKey do Cloud KMS à conta de serviço do Cloud Build (assinatura baseada em KMS):

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/cloudkms.signerVerifier

Adicione o papel Anexador de notas do Container Analysis à conta de serviço do Cloud Build:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
  --member serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
  --role roles/containeranalysis.notes.attacher

Fornecer acesso à conta de serviço do Cloud Build

O Cloud Build vai precisar de direitos para acessar a API On-Demand Scanning. Forneça acesso com os comandos a seguir.

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/iam.serviceAccountUser"
        
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com" \
        --role="roles/ondemandscanning.admin"

Preparar a etapa de versão personalizada do Cloud Build

Você vai usar uma etapa de versão personalizada no Cloud Build para simplificar o processo de atestado. O Google fornece essa etapa do build personalizado, contendo mais funções auxiliares para simplificar o processo. Antes do uso, o código da etapa de versão personalizada precisa ser integrado a um contêiner e enviado ao Cloud Build. Para fazer isso, execute os seguintes comandos:

git clone https://github.com/GoogleCloudPlatform/cloud-builders-community.git
cd cloud-builders-community/binauthz-attestation
gcloud builds submit . --config cloudbuild.yaml
cd ../..
rm -rf cloud-builders-community

Adicionar uma etapa de assinatura ao seu cloudbuild.yaml

Nesta etapa, você vai adicionar a etapa de atestado ao seu pipeline do Cloud Build.

  1. Confira a etapa de assinatura abaixo.

Apenas revisão. Não copiar

#Sign the image only if the previous severity check passes
- id: 'create-attestation'
  name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
  args:
    - '--artifact-url'
    - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image'
    - '--attestor'
    - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
    - '--keyversion'
    - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'
  1. Escreva um arquivo cloudbuild.yaml com o pipeline completo abaixo.
cat > ./cloudbuild.yaml << EOF
steps:

# build
- id: "build"
  name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', '.']
  waitFor: ['-']

#Run a vulnerability scan at _SECURITY level
- id: scan
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    (gcloud artifacts docker images scan \
    us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image \
    --location us \
    --format="value(response.scan)") > /workspace/scan_id.txt

#Analyze the result of the scan
- id: severity check
  name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
      gcloud artifacts docker images list-vulnerabilities \$(cat /workspace/scan_id.txt) \
      --format="value(vulnerability.effectiveSeverity)" | if grep -Fxq CRITICAL; \
      then echo "Failed vulnerability check for CRITICAL level" && exit 1; else echo "No CRITICAL vulnerability found, congrats !" && exit 0; fi

#Retag
- id: "retag"
  name: 'gcr.io/cloud-builders/docker'
  args: ['tag',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image', 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#pushing to artifact registry
- id: "push"
  name: 'gcr.io/cloud-builders/docker'
  args: ['push',  'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good']


#Sign the image only if the previous severity check passes
- id: 'create-attestation'
  name: 'gcr.io/${PROJECT_ID}/binauthz-attestation:latest'
  args:
    - '--artifact-url'
    - 'us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good'
    - '--attestor'
    - 'projects/${PROJECT_ID}/attestors/$ATTESTOR_ID'
    - '--keyversion'
    - 'projects/${PROJECT_ID}/locations/$KEY_LOCATION/keyRings/$KEYRING/cryptoKeys/$KEY_NAME/cryptoKeyVersions/$KEY_VERSION'



images:
  - us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:good
EOF

Executar o build

gcloud builds submit

Analisar o build no histórico do Cloud Build

Abra o console do Cloud na página "Histórico do Cloud Build" e confira o build mais recente e a execução bem-sucedida das etapas de build.

6. Autorização de imagens assinadas

Nesta seção, você vai atualizar o GKE para usar a autorização binária para validar se a imagem tem uma assinatura da verificação de vulnerabilidades antes de permitir que ela seja executada.

d5c41bb89e22fd61.png

Atualizar a política do GKE para exigir atestado

Exigir que as imagens sejam assinadas pelo seu atestador adicionando clusterAdmissionRules à sua política BinAuth do GKE

Atualmente, seu cluster está executando uma política com uma regra: permitir contêineres de repositórios oficiais e rejeitar todos os outros.

Substitua a política pela configuração atualizada usando o comando abaixo.

COMPUTE_ZONE=us-central1-a

cat > binauth_policy.yaml << EOM
defaultAdmissionRule:
  enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
  evaluationMode: ALWAYS_DENY
globalPolicyEvaluationMode: ENABLE
clusterAdmissionRules:
  ${COMPUTE_ZONE}.binauthz:
    evaluationMode: REQUIRE_ATTESTATION
    enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
    requireAttestationsBy:
    - projects/${PROJECT_ID}/attestors/vulnz-attestor
EOM

Agora você tem um novo arquivo no disco chamado updated_policy.yaml. Agora, em vez de rejeitar todas as imagens, a regra padrão primeiro verifica seu atestador em busca de verificações.

822240fc0b02408e.png

Faça upload da nova política para a Autorização Binária:

gcloud beta container binauthz policy import binauth_policy.yaml

Implantar uma imagem assinada

Receba o resumo da imagem boa

CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image


DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:good \
    --format='get(image_summary.digest)')

Use o resumo na configuração do Kubernetes

cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
  name: deb-httpd
spec:
  selector:
    app: deb-httpd
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deb-httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deb-httpd
  template:
    metadata:
      labels:
        app: deb-httpd
    spec:
      containers:
      - name: deb-httpd
        image: ${CONTAINER_PATH}@${DIGEST}
        ports:
        - containerPort: 8080
        env:
          - name: PORT
            value: "8080"

EOM

Implantar o app no GKE

kubectl apply -f deploy.yaml

Analise a carga de trabalho no console e observe a implantação bem-sucedida da imagem.

7. imagens não assinadas bloqueadas

Criar uma imagem

Nesta etapa, você vai usar o Docker local para criar a imagem no cache local.

docker build -t us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad .

Envie a imagem não assinada para o repositório

docker push us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image:bad

Receba o resumo da imagem inadequada

CONTAINER_PATH=us-central1-docker.pkg.dev/${PROJECT_ID}/artifact-scanning-repo/sample-image


DIGEST=$(gcloud container images describe ${CONTAINER_PATH}:bad \
    --format='get(image_summary.digest)')

Use o resumo na configuração do Kubernetes

cat > deploy.yaml << EOM
apiVersion: v1
kind: Service
metadata:
  name: deb-httpd
spec:
  selector:
    app: deb-httpd
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deb-httpd
spec:
  replicas: 1
  selector:
    matchLabels:
      app: deb-httpd
  template:
    metadata:
      labels:
        app: deb-httpd
    spec:
      containers:
      - name: deb-httpd
        image: ${CONTAINER_PATH}@${DIGEST}
        ports:
        - containerPort: 8080
        env:
          - name: PORT
            value: "8080"

EOM

Tente implantar o app no GKE

kubectl apply -f deploy.yaml

Analise a carga de trabalho no console e observe o erro que indica que a implantação foi negada:

No attestations found that were valid and signed by a key trusted by the attestor

8. Parabéns!

Parabéns, você concluiu o codelab.

O que aprendemos:

  • assinatura de imagens
  • Políticas de controle de admissão
  • Assinatura de imagens digitalizadas
  • Autorização de imagens assinadas
  • imagens não assinadas bloqueadas

Qual é a próxima etapa?

Limpar

Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto ou mantenha o projeto e exclua cada um dos recursos.

Excluir o projeto

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para este tutorial.

Última atualização: 21/03/23