Integração da verificação de vulnerabilidades com o Kritis Signer

Este guia explica como criar atestados de autorização binária, baseado na verificação de vulnerabilidades do Container Analysis, usando o Kritis Signer.

Visão geral do Kritis Signer

Vulnerabilidades de software são pontos fracos que podem causar uma falha acidental do sistema ou ser explorados intencionalmente. Impedir a implantação de imagens vulneráveis é um aspecto importante da segurança da cadeia de suprimentos.

Kritis Signer é uma ferramenta de linha de comando de código aberto que pode criar atestados de autorização binária com base nos serviços de pipeline de CI/CD, como a verificação de vulnerabilidades. É possível usar o Kritis Signer como um criador personalizado do Cloud Build para recuperar resultados da verificação de vulnerabilidades do Container Analysis e verificar os resultados com uma política de vulnerabilidade que você configurar.

Se todas as vulnerabilidades identificadas nos resultados atenderem à política de assinatura de vulnerabilidades, o Kritis Signer criará um atestado de autorização binária para a imagem associada.

Se alguma das vulnerabilidades identificadas nos resultados violar a política de vulnerabilidades, o Kritis Signer não criará um atestado.

Sem um atestado verificado, o implementador de autorização binária nega a implantação da imagem.

Objetivos

Neste guia, você realizará as seguintes ações:

  1. Configure o Kritis Signer como um criador personalizado do Cloud Build.
  2. Veja uma política de assinatura de vulnerabilidades.
  3. Execute o criador personalizado do Kritis Signer para criar atestados com base nos resultados da verificação de vulnerabilidades.

Custos

Neste guia, usamos os seguintes produtos do Google Cloud. Os custos podem ser incorridos.

  • Container Registry
  • Análise de contêiner
  • Cloud Build
  • Cloud Key Management Service

Use a Calculadora de preços para gerar uma estimativa de custo com base no uso previsto.

Antes de começar

Nesta seção, você fará uma configuração única do sistema.

Configure o ambiente

  1. Armazene o projeto do Google Cloud em uma variável de ambiente.

export PROJECT_ID=project-id

em que project-id é o ID do projeto do Google Cloud.

  1. Armazene o número do projeto em uma variável de ambiente para etapas futuras:

    export PROJECT_NUMBER=$(gcloud projects list --filter="${PROJECT_ID}" \
     --format="value(PROJECT_NUMBER)")
    
  2. Ative APIs:

    Para garantir que os serviços necessários para este guia estejam ativados, execute o seguinte comando:

    gcloud --project=$PROJECT_ID services enable \
      cloudbuild.googleapis.com \
      containerregistry.googleapis.com \
      containeranalysis.googleapis.com \
      containerscanning.googleapis.com \
      cloudkms.googleapis.com
    

Configurar papéis do IAM

Execute os seguintes comandos para configurar a conta de serviço do Cloud Build com os seguintes papéis:

  • containeranalysis.notes.editor: adiciona o papel Editor de notas do Container Analysis para gerenciar o atestador.
  • containeranalysis.notes.occurrences.viewer: adiciona o papel Ocorrências do Container Analysis para observações para gerenciar as ocorrências de vulnerabilidade e de atestado.
  • roles/containeranalysis.occurrences.editor: adiciona o papel Editor de ocorrências do Container Analysis para criar ocorrências de atestado no Container Analysis.
  • cloudkms.signer: adiciona o papel Signatário de CryptoKey do Cloud KMS que permite que a conta de serviço acesse o serviço de assinatura do Cloud KMS.

    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/containeranalysis.notes.editor
    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/containeranalysis.notes.occurrences.viewer
    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/containeranalysis.occurrences.editor
    gcloud projects add-iam-policy-binding $PROJECT_ID --member serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com --role roles/cloudkms.signer
    

Configurar o criador personalizado do Kritis Signer

Nesta seção, você realiza uma configuração única do criador personalizado do Kritis Signer. Depois de receber, criar e enviar o Kritis Signer, ele pode ser usado em qualquer pipeline do Cloud Build.

Esta seção mostra como:

  • Clonar o repositório Kritis.
  • Criar o builder personalizado do Cloud Build do Kritis Signer.
  • Envie o Kritis Signer para o Container Registry e disponibilize-o para uso como uma etapa de versão do Cloud Build.

Execute os seguintes comandos para conseguir os arquivos de código e configuração usados neste guia:

  1. Clone o repositório Kritis:

     git clone --branch signer-v1.0.0 https://github.com/grafeas/kritis.git
    

    Esse repositório contém o seguinte:

    • Código-fonte de Kritis, que também inclui o Kritis Signer.
    • Um arquivo de configuração do Cloud Build usado pelo Cloud Build para produzir o criador personalizado do Kritis Signer.
    • Um exemplo de política de assinatura de vulnerabilidade.
    • Exemplo de arquivos de configuração do Cloud Build. Cada arquivo de configuração demonstra um pipeline de verificação de vulnerabilidades com base em Kritis Signer.
  2. Navegue até o diretório kritis/:

    cd kritis
    
  3. Construa e registre o criador personalizado do Kritis Signer.

    Esta etapa única de configuração cria o criador personalizado do Kritis Signer e o registra com o Cloud Build. Depois de registrado, o builder personalizado estará disponível para uso em qualquer pipeline do Cloud Build.

    gcloud --project=$PROJECT_ID builds submit . --config deploy/kritis-signer/cloudbuild.yaml
    

Veja uma política de assinatura de vulnerabilidades existente

Nesta seção, mostramos um exemplo de política de assinatura de vulnerabilidades do Kritis Signer.

A Kritis Signer verifica as vulnerabilidades identificadas pelo Container Analysis em relação a esta política.

É possível editar esta política para lista de permissões:

  • Pontuações de gravidade qualificadas associadas a vulnerabilidades identificadas, conforme descrito na especificação do CVSS.
  • Vulnerabilidades específicas (CVEs).

Para ver a política de assinatura de vulnerabilidades:

cat samples/signer/policy.yaml

A aparência será semelhante a esta:

apiVersion: kritis.grafeas.io/v1beta1
kind: VulnzSigningPolicy
metadata:
  name: my-vsp
spec:
  imageVulnerabilityRequirements:
    maximumFixableSeverity: MEDIUM
    maximumUnfixableSeverity: MEDIUM
    allowlistCVEs:
    - projects/goog-vulnz/notes/CVE-2020-10543
    - projects/goog-vulnz/notes/CVE-2020-10878
    - projects/goog-vulnz/notes/CVE-2020-14155

Em que:

  • maximumUnfixableSeverity e maximumFixableSeverity podem ser um destes:

    • CRITICAL: uma pontuação de Critical, de acordo com a especificação CVSS
    • HIGH: uma pontuação de High, de acordo com a especificação CVSS
    • MEDIUM: uma pontuação de Medium, de acordo com a especificação CVSS
    • LOW: uma pontuação de Low, de acordo com a especificação CVSS
    • BLOCK_ALL: o atestado não será criado se alguma vulnerabilidade for identificada.
    • ALLOW_ALL: a confirmação é criada mesmo quando há vulnerabilidades.
  • allowlistCVEs é uma lista de vulnerabilidades. Cada entrada precisa corresponder exatamente ao nome da nota.

Criar uma chave de assinatura do Cloud KMS

As chaves do Cloud Key Management Service são usadas para criar o atestador e o atestado.

  1. Crie um novo keyring do Cloud KMS com o nome my-key-ring-1:

    gcloud --project=$PROJECT_ID kms keyrings create my-key-ring-1 \
       --location global
    
  2. Crie uma nova chave do Cloud KMS chamada my-signing-key-1 no keyring:

    gcloud --project=$PROJECT_ID kms keys create my-signing-key-1 \
        --keyring my-key-ring-1 \
        --location global \
        --purpose "asymmetric-signing" \
        --default-algorithm "rsa-sign-pkcs1-2048-sha256"
    
  3. Armazene o algoritmo de resumo e o Cloud KMS em uma variável de ambiente para etapas futuras:

    export KMS_DIGEST_ALG=SHA256
    export KMS_KEY_NAME=projects/$PROJECT_ID/locations/global/keyRings/my-key-ring-1/cryptoKeys/my-signing-key-1/cryptoKeyVersions/1
    

Definir o nome de uma nota

Todos os atestados referenciam uma observação do Container Analysis. A Kritis Signer cria automaticamente uma nota para um determinado nome. Também é possível reutilizar os nomes de notas existentes.

export NOTE_ID=my-signer-note
export NOTE_NAME=projects/${PROJECT_ID}/notes/${NOTE_ID}

Criar atestados com Kritis Signer em um pipeline do Cloud Build

Nesta seção, demonstramos como usar o criador de nuvem personalizado do Kritis Signer para criar atestados de autorização binária com base nos resultados da verificação de vulnerabilidades.

Nas etapas a seguir, demonstramos como o Kritis Signer funciona com os arquivos de configuração de compilação de exemplo no repo do Kritis Signer. Cada arquivo de configuração de exemplo contém as seguintes etapas de criação:

  1. Uma etapa docker build que cria uma imagem de contêiner do Docker.
  2. Uma etapa docker push que envia a imagem de contêiner recém-criada ao Container Registry.
  3. Uma etapa vulnsign que verifica e assina a imagem do contêiner:

    1. Como aguardar o Container Analysis retornar resultados de vulnerabilidade na imagem de contêiner recém-criada.
    2. Como verificar as descobertas em relação à política de assinatura de vulnerabilidades.
    3. Criação do atestado se os resultados satisfizerem a política de vulnerabilidade.

Você envia cada um dos exemplos de compilação para o Cloud Build. Cada compilação produz um resultado de vulnerabilidade:

  • Caso de falha: na primeira versão, o resultado da vulnerabilidade viola a política de assinatura de vulnerabilidade. Essa versão vai falhar.
  • Caso de sucesso: na segunda versão, o resultado da vulnerabilidade não deve violar a política de assinatura de vulnerabilidade. Esta versão precisa ser bem-sucedida.

Enviar a amostra de amostra do caso de falha

Este exemplo cria uma imagem de contêiner com base no Debian 9. No momento, o contêiner tem uma vulnerabilidade que não é permitida pela política de assinatura de vulnerabilidade descrita acima. O criador personalizado Kritis Signer não produz um atestado.

  1. (Opcional) Veja o arquivo de configuração da compilação no caso de falha.

    cat samples/signer/cloudbuild-bad.yaml
    
  2. Envie o build:

    gcloud --project=$PROJECT_ID builds submit \
      --substitutions=_KMS_KEY_NAME=$KMS_KEY_NAME,_KMS_DIGEST_ALG=$KMS_DIGEST_ALG,_NOTE_NAME=$NOTE_NAME \
      --config=samples/signer/cloudbuild-bad.yaml samples/signer
    

    O resultado será assim:

    "ERROR: (gcloud.builds.submit) build build-id completed with status "FAILURE"
    
  3. Observe Build ID na saída da criação.

    Defina a variável de ambiente $BUILD_ID como build-id:

    export BUILD_ID=build-id
    

    Essa variável será usada na próxima etapa.

  4. Como alternativa, você pode encontrar o ID da versão mais recente executando o seguinte comando:

    gcloud builds list --limit 1
    

    O ID da versão é o primeiro campo retornado. Altere o valor --limit para ver mais versões ou remova completamente a sinalização para ver todas as versões.

  5. Verificar o resultado:

     gsutil cat gs://${PROJECT_NUMBER}.cloudbuild-logs.googleusercontent.com/log-${BUILD_ID}.txt | grep "does not pass VulnzSigningPolicy"
    

Envie a amostra de amostra do caso de sucesso

Este exemplo cria uma imagem de contêiner que contém vulnerabilidades que não violam a política de assinatura de vulnerabilidades. O criador personalizado de Kritis Signer produz uma confirmação.

Para enviar a amostra da compilação do caso de sucesso para o Cloud Build, faça o seguinte:

  1. (Opcional) Visualizar o arquivo de configuração da compilação no caso de sucesso

    cat samples/signer/cloudbuild-good.yaml
    
  2. Envie o build:

    gcloud --project=$PROJECT_ID builds submit \
      --substitutions=_KMS_KEY_NAME=$KMS_KEY_NAME,_KMS_DIGEST_ALG=$KMS_DIGEST_ALG,_NOTE_NAME=$NOTE_NAME \
      --config=samples/signer/cloudbuild-good.yaml samples/signer
    
  3. Novamente, anote o ID da versão e armazene-o na variável de ambiente $BUILD_ID:

    export BUILD_ID=build-id
    
  4. Por fim, para verificar o resultado, digite o seguinte comando:

    gcloud --project=$PROJECT_ID builds describe $BUILD_ID | grep status
    

A seguir