容器扫描

您的应用程序的 Docker 镜像本身可能基于包含已知漏洞的 Docker 镜像。通过在流水线中包含一个额外的容器扫描作业来扫描这些漏洞,并在合并请求中显示它们,您可以使用极狐GitLab 来审核基于 Docker 的应用程序。

容器扫描通常被认为是软件组合分析 (SCA) 的一部分。SCA 可以包含检查代码使用的项目的各个方面。这些项目通常来自从外部源导入的应用程序和系统依赖项,而不是来自您自己编写的项目。

极狐GitLab 提供容器扫描和依赖扫描,确保覆盖所有依赖类型。为了尽可能多地覆盖您的风险区域,我们鼓励您使用我们所有的安全扫描器。

极狐GitLab 同时提供容器扫描和依赖扫描,以确保覆盖所有这些依赖类型。为了尽可能多地覆盖您的风险区域,我们鼓励您使用我们所有的安全扫描器。有关这些功能的比较,请参阅依赖扫描与容器扫描的比较

极狐GitLab 集成了 Trivy 安全扫描器,以在容器中执行漏洞静态分析。

caution Grype 分析器不再被维护,除了有限的修复,如我们在我们的支持声明中解释的那样。Grype 分析器镜像的现有当前主版本将继续使用最新的安全公告数据库和操作系统软件包进行更新,直至极狐GitLab 19.0 版本。到那时,该分析器将停止工作。

极狐GitLab 会在目标分支和源分支间对比找到的漏洞,然后:

Container Scanning Widget

功能

功能 在免费和专业版中 在綦江那汇总
自定义设置(变量覆盖离线环境支持 等) Yes Yes
将 JSON 报告作为 CI 产物进行查看 Yes Yes
生成 CycloneDX SBOM JSON 报告,作为 CI 作业产物 Yes Yes
在 UI 上通过 MR 来启用容器扫描 Yes Yes
UBI 镜像支持 Yes Yes
Trivy 支持 Yes Yes
包含极狐GitLab 安全公告数据库 受限且有延迟的内容 Yes - 所有来自 Gemnasium DB 的最新内容
在合并请求和 CI 流水线选项卡的安全部分中展示报告 No Yes
漏洞解决方案(自动修复) No Yes
支持漏洞允许列表 No Yes
访问依赖列表页面 No Yes

配置

在 CI/CD 流水线中启用容器扫描分析器。当流水线运行时,您应用程序依赖的镜像将被扫描以查找漏洞。您可以使用 CI/CD 变量来自定义容器扫描。

启用分析器

先决条件:

  • 需要在 .gitlab-ci.yml 文件中有测试阶段。
  • 对于私有化部署的 runner,您需要有在 Linux/amd64 上运行的 dockerkubernetes runner 执行器。如果您正在使用 JihuLab.com 上的实例 runner,此功能默认启用。
  • 支持的发行版相匹配的镜像。
  • 在您的项目容器镜像仓库中构建和推送 Docker 镜像。
  • 如果您在使用第三方容器镜像服务,您需要通过 CS_REGISTRY_USERCS_REGISTRY_PASSWORD 配置变量来提供认证凭据。有关如何使用这些变量的更多详细信息,请参阅认证到远程仓库

要启用分析器,或:

  • 启用 Auto DevOps,其中包括依赖扫描。
  • 使用预配置的合并请求。
  • 创建一个扫描执行策略,强制执行容器扫描。
  • 手动编辑 .gitlab-ci.yml 文件。

使用预配置的合并请求

此方法会自动准备一个在 .gitlab-ci.yml 文件中包含容器扫描模板的合并请求。然后您合并此请求并启用依赖项扫描。

note 此方法在没有既有 .gitlab-ci.yml 文件的情况下运行良好,或者只有最小配置文件。如果您有一个复杂的极狐GitLab 配置文件,它可能无法正确解析,可能会发生错误。在这种情况下,请改用手动方法。

要启用容器扫描:

  1. 在左侧导航栏,选择 搜索或前往 并找到您的项目。
  2. 选择 安全 > 安全配置
  3. 容器扫描 行中,选择 使用合并请求配置
  4. 选择 创建合并请求
  5. 查看合并请求,然后选择 合并

现在,流水线包含容器扫描作业了。

手动编辑 .gitlab-ci.yml 文件

此方法需要您手动编辑既有的 .gitlab-ci.yml 文件。如果您需要使用非默认选项,或者您的极狐GitLab CI/CD 配置文件很复杂,请使用此方法。

要启用容器扫描:

  1. 在左侧导航栏,选择 搜索或前往 并找到您的项目。
  2. 选择 构建 > 流水线编辑器
  3. 如果不存在 .gitlab-ci.yml 文件,请选择 配置流水线,然后删除示例内容。
  4. 将以下内容复制并粘贴到 .gitlab-ci.yml 文件的底部。如果已经存在 include 行,请只添加 template 行。

    include:
      - template: Jobs/Container-Scanning.gitlab-ci.yml
    
  5. 选择 验证 选项卡,然后选择 验证流水线

    此消息 模拟成功完成 以确认文件有效。

  6. 选择 编辑 选项卡。
  7. 完成字段。不要为 分支 字段使用默认分支。
  8. 选择 为这些变更启动新的合并请求 勾选框,然后选择 提交变更
  9. 根据标准工作流程完成字段,等待流水线通过,然后选择 合并
  10. 根据您的标准工作流来审核和编辑合并请求,等待流水线通过,然后选择 合并

现在,流水线包含容器扫描作业了。

自定义分析器行为

要自定义容器扫描。使用CI/CD 变量

启用详情(verbose)输出

当您需要查看依赖项扫描作业的详细操作时,例如在故障排除时,启用详细输出。

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

variables:
    SECURE_LOG_LEVEL: 'debug'

扫描远端仓库中的镜像

要扫描远端仓库而不是当前项目中的镜像,使用如下的 .gitlab-ci.yml

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_IMAGE: example.com/user/image:tag
认证远端仓库

扫描私有仓库中的镜像需要认证。在 CS_REGISTRY_USER 变量中提供用户名,在 CS_REGISTRY_PASSWORD 配置变量中提供密码。

比如,要从 AWS Elastic Container Registry 中扫描镜像:

container_scanning:
  before_script:
    - ruby -r open-uri -e "IO.copy_stream(URI.open('https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip'), 'awscliv2.zip')"
    - unzip awscliv2.zip
    - sudo ./aws/install
    - aws --version
    - export AWS_ECR_PASSWORD=$(aws ecr get-login-password --region region)

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

variables:
    CS_IMAGE: <aws_account_id>.dkr.ecr.<region>.amazonaws.com/<image>:<tag>
    CS_REGISTRY_USER: AWS
    CS_REGISTRY_PASSWORD: "$AWS_ECR_PASSWORD"
    AWS_DEFAULT_REGION: <region>

当启用 FIPS 模式 时,不支持认证远端仓库。

报告特定语言漏洞

CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN CI/CD 变量控制扫描是否报告与编程语言相关的发现。关于支持语言的更多详情,可查阅 特定语言软件包 中的 Trivy 文档。

默认情况下,报告仅包含由操作系统(OS)包管理器管理的软件包(比如, yumaptapktdnf)。要报告非 OS 的软件包漏洞,需要设置 CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN"false"

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN: "false"

当您启用此功能时,且为您的项目启用了依赖项扫描,您可能会在漏洞报告中看到重复发现。发生此问题是因为极狐GitLab 无法自动为不同类型的扫描工具去重发现。要了解哪些类型的依赖项可能会重复,请参阅依赖项扫描与容器扫描的比较

在合并请求流水线中运行作业

查阅在合并请求流水线中使用安全扫描

可用的 CI/CD 变量

您可以使用以下 CI/CD 变量配置分析器:

CI/CD 变量 默认值 描述 扫描器
ADDITIONAL_CA_CERT_BUNDLE "" 您想要信任的 CA 证书捆绑包。查看使用自定义 SSL CA 证书颁发机构获取详情。 All
CI_APPLICATION_REPOSITORY $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG 要扫描的镜像的 Docker 仓库 URL。 All
CI_APPLICATION_TAG $CI_COMMIT_SHA 要扫描的镜像的 Docker 仓库标记。 All
CS_ANALYZER_IMAGE registry.gitlab.cn/security-products/container-scanning:6 分析器的 Docker 镜像。 All
CS_DEFAULT_BRANCH_IMAGE "" 默认分支上的 CS_IMAGE 的名称。查看设置默认分支镜像获取详情。引入于 14.5 版本。 All
CS_DISABLE_DEPENDENCY_LIST "false" 禁用扫描镜像中安装的软件包的依赖扫描。引入于 14.6 版本。 All
CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN "true" 禁用扫描安装在扫描镜像中的特定语言包。引入于 14.6 版本。 All
CS_DOCKER_INSECURE "false" 允许在不验证证书的情况下使用 HTTPS 访问安全的 Docker 镜像库。 All
CS_DOCKERFILE_PATH Dockerfile 用于生成修复的 Dockerfile 的路径。默认情况下,扫描器会在项目的根目录中查找名为“Dockerfile”的文件。仅当 Dockerfile 位于非标准位置(例如子目录)时,才应配置此变量。有关详细信息,请参阅漏洞解决方案 All
CS_IGNORE_STATUSES "" 强制分析器忽略特定状态的漏洞,以逗号分隔的列表。允许的值为: unknown,not_affected,affected,fixed,under_investigation,will_not_fix,fix_deferred,end_of_life1  
CS_IGNORE_UNFIXED "false" 忽略未修复的漏洞。 All
CS_IMAGE $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG 要扫描的 Docker 镜像。如果设置,此变量将覆盖 $CI_APPLICATION_REPOSITORY$CI_APPLICATION_TAG 变量。 All
CS_IMAGE_SUFFIX "" 后缀添加到 CS_ANALYZER_IMAGE。如果设置为 -fips,则使用 FIPS-enabled 镜像进行扫描。有关详细信息,请参阅启用 FIPS 的镜像。引入于 14.10 版本。 All
CS_QUIET "" 如设置,此变量会在作业日志中禁用漏洞表的输出。引入于极狐GitLab 15.1。  
CS_REGISTRY_INSECURE "false" 允许访问不安全的镜像库(仅限 HTTP)。仅应在本地测试镜像时设置为 true。适用于所有扫描器,但镜像库必须侦听端口 80/tcp 才能使 Trivy 工作。 All
CS_REGISTRY_PASSWORD $CI_REGISTRY_PASSWORD 用于访问需要身份验证的 Docker 镜像库的密码。仅当 $CS_IMAGE 位于 $CI_REGISTRY 时才设置默认值。启用 FIPS 模式时不支持。 All
CS_REGISTRY_USER $CI_REGISTRY_USER 用于访问需要身份验证的 Docker 镜像库的用户名。仅当 $CS_IMAGE 位于 $CI_REGISTRY 时才设置默认值。启用 FIPS 模式时不支持。 All
CS_SEVERITY_THRESHOLD UNKNOWN 严重级别阈值。扫描器输出严重级别高于或等于此阈值的漏洞。支持的级别为 UNKNOWNLOWMEDIUMHIGHCRITICAL Trivy
CS_TRIVY_JAVA_DB "registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-java-db" trivy-java-db 漏洞数据可指定一个备用位置。  
SECURE_LOG_LEVEL info 设置最低日志记录级别。输出此日志级别或更高级别的消息。从最高到最低严重性,日志记录级别是:fatalerrorwarninfodebug。引入于 13.1 版本。 All
TRIVY_TIMEOUT 5m0s 为扫描设置超时。  

脚注:

  1. 修复状态信息取决于软件供应商准确的修复可用性数据和容器镜像操作系统包元数据。它也取决于各个容器扫描器的个人解释。在容器扫描器误报漏洞的修复包可用性的情况下,启用 CS_IGNORE_STATUSES 可能会导致在启用此设置时过滤发现的假阳性或假阴性。

支持的发行版

支持的发行版如下:

  • Alma Linux
  • Alpine Linux
  • Amazon Linux
  • CentOS
  • CBL-Mariner
  • Debian
  • Distroless
  • Oracle Linux
  • Photon OS
  • Red Hat (RHEL)
  • Rocky Linux
  • SUSE
  • Ubuntu

启用 FIPS 的镜像

提供 FIPS-enabled Red Hat UBI 版本的容器扫描镜像。因此,您可以使用基于 UBI 的镜像替换标准镜像。要配置镜像,将 CS_IMAGE_SUFFIX 设置为 -fips 或修改 CS_ANALYZER_IMAGE 变量为标准标签加上 -fips 扩展名。

note 当在极狐GitLab 实例上启用 FIPS 模式时,-fips 标志会被自动添加到 CS_ANALYZER_IMAGE 中。

启用 FIPS 模式时,不支持对经过身份验证的镜像库中的镜像进行容器扫描。当 CI_GITLAB_FIPS_MODE"true",并且设置了 CS_REGISTRY_USERCS_REGISTRY_PASSWORD 时,分析器会出错退出并且不执行扫描。

覆盖容器扫描模板

如果您想覆盖作业定义(例如,更改诸如 variables 之类的属性),则必须在模板包含后,声明并覆盖作业,然后指定任何其它键。

此示例将 GIT_STRATEGY 设置为 fetch

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    GIT_STRATEGY: fetch

设置默认分支镜像

默认情况下,容器扫描假定镜像命名约定将任何特定于分支的标识符存储在镜像标签中,而不是镜像名称中。当默认分支和非默认分支之间的镜像名称不同时,先前检测到的漏洞会在合并请求中显示为新检测到的漏洞。

当同一镜像在默认分支和非默认分支上具有不同的名称时,您可以使用 CS_DEFAULT_BRANCH_IMAGE 变量来指示该镜像在默认分支上的名称。 然后系统在非默认分支上运行扫描时可以正确确定是否存在漏洞。

例如,假设以下情况:

  • 非默认分支使用命名约定 $CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:$CI_COMMIT_SHA 发布镜像。
  • 默认分支使用命名约定 $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA 发布镜像。

在此示例中,您可以使用以下 CI/CD 配置来确保不重复漏洞:

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_DEFAULT_BRANCH_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  before_script:
    - export CS_IMAGE="$CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:$CI_COMMIT_SHA"
    - |
      if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then
        export CS_IMAGE="$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
      fi

对于给定的 CS_IMAGECS_DEFAULT_BRANCH_IMAGE 应该保持不变。如果它发生变化,则会创建一组重复的漏洞,必须手动消除这些漏洞。

使用 Auto DevOps 时,CS_DEFAULT_BRANCH_IMAGE 会自动设置为 $CI_REGISTRY_IMAGE/$CI_DEFAULT_BRANCH:$CI_APPLICATION_TAG

使用自定义 SSL CA 证书颁发机构

您可以使用 ADDITIONAL_CA_CERT_BUNDLE CI/CD 变量来配置自定义 SSL CA 证书颁发机构,用于在从使用 HTTPS 的镜像库获取 Docker 镜像时验证对等方。ADDITIONAL_CA_CERT_BUNDLE 值应包含 X.509 PEM 公钥证书的文本表示形式。例如,要在 .gitlab-ci.yml 文件中配置此值,请使用以下命令:

container_scanning:
  variables:
    ADDITIONAL_CA_CERT_BUNDLE: |
        -----BEGIN CERTIFICATE-----
        MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB
        ...
        jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs=
        -----END CERTIFICATE-----

ADDITIONAL_CA_CERT_BUNDLE 值也可以配置为 UI 中的自定义变量,或者配置为 file, 需要证书的路径,或者作为变量(需要证书的文本表示)。

漏洞许可名单

要将特定漏洞列入白名单,请执行以下步骤:

  1. 按照 覆盖容器扫描模板 中的说明,在 .gitlab-ci.yml 文件中设置 GIT_STRATEGY: fetch
  2. 在名为 vulnerability-allowlist.yml 的 YAML 文件中定义列入许可名单的漏洞。必须使用 vulnerability-allowlist.yml 数据格式 中描述的格式。
  3. vulnerability-allowlist.yml 文件添加到项目 Git 仓库的根文件夹中。

vulnerability-allowlist.yml 数据格式

vulnerability-allowlist.yml 文件是一个 YAML 文件,它指定了允许存在的漏洞的 CVE ID 列表,主要原因包括 误报不适用

如果在 vulnerability-allowlist.yml 文件中找到匹配条目,则会发生以下情况:

  • 当分析器生成 gl-container-scanning-report.json 文件时,漏洞不包括在内。
  • 流水线的安全选项卡不显示漏洞。它不包含在 JSON 文件中,即安全选项卡内容的真实来源。

示例 vulnerability-allowlist.yml 文件:

generalallowlist:
  CVE-2019-8696:
  CVE-2014-8166: cups
  CVE-2017-18248:
images:
  registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256:
    CVE-2018-4180:
  your.private.registry:5000/centos:
    CVE-2015-1419: libxml2
    CVE-2015-1447:

此示例从 gl-container-scanning-report.json 中排除以下漏洞:

  1. 所有具有 CVE ID 的漏洞:CVE-2019-8696CVE-2014-8166CVE-2017-18248
  2. registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256 容器镜像中发现的所有 CVE ID 为 CVE-2018-4180 的漏洞。
  3. your.private.registry:5000/centos 容器中发现的所有 CVE ID 为 CVE-2015-1419CVE-2015-1447 的漏洞。
文件格式
  • generalallowlist 块允许您在全局范围内指定 CVE ID。具有匹配 CVE ID 的所有漏洞都将从扫描报告中排除。

  • images 块允许您为每个容器镜像独立指定 CVE ID。给定镜像中具有匹配 CVE ID 的所有漏洞都将从扫描报告中排除。镜像名称是从用于指定要扫描的 Docker 镜像的环境变量之一检索的,例如 $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAGCS_IMAGE。此块中提供的镜像必须匹配此值并且不得包含标签值。例如,如果您使用 CS_IMAGE=alpine:3.7 指定要扫描的镜像,则可以在 images 块中使用 alpine,但不能使用 alpine:3.7

    您可以通过多种方式指定容器镜像:

    • 仅镜像名称(例如 centos)。
    • 带有主机名的完整镜像名称(例如 your.private.registry:5000/centos)。
    • 带有镜像库主机名和 sha256 标签的完整镜像名称(例如 registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256)。
note CVE ID 后面的字符串(上例中的cupslibxml2)是可选的注释格式,对漏洞的处理没有影响。您可以包含注释来描述漏洞。
容器扫描作业日志格式

您可以通过查看容器扫描分析器在 container_scanning 作业详细信息中生成的日志来验证扫描结果和 vulnerability-allowlist.yml 文件的正确性。

该日志包含以表格形式列出的已发现漏洞列表,例如:

+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
|   STATUS   |      CVE SEVERITY       |      PACKAGE NAME      |    PACKAGE VERSION    |                            CVE DESCRIPTION                             |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
|  Approved  |   High CVE-2019-3462    |          apt           |         1.4.8         | Incorrect sanitation of the 302 redirect field in HTTP transport metho |
|            |                         |                        |                       | d of apt versions 1.4.8 and earlier can lead to content injection by a |
|            |                         |                        |                       |  MITM attacker, potentially leading to remote code execution on the ta |
|            |                         |                        |                       |                             rget machine.                              |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
| Unapproved |  Medium CVE-2020-27350  |          apt           |         1.4.8         | APT had several integer overflows and underflows while parsing .deb pa |
|            |                         |                        |                       | ckages, aka GHSL-2020-168 GHSL-2020-169, in files apt-pkg/contrib/extr |
|            |                         |                        |                       | acttar.cc, apt-pkg/deb/debfile.cc, and apt-pkg/contrib/arfile.cc. This |
|            |                         |                        |                       |  issue affects: apt 1.2.32ubuntu0 versions prior to 1.2.32ubuntu0.2; 1 |
|            |                         |                        |                       | .6.12ubuntu0 versions prior to 1.6.12ubuntu0.2; 2.0.2ubuntu0 versions  |
|            |                         |                        |                       | prior to 2.0.2ubuntu0.2; 2.1.10ubuntu0 versions prior to 2.1.10ubuntu0 |
|            |                         |                        |                       |                                  .1;                                   |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
| Unapproved |  Medium CVE-2020-3810   |          apt           |         1.4.8         | Missing input validation in the ar/tar implementations of APT before v |
|            |                         |                        |                       | ersion 2.1.2 could result in denial of service when processing special |
|            |                         |                        |                       |                         ly crafted deb files.                          |
+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+

将对应的 CVE ID 添加到 vulnerability-allowlist.yml 文件时,日志中的漏洞会被标记为 Approved

在离线环境中运行容器扫描

对于通过 Internet 对外部资源进行有限、受限或间歇性访问的环境中的私有化部署的极狐GitLab 实例,需要进行一些调整才能使容器扫描作业成功运行。更多详情,请查阅离线环境

离线容器扫描的要求

要在离线环境中使用容器扫描,您需要:

  • 带有 dockerkubernetes 执行器 的极狐GitLab Runner。
  • 使用容器扫描镜像的副本配置本地 Docker 容器镜像库。您可以在它们各自的镜像库中找到这些镜像:
GitLab Analyzer Container Registry
Container-Scanning Container-Scanning container registry

请注意,极狐GitLab Runner 的默认 pull policyalways,这意味着即使本地副本可用,runner 也会尝试从 GitLab 容器镜像库中提取 Docker 镜像。如果您更喜欢仅使用本地可用的 Docker 镜像,则可以在离线环境中将 GitLab Runner pull_policy 设置为 if-not-present。但是,如果不在离线环境中,我们建议将拉取策略设置保持为 always,因为这样可以在 CI/CD 流水线中使用更新的扫描程序。

支持自定义证书颁发机构

对 Trivy 自定义证书颁发机构的支持引入于版本 4.0.0。

在 Docker 镜像库中提供极狐GitLab 容器扫描分析器镜像

对于容器扫描,将以下镜像从 registry.gitlab.cn 导入您的本地 Docker 容器镜像库

registry.gitlab.cn/security-products/container-scanning:7
registry.gitlab.cn/security-products/container-scanning/trivy:7

将 Docker 镜像导入本地离线 Docker 镜像库的过程取决于您的网络安全策略。请咨询您的 IT 人员,找到一个接受和批准的流程,您可以通过该流程导入或临时访问外部资源。这些扫描程序定期更新,您可以自己进行不定期更新。

有关将 Docker 镜像作为文件保存和传输的详细信息,请参阅 Docker 关于 docker save 的文档,docker loaddocker exportdocker import

设置容器扫描 CI/CD 变量来使用本地容器扫描分析器

  1. 覆盖容器扫描模板 在您的 .gitlab-ci.yml 文件中引用托管在本地 Docker 容器镜像库上的 Docker 镜像:

    include:
      - template: Jobs/Container-Scanning.gitlab-ci.yml
    
    container_scanning:
      image: $CI_REGISTRY/namespace/gitlab-container-scanning
    
  2. 如果您的本地 Docker 容器镜像库通过 HTTPS 安全运行,但您使用的是自签名证书,则必须在 .gitlab-ci.yml 的上述 container_scanning 部分中设置 CS_DOCKER_INSECURE: "true"

使用流水线自动进行容器扫描漏洞数据库更新

我们建议您设置一个计划流水线,按照预设的计划获取最新的漏洞数据库。 使用流水线自动执行此操作意味着您不必每次都手动执行。您可以使用以下 .gitlab-ci.yml 示例作为模板。

variables:
  SOURCE_IMAGE: registry.gitlab.cn/security-products/container-scanning:7
  TARGET_IMAGE: $CI_REGISTRY/namespace/gitlab-container-scanning

image: docker:stable

update-scanner-image:
  services:
    - docker:dind
  script:
    - docker pull $SOURCE_IMAGE
    - docker tag $SOURCE_IMAGE $TARGET_IMAGE
    - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY --username $CI_REGISTRY_USER --password-stdin
    - docker push $TARGET_IMAGE

上述模板适用于在本地安装上运行的 GitLab Docker 镜像库。但是,如果您使用的是非 GitLab Docker 镜像库,则必须更改 $CI_REGISTRY 值和 docker login 凭据来匹配本地镜像库的详细信息。

扫描外部私有镜像库中的镜像

要扫描外部私有镜像库中的镜像,您必须配置访问凭据,以便容器扫描分析器可以在尝试访问要扫描的镜像之前对其进行身份验证。

如果您使用极狐GitLab Container RegistryCS_REGISTRY_USERCS_REGISTRY_PASSWORD 配置变量会自动设置,您可以跳过这个配置。

此示例显示了在私有 Google Container Registry 中扫描镜像所需的配置:

include:
  - template: Jobs/Container-Scanning.gitlab-ci.yml

container_scanning:
  variables:
    CS_REGISTRY_USER: _json_key
    CS_REGISTRY_PASSWORD: "$GCP_CREDENTIALS"
    CS_IMAGE: "gcr.io/path-to-you-registry/image:tag"

在提交此配置之前,为包含 JSON 的 GCP_CREDENTIALS 添加 CI/CD 变量密钥。 同时:

  • 变量的值可能不符合 隐藏变量 选项的隐藏要求,因此该值可能会暴露在作业日志中。
  • 如果您选择 保护变量 选项,扫描可能不会在不受保护的功能分支中运行。
  • 如果未选择这些选项,请考虑创建具有只读权限的凭据并定期轮换它们。

启用 FIPS 模式时,不支持扫描外部私有镜像库中的镜像。

运行独立的容器扫描工具

可以针对 Docker 容器运行极狐GitLab 容器扫描工具,而无需在 CI 作业的上下文中运行它。要直接扫描镜像,请执行以下步骤:

  1. 运行 Docker DesktopDocker Machine

  2. 运行分析器的 Docker 镜像,在 CI_APPLICATION_REPOSITORYCI_APPLICATION_TAG 变量中传递要分析的镜像和标签:

    docker run \
      --interactive --rm \
      --volume "$PWD":/tmp/app \
      -e CI_PROJECT_DIR=/tmp/app \
      -e CI_APPLICATION_REPOSITORY=registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256 \
      -e CI_APPLICATION_TAG=bc09fe2e0721dfaeee79364115aeedf2174cce0947b9ae5fe7c33312ee019a4e \
      registry.gitlab.cn/security-products/container-scanning
    

结果存储在 gl-container-scanning-report.json 中。

报告 JSON 格式

容器扫描工具发出 JSON 报告,极狐GitLab Runner 通过 artifacts:reports CI 配置文件中的关键字识别该报告。

CI 作业完成后,Runner 会将这些报告上传到极狐GitLab,然后在 CI 作业产物中可用。在旗舰版中,这些报告可以在相应的流水线中查看,并成为漏洞报告的一部分。

CycloneDX 软件物料清单

  • 引入于 15.11 版本。

除了 JSON 报告文件之外,容器扫描工具还为扫描镜像输出 CycloneDX 软件物料清单 (SBOM)。此 CycloneDX SBOM 名为 gl-sbom-report.cdx.json,并保存在与 JSON 报告文件相同的目录中。只有在使用 Trivy 分析器时才支持此功能。

您可以使用与其他作业产物相同的方式下载 CycloneDX SBOM。

针对仓库的容器扫描

  • 引入于极狐GitLab 17.1,使用名为 enable_container_scanning_for_registry 的功能标志。默认禁用。
  • 在极狐GitLab 17.2 中为 JihuLab.com 和私有化部署启用。
  • 在极狐GitLab 17.2 中 GA。功能标志 enable_container_scanning_for_registry 被删除。

当使用 latest 标签推送容器镜像时,容器扫描作业由安全策略机器人在针对默认分支的新流水线中自动触发。

和常规容器扫描不同,扫描结果不会包含安全报告。针对仓库的容器扫描依赖于持续漏洞扫描来检查扫描检测到的组件。

当识别安全漏洞时,极狐GitLab 会将这些漏洞填充到漏洞报告中。漏洞可以在漏洞报告页面的 容器仓库漏洞 选项卡下查看。

note 仅当新的公告发布到极狐GitLab 公告 Database中时,才会填充漏洞报告。填充漏洞报告时,仅填充新检测到的数据,而不是所有现有数据。

先决条件

  • 您必须至少是项目中的维护者才能为极狐GitLab 容器仓库启用容器扫描。
  • 使用的项目不能为空。如果仅用于存储容器镜像的空项目,则此功能将无法正常工作。作为解决方法,请确保项目在默认分支上包含初始提交。
  • 默认情况下,每个项目每天最多可执行 50 次扫描。
  • 您必须配置容器仓库通知

启用仓库容器扫描

要为极狐GitLab 容器仓库启用容器扫描:

  1. 在左侧导航栏,选择 搜索或前往 并找到您的项目。
  2. 选择 安全 > 安全配置
  3. 滚动到 针对仓库的容器扫描 部分,打开开关。

漏洞数据可

所有的分析器都会进行每日更新。

镜像使用从以下上游公告数据库中的数据:

  • AlmaLinux Security Advisory
  • Amazon Linux Security Center
  • Arch Linux Security Tracker
  • SUSE CVRF
  • CWE Advisories
  • Debian Security Bug Tracker
  • GitHub Security Advisory
  • Go Vulnerability Database
  • CBL-Mariner Vulnerability Data
  • NVD
  • OSV
  • Red Hat OVAL v2
  • Red Hat Security Data API
  • Photon Security Advisories
  • Rocky Linux UpdateInfo
  • Ubuntu CVE Tracker (only data sources from mid 2021 and later)

除了这些分析器源提供的数据,极狐GitLab 还自己维护以下漏洞数据库:

在极狐GitLab 旗舰版中,GitLab Advisory Database中的数据与来自外部源的数据合并。在极狐GitLab 高级版和免费版中,极狐GitLab 公告数据库(开源版)中的数据与来自外部源的数据合并。此增强功能目前仅适用于 Trivy 扫描器的分析器镜像。

对其他分析器的数据库更新信息,可以在维护表中找到。

漏洞修复方案(自动修复)

有些漏洞可以通过应用极狐GitLab 自动生成的解决方案来修复。

要启用修复支持,扫描工具 必须 要能够访问由 CS_DOCKERFILE_PATH CI/CD 变量指定的 Dockerfile。要确保扫描工具能够访问此文件,您需要按照此文档的覆盖容器扫描模板部分中所述的说明,在 .gitlab-ci.yml 文件中设置 GIT_STRATEGY: fetch

更多详情,可查阅漏洞的解决方案

故障排查

docker: Error response from daemon: failed to copy xattrs

当 runner 使用 docker 执行器并使用 NFS 时(例如,/var/lib/docker 在 NFS 挂载上),容器扫描可能会失败,并出现如下错误:

docker: Error response from daemon: failed to copy xattrs: failed to set xattr "security.selinux" on /path/to/file: operation not supported.

这是 Docker 中的一个错误的结果,现在 已修复。为防止出现错误,请确保 runner 使用的 Docker 版本为 18.09.03 或更高版本。

收到警告消息 gl-container-scanning-report.json: no matching files

要获取更多信息,查看通用应用安全故障排除部分

当扫描 AWS ECR 中的镜像时,发生 unexpected status code 401 Unauthorized: Not Authorized

当没有配置 AWS 区域且扫描器无法获取认证令牌时,就会发生此问题。当您将 SECURE_LOG_LEVEL 设置为 debug 时,您将看到如下日志消息:

[35mDEBUG[0m failed to get authorization token: MissingRegion: could not find region configuration

要解决此问题,请将 AWS_DEFAULT_REGION 添加到您的 CI/CD 变量中:

variables:
  AWS_DEFAULT_REGION: <AWS_REGION_FOR_ECR>

unable to open a file: open /home/gitlab/.cache/trivy/ee/db/metadata.json: no such file or directory

压缩的 Trivy 数据库存储在容器的 /tmp 目录下,它在运行时被提取到 /home/gitlab/.cache/trivy/{ee|ce}/db。如果在您的运行器配置中为 /tmp 目录绑定了卷挂载,则可能会发生此错误。

要解决此问题,请不要绑定 /tmp 目录,而是绑定 /tmp 目录中的特定文件或文件夹(例如 /tmp/myfile.txt)。

解决 context deadline exceeded 错误

此错误意味着发生了超时。要解决此问题,请将 TRIVY_TIMEOUT 环境变量添加到 container_scanning 作业中,以指定足够长的持续时间。

变更

您可以在项目的 changelog 中找到对容器扫描分析器的更改。