在 Cloud Build 流水线中使用 On-Demand Scanning

在 Cloud Build 流水线中使用 On-Demand Scanning API,可以在容器映像存在与预定义级别匹配的漏洞时阻止构建。

本教程将向您展示如何使用 Cloud Build 从源代码构建容器映像,扫描映像是否存在漏洞,检查漏洞的严重级别,以及在没有特定严重级别的漏洞时将映像推送到 Artifact Registry。

我们建议您为本教程创建一个新 Google Cloud 项目,并 在隔离的环境中完成这些步骤。

目标

  • 使用 Cloud Build 构建映像。
  • 使用 On-Demand Scanning API 扫描构建的映像。
  • 评估可接受的漏洞级别。
  • 将映像存储在 Artifact Registry 中。

费用

在本文档中,您将使用的以下收费组件: Google Cloud

您可使用 价格计算器 根据您的预计使用情况来估算费用。

新 Google Cloud 用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud的新用户, 请创建账号,以评估我们的产品在 实际场景中的表现。新客户还可获享 $300 赠金,用于 运行、测试和部署工作负载。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the On-Demand Scanning, Cloud Build, and Artifact Registry APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  5. 安装 Google Cloud CLI。

  6. 如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI

  7. 如需初始化 gcloud CLI,请运行以下命令:

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  9. Verify that billing is enabled for your Google Cloud project.

  10. Enable the On-Demand Scanning, Cloud Build, and Artifact Registry APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  11. 安装 Google Cloud CLI。

  12. 如果您使用的是外部身份提供方 (IdP),则必须先使用联合身份登录 gcloud CLI

  13. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init

所需的角色

您与 Cloud Build 搭配使用的服务帐号需要具有以下角色:

默认的 Cloud Build 服务帐号具有同一项目中 Artifact Registry 仓库所需的权限。如果您的仓库与您用于 Cloud Build 的项目位于同一项目中,则只需授予 On-Demand Scanning Admin 角色。

如果您使用的是用户提供的 Cloud Build 服务帐号,则需要授予这两个角色。

准备源文件

在本教程中,您将使用 Dockerfile 构建映像。Dockerfile 是一个源文件,其中包含 Docker 如何构建映像的说明。

  1. 打开终端,创建一个名为 ods-tutorial 的新目录,然后导航到该目录:

    mkdir ods-tutorial && cd ods-tutorial
    
  2. 创建名为 Dockerfile 且包含以下内容的文件:

    # Debian10 image
    FROM gcr.io/google-appengine/debian10:latest
    
    # Ensures that the built image is always unique
    RUN apt-get update && apt-get -y install uuid-runtime && uuidgen > /IAMUNIQUE
    

创建 Artifact Registry 仓库

  1. 将项目 ID 设置为与您启用 API 的项目相同的项目:

    gcloud config set project PROJECT_ID
    
  2. us-central1 位置创建一个名为 ods-build-repo 的 Docker 仓库:

    gcloud artifacts repositories create ods-build-repo --repository-format=docker \
    --location=us-central1 --description="Repository for scan and build"
    
  3. 验证您的仓库是否已成功创建:

    gcloud artifacts repositories list
    

构建和扫描

在本部分中,您将使用构建配置文件运行构建流水线 。构建配置文件会指示 Cloud Build 如何根据您的规范执行多项任务。

  1. ods-tutorial/ 文件夹中,创建包含以下内容的 cloudbuild.yaml 文件:

    steps:
       - id: build
         name: gcr.io/cloud-builders/docker
         entrypoint: /bin/bash
         args:
         - -c
         - |
           docker build -t us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest -f ./Dockerfile . &&
           docker image inspect us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest --format \
           '{{index .RepoTags 0}}@{{.Id}}' > /workspace/image-digest.txt &&
           cat image-digest.txt
       - id: scan
         name: gcr.io/google.com/cloudsdktool/cloud-sdk
         entrypoint: /bin/bash
         args:
         - -c
         - |
           gcloud artifacts docker images scan us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest \
           --format='value(response.scan)' > /workspace/scan_id.txt
       - id: severity check
         name: gcr.io/google.com/cloudsdktool/cloud-sdk
         entrypoint: /bin/bash
         args:
         - -c
         - |
           gcloud artifacts docker images list-vulnerabilities $(cat /workspace/scan_id.txt) \
           --format='value(vulnerability.effectiveSeverity)' | if grep -Exq $_SEVERITY; \
           then echo 'Failed vulnerability check' && exit 1; else exit 0; fi
       - id: push
         name: gcr.io/cloud-builders/docker
         entrypoint: /bin/bash
         args:
         - -c
         - |
           docker push us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest
    images: ['us-central1-docker.pkg.dev/$_PROJECT_ID/ods-build-repo/ods-test:latest']
    
    

    此文件包含之前在 Artifact Registry 中创建的位置和仓库。如果您决定使用不同的值,请相应地修改 cloudbuild.yaml 文件。PROJECT_IDSEVERITY 的值在构建命令中传递给脚本。

  2. 指定要阻止的漏洞 SEVERITY 级别,然后启动构建。

    您可以为 SEVERITY 使用以下值:

    • CRITICAL
    • HIGH
    • MEDIUM
    • LOW

    您可以使用正则表达式指定多个严重级别。

    在以下示例中,您同时指定了 CRITICALHIGH 严重级别值。这会指示 Cloud Build 检查严重级别为 HIGH 或更高的漏洞。

    gcloud builds submit --substitutions=_PROJECT_ID=PROJECT_ID,_SEVERITY='"CRITICAL|HIGH"' \
    --config cloudbuild.yaml
    

    地点

    • PROJECT_ID 是项目 ID。
    • SEVERITY 可让您设置要阻止的严重级别。如果 On-Demand Scanning API 发现与任何指定严重级别匹配的漏洞,构建就会失败。

了解检测结果

当您将 SEVERITY 值设置为 CRITICAL|HIGH 后,On-Demand Scanning API 在扫描漏洞后,会查看是否存在 HIGH 级别和更严重的 CRITICAL 级别的漏洞。如果在映像中未找到匹配的漏洞,构建就会成功,并且 Cloud Build 会将映像推送到 Artifact Registry。

输出类似于以下内容:

DONE
--------------------------------------------------------------------------------------------------------------------------------------------

ID                                    CREATE_TIME                DURATION  SOURCE                                                                                         IMAGES                                                                        STATUS
abb3ce73-6ae8-41d1-9080-7d74a7ecd7bc  2021-03-15T06:50:32+00:00  1M48S     gs://ods-tests_cloudbuild/source/1615791031.906807-a648d10faf4a46d695c163186a6208d5.tgz  us-central1-docker.pkg.dev/ods-tests/ods-build-repo/ods-test (+1 more)  SUCCESS

如果 On-Demand Scanning API 在映像中发现 HIGHCRITICAL 漏洞,则 scan 构建步骤会失败,后续构建步骤不会启动,并且 Cloud Build 不会将映像推送到 Artifact Registry。

输出类似于以下内容:

Step #2 - "severity check": Failed vulnerability check
Finished Step #2 - "severity check"
ERROR
ERROR: build step 2 "gcr.io/cloud-builders/gcloud" failed: step exited with non-zero status: 1

在本教程中,您的结果可能会有所不同,因为示例源代码是公开提供的 Linux 发行版 debian10:latest。Linux 发行版和相关漏洞数据会持续更新。

如需了解有助于保护软件供应链的其他 Google Cloud 工具和最佳实践,请参阅软件供应链安全

如需详细了解 Linux 漏洞管理最佳实践,您可以使用 Linux 基金会提供的免费在线培训。请参阅开发安全软件

清理

为避免因本教程中使用的资源导致您的 Google Cloud 账号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

  1. 在 Google Cloud 控制台中,前往 管理资源 页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击 关闭以删除项目。

删除各个资源

在移除代码库之前,请确保您要保留的任何映像在其他位置提供。

如需删除代码库,请执行以下操作:

控制台

  1. 在 Google Cloud 控制台中打开代码库 页面。

    打开“代码库”页面

  2. 在代码库列表中,选择 ods-build-repo 代码库。

  3. 点击删除

gcloud

如需删除 ods-build-repo 代码库,请运行以下命令:

gcloud artifacts repositories delete ods-build-repo --location=us-central1

后续步骤