容器镜像扫描
Tier: 基础版,专业版,旗舰版
Offering: JihuLab.com,私有化部署
容器镜像中的安全漏洞在您的应用整个生命周期中带来风险。 容器镜像扫描能够在风险进入生产环境之前尽早检测到它们。当 您的基础镜像或操作系统软件包中出现漏洞时,容器镜像扫描 能够识别它们,并为可修复的漏洞提供修复路径。
- 有关入门教程,请参阅扫描 Docker 容器中的漏洞。
容器镜像扫描通常被视为软件构成分析 (SCA) 的一部分。SCA 包含检查代码所使用项目的过程。这些项目通常包括应用程序和系统依赖项,它们几乎总是从外部源导入,而不是来自您自己编写的代码。
极狐GitLab 同时提供容器镜像扫描和依赖项扫描 以确保覆盖所有这些依赖类型。为了尽可能覆盖您所面临的风险领域, 请使用所有安全扫描工具。要比较这些功能,请参阅 依赖项扫描与容器镜像扫描对比。
极狐GitLab 与 Trivy 安全扫描器集成,对容器中的漏洞进行静态分析。
功能特性
| 功能特性 | 基础版和专业版 | 旗舰版 |
|---|---|---|
| 自定义设置(变量、覆盖、离线环境支持等) | ||
| 以 CI 作业产物的形式 查看 JSON 报告 | ||
| 以 CI 作业产物的形式生成 CycloneDX SBOM JSON 报告 | ||
| 通过极狐GitLab UI 中的 MR 启用容器镜像扫描 | ||
| UBI 镜像支持 | ||
| 支持 Trivy | ||
| End-of-life 操作系统检测 | ||
| 包含极狐GitLab 公告数据库 | 仅限于极狐GitLab advisories-communities 项目中延迟发布的内容 | 是 - 来自 Gemnasium DB 的所有最新内容 |
| 在合并请求和 CI 流水线作业的安全选项卡中展示报告数据 | ||
| 漏洞解决方案(自动修复) | ||
| 支持 漏洞允许列表 | ||
| 访问依赖项列表页面 |
入门
在 CI/CD 流水线中启用容器镜像扫描分析器。当流水线运行时,您的应用程序所依赖的镜像会被扫描以查找漏洞。您可以通过使用 CI/CD 变量来自定义容器镜像扫描。
前提条件:
- .gitlab-ci.yml 文件中需要包含 test 阶段。
- 对于私有化部署的 runner,您需要在 Linux/amd64 上使用具有 docker 或 kubernetes 执行器的 runner。如果您使用的是 JihuLab.com 上的实例 runner,则该项默认已启用。
- 匹配支持的操作系统发行版的镜像。
- 将 Docker 镜像构建并推送到您项目的容器镜像仓库中。
- 如果您使用的是第三方容器镜像仓库,可能需要使用 CI/CD 变量 CS_REGISTRY_USER 和 CS_REGISTRY_PASSWORD 提供认证凭据。有关如何使用这些变量的详细信息,请参阅向私有的外部镜像仓库进行认证。
要启用分析器,可执行以下任一操作:
- 启用 Auto DevOps,其中包含依赖项扫描。
- 使用预配置的合并请求。
- 创建强制进行容器镜像扫描的扫描执行策略。
- 手动编辑 .gitlab-ci.yml 文件。
使用预配置的合并请求
此方法会自动准备一个合并请求,其中包含 .gitlab-ci.yml 文件中的容器镜像扫描模板。然后您合并该合并请求以启用容器镜像扫描。
前提条件:
- 拥有项目的 Developer、Maintainer 或 Owner 角色。
- .gitlab-ci.yml 文件中存在 test 阶段。
- 对于私有化部署的 runner,需要在 Linux/amd64 上使用具有 docker 或 kubernetes 执行器的 runner。如果您使用的是 JihuLab.com 上的实例 runner,则该项默认已启用。
- 匹配支持的操作系统发行版的镜像。
- Docker 镜像已构建并推送到您项目的容器镜像仓库。
- 如果您使用的是第三方容器镜像仓库,可能需要使用 CI/CD 变量 CS_REGISTRY_USER 和 CS_REGISTRY_PASSWORD 提供认证凭据。有关详细信息,请参阅向私有的外部镜像仓库进行认证。
要启用容器镜像扫描:
- 在顶部栏中,选择 搜索或跳转到 并找到您的项目。
- 在左侧边栏中,选择 安全 > 安全配置。
- 在 容器镜像扫描 行中,选择 使用合并请求配置。
- 选择 创建合并请求。
- 审查合并请求,然后选择 合并。
流水线现在包含容器镜像扫描作业。
手动编辑 .gitlab-ci.yml 文件
此方法要求您手动编辑现有的 .gitlab-ci.yml 文件。如果您有复杂的极狐GitLab 配置文件或需要使用非默认选项,请使用此方法。
前提条件:
- 拥有项目的 Developer、Maintainer 或 Owner 角色。
- .gitlab-ci.yml 文件中存在 test 阶段。
- 对于私有化部署的 runner,需要在 Linux/amd64 上使用具有 docker 或 kubernetes 执行器的 runner。如果您使用的是 JihuLab.com 上的实例 runner,则该项默认已启用。
- 匹配支持的操作系统发行版的镜像。
- Docker 镜像已构建并推送到您项目的容器镜像仓库。
- 如果您使用的是第三方容器镜像仓库,可能需要使用 CI/CD 变量 CS_REGISTRY_USER 和 CS_REGISTRY_PASSWORD 提供认证凭据。有关详细信息,请参阅向私有的外部镜像仓库进行认证。
要启用容器镜像扫描:
-
在顶部栏中,选择 搜索或跳转到 并找到您的项目。
-
在左侧边栏中,选择 构建 > 流水线编辑器。
-
如果不存在 .gitlab-ci.yml 文件,请选择 配置流水线,然后删除示例内容。
-
将以下内容复制并粘贴到 .gitlab-ci.yml 文件底部。如果已存在 include 行,则仅在其下方添加 template 行。
yamlinclude: - template: Jobs/Container-Scanning.gitlab-ci.yml -
选择 验证 选项卡,然后选择 验证流水线。
消息 模拟成功完成 确认文件有效。
-
选择 编辑 选项卡。
-
填写字段。分支 字段不要使用默认分支。
-
选中 使用这些更改开始一个新的合并请求 复选框,然后选择 提交更改。
-
按照您的标准工作流程填写字段,然后选择 创建合并请求。
-
按照您的标准工作流程审查和编辑合并请求,等待流水线通过,然后选择 合并。
流水线现在包含容器镜像扫描作业。
理解扫描结果
前提条件:
- 拥有项目的 Security Manager、Developer、Maintainer 或 Owner 角色。
您可以在流水线中审查漏洞:
- 在顶部栏中,选择 搜索或跳转到 并找到您的项目。
- 在左侧边栏中,选择 构建 > 流水线。
- 选择流水线。
- 选择 安全 选项卡。
- 选择一个漏洞以查看其详细信息,包括:
- 描述:解释漏洞的成因、潜在影响以及推荐的修复步骤。
- 状态:指示漏洞是否已进行分类或已解决。
- 严重性:根据影响分为六个级别。 了解更多关于严重性级别的信息。
- CVSS 评分:提供与严重性相对应的数值。
- EPSS:显示该漏洞在野利用的可能性。
- 已知利用漏洞 (KEV):指示该漏洞已被利用。
- 项目:突出显示发现漏洞的项目。
- 报告类型:解释输出类型。
- 扫描器:标识检测到漏洞的是哪个分析器。
- 镜像:提供与该漏洞相关的镜像。
- 命名空间:标识与该漏洞相关的工作区。
- 链接:显示该漏洞被各种公告数据库收录的证据。
- 标识符:用于对漏洞进行分类的引用列表,例如 CVE 标识符。
更多详情,请参阅流水线安全报告。
查看容器镜像扫描结果的其他方式:
- 漏洞报告:显示默认分支上已确认的漏洞。
- 容器镜像扫描报告产物
优化
极狐GitLab 为容器镜像扫描提供两种方式:
- 标准容器镜像扫描:每个作业扫描单个容器镜像。最适合简单和分布式工作流程。
- 多容器扫描:使用单个配置文件并行扫描多个镜像。最适合高效扫描多个镜像。
推广
在对单个项目的容器镜像扫描结果有信心后,您可以将其实现扩展到更多项目:
支持的操作系统发行版
支持以下 Linux 发行版:
- Alma Linux
- Alpine Linux
- Amazon Linux
- CentOS
- CBL-Mariner
- Debian
- Distroless
- Oracle Linux
- Photon OS
- Red Hat (RHEL)
- Rocky Linux
- SUSE
- Ubuntu
启用 FIPS 的镜像
极狐GitLab 还提供容器镜像扫描镜像的 启用 FIPS 的 Red Hat UBI 版本。因此,您可以用启用 FIPS 的镜像替换标准镜像。要配置镜像,请将 CS_IMAGE_SUFFIX 设置为 -fips,或将 CS_ANALYZER_IMAGE 变量修改为标准标签加上 -fips 后缀。
启用 FIPS 模式时,不支持扫描需要认证的镜像仓库中的容器镜像。当 CI_GITLAB_FIPS_MODE 为 "true" 且设置了 CS_REGISTRY_USER 或 CS_REGISTRY_PASSWORD 时,分析器会报错退出,不执行扫描。
配置
自定义分析器行为
要自定义容器镜像扫描,请使用 CI/CD 变量。
启用详细输出
当您需要详细了解依赖项扫描作业的具体操作时(例如进行故障排除时),请启用详细输出。
在以下示例中,包含了容器镜像扫描模板,并启用了详细输出。
yamlinclude: - template: Jobs/Container-Scanning.gitlab-ci.yml variables: SECURE_LOG_LEVEL: 'debug'
报告语言特定的发现项
CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN CI/CD 变量控制扫描是否报告与编程语言相关的发现项。有关支持的语言的更多信息,请参阅 Trivy 文档中的特定语言软件包。
默认情况下,报告仅包括由操作系统 (OS) 软件包管理器(例如 yum、apt、apk、tdnf)管理的软件包。要报告非操作系统软件包中的安全发现项,请将 CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN 设置为 "false":
yaml1include: 2 - template: Jobs/Container-Scanning.gitlab-ci.yml 3 4container_scanning: 5 variables: 6 CS_DISABLE_LANGUAGE_VULNERABILITY_SCAN: "false"
启用此功能后,如果您的项目同时启用了依赖项扫描,您可能在漏洞报告中看到重复的发现项。这是因为极狐GitLab 无法自动对不同类型扫描工具之间的发现项进行去重。要了解哪些类型的依赖项可能会重复,请参阅依赖项扫描与容器镜像扫描对比。
在合并请求流水线中运行作业
可用的 CI/CD 变量
要自定义容器镜像扫描,请使用 CI/CD 变量。下表列出了特定于容器镜像扫描的 CI/CD 变量。您也可以使用任何预定义的 CI/CD 变量。
脚注:
- 修复状态信息高度依赖于软件供应商提供的准确修复可用性数据以及容器镜像操作系统软件包的元数据。同时,它也受到各个容器扫描器解释的影响。当容器扫描器错误报告某个漏洞的修复包可用性时,启用 CS_IGNORE_STATUSES 可能会导致对发现项的误判(误报或漏报)筛选。
直接使用原生环境变量配置 Trivy
除了上面列出的极狐GitLab 特有的 CS_* 变量外,您还可以在 container_scanning 作业中直接设置 Trivy 的任何原生环境变量来配置 Trivy。极狐GitLab 容器扫描分析器会自动将所有环境变量传递给 Trivy。
例如,要为 Trivy 无法自动检测的容器镜像手动指定操作系统发行版(例如定制的基础镜像):
yaml1include: 2 - template: Jobs/Container-Scanning.gitlab-ci.yml 3 4container_scanning: 5 variables: 6 GIT_STRATEGY: fetch 7 TRIVY_DISTRO: "alma/10"
由 极狐GitLab 包装器管理的变量
以下 TRIVY_* 变量由极狐GitLab 容器扫描分析器内部设置。它们由对应的 GitLab CI/CD 变量控制,不能直接覆盖:
| Trivy 变量 | 极狐GitLab CI/CD 变量 |
|---|---|
| TRIVY_CACHE_DIR | (内部使用,不对外公开) |
| TRIVY_USERNAME | CS_REGISTRY_USER |
| TRIVY_PASSWORD | CS_REGISTRY_PASSWORD |
| TRIVY_DEBUG | SECURE_LOG_LEVEL |
| TRIVY_INSECURE | CS_DOCKER_INSECURE |
| TRIVY_NON_SSL | CS_REGISTRY_INSECURE |
使用 TRIVY_DB_REPOSITORY 的已知问题
将 TRIVY_DB_REPOSITORY 设置为指向自定义漏洞数据库没有效果。极狐GitLab 容器扫描分析器将漏洞数据库打包在分析器镜像内,并在运行时向 Trivy 传递 --skip-db-update,因此无论此变量如何,Trivy 都不会下载数据库。要使用自定义数据库位置,请参阅使用 Trivy Java 数据库镜像(针对 Java 数据库)或离线环境(针对一般的离线设置)。
覆盖容器扫描模板
如果您想覆盖作业定义(例如,更改诸如 variables 之类的属性),必须在包含模板之后声明并覆盖一个作业,然后指定任何额外的键。
此示例将 GIT_STRATEGY 设置为 fetch:
yaml1include: 2 - template: Jobs/Container-Scanning.gitlab-ci.yml 3 4container_scanning: 5 variables: 6 GIT_STRATEGY: fetch
扫描外部仓库中的镜像
默认情况下,容器扫描会扫描极狐GitLab 容器镜像仓库中的镜像。您也可以扫描外部仓库中的镜像。
要扫描外部仓库中的镜像,请使用镜像的完整路径配置 CS_IMAGE 变量。
yaml1include: 2 - template: Jobs/Container-Scanning.gitlab-ci.yml 3 4container_scanning: 5 variables: 6 CS_IMAGE: <example.com>/<user>/<image>:<tag>
对私有外部仓库进行认证
如果外部仓库需要认证,请使用 CS_REGISTRY_USER 和 CS_REGISTRY_PASSWORD CI/CD 变量提供凭据。
使用 Trivy Java 数据库镜像
当使用 trivy 扫描器并在被扫描的容器镜像中遇到 jar 文件时,trivy 会下载一个额外的 trivy-java-db 漏洞数据库。默认情况下,trivy-java-db 数据库作为 OCI 工件 托管在 ghcr.io/aquasecurity/trivy-java-db:1。如果此仓库不可访问或返回 TOOMANYREQUESTS,一个解决方案是将 trivy-java-db 镜像到更易访问的容器仓库中:
yaml1mirror trivy java db: 2 image: 3 name: ghcr.io/oras-project/oras:v1.1.0 4 entrypoint: [""] 5 script: 6 - oras login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY 7 - oras pull ghcr.io/aquasecurity/trivy-java-db:1 8 - oras push $CI_REGISTRY_IMAGE:1 --config /dev/null:application/vnd.aquasec.trivy.config.v1+json javadb.tar.gz:application/vnd.aquasec.trivy.javadb.layer.v1.tar+gzip
漏洞数据库不是常规的 Docker 镜像,因此您不能使用 docker pull 拉取它。如果您在极狐GitLab UI 中查看该镜像,会显示错误。
如果容器仓库为 gitlab.example.com/trivy-java-db-mirror,则应按以下方式配置容器扫描作业。不要在末尾添加 :1 标签,它会由 trivy 添加:
yaml1include: 2 - template: Jobs/Container-Scanning.gitlab-ci.yml 3 4container_scanning: 5 variables: 6 CS_TRIVY_JAVA_DB: gitlab.example.com/trivy-java-db-mirror
设置默认分支镜像
默认情况下,容器扫描假定镜像命名规范将任何分支特定的标识符存储在镜像标签中,而不是镜像名称中。当默认分支与非默认分支的镜像名称不同时,先前检测到的漏洞在合并请求中会显示为新发现的漏洞。
当同一镜像在默认分支和非默认分支上有不同名称时,您可以使用 CS_DEFAULT_BRANCH_IMAGE 变量指示该镜像在默认分支上的名称。然后,极狐GitLab 会在非默认分支上运行扫描时正确判断漏洞是否已存在。
例如,假设:
- 非默认分支使用命名规范 $CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:$CI_COMMIT_SHA 发布镜像。
- 默认分支使用命名规范 $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA 发布镜像。
在此示例中,您可以使用以下 CI/CD 配置来确保漏洞不会被重复:
yaml1include: 2 - template: Jobs/Container-Scanning.gitlab-ci.yml 3 4container_scanning: 5 variables: 6 CS_DEFAULT_BRANCH_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA 7 before_script: 8 - export CS_IMAGE="$CI_REGISTRY_IMAGE/$CI_COMMIT_BRANCH:$CI_COMMIT_SHA" 9 - | 10 if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then 11 export CS_IMAGE="$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA" 12 fi
对于给定的 CS_IMAGE,CS_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 文件中配置此值,请使用以下内容:
yaml1container_scanning: 2 variables: 3 ADDITIONAL_CA_CERT_BUNDLE: | 4 -----BEGIN CERTIFICATE----- 5 MIIGqTCCBJGgAwIBAgIQI7AVxxVwg2kch4d56XNdDjANBgkqhkiG9w0BAQsFADCB 6 ... 7 jWgmPqF3vUbZE0EyScetPJquRFRKIesyJuBFMAs= 8 -----END CERTIFICATE-----
ADDITIONAL_CA_CERT_BUNDLE 值也可以在 UI 中配置为自定义变量,可以是 file 类型(需要证书路径),也可以是 variable 类型(需要证书的文本表示)。
扫描多架构镜像
您可以使用 TRIVY_PLATFORM CI/CD 变量将容器扫描配置为针对特定操作系统和架构运行。例如,要在 .gitlab-ci.yml 文件中配置此值,请使用以下内容:
yamlcontainer_scanning: # 使用 arm64 SaaS Runner 本地扫描 tags: ["saas-linux-small-arm64"] variables: TRIVY_PLATFORM: "linux/arm64"
漏洞允许列表
Tier: 基础版,专业版,旗舰版
Offering: JihuLab.com,私有化部署
先决条件:
- 项目的开发者、维护者或所有者角色。
要将特定漏洞添加到允许列表中,请按以下步骤操作:
- 在 .gitlab-ci.yml 文件中,按照覆盖容器扫描模板的说明,设置 GIT_STRATEGY: fetch。
- 在名为 vulnerability-allowlist.yml 的 YAML 文件中定义允许列表中的漏洞。此文件必须使用 vulnerability-allowlist.yml 数据格式中描述的格式。
- 将 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 文件:
yaml1generalallowlist: 2 CVE-2019-8696: 3 CVE-2014-8166: cups 4 CVE-2017-18248: 5images: 6 registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256: 7 CVE-2018-4180: 8 your.private.registry:5000/centos: 9 CVE-2015-1419: libxml2 10 CVE-2015-1447:
这个例子从 gl-container-scanning-report.json 中排除了:
- 所有具有以下 CVE ID 的漏洞:CVE-2019-8696、CVE-2014-8166、CVE-2017-18248。
- 所有在 registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256 容器镜像中发现的 CVE ID 为 CVE-2018-4180 的漏洞。
- 所有在 your.private.registry:5000/centos 容器中发现的 CVE ID 为 CVE-2015-1419、CVE-2015-1447 的漏洞。
文件格式
-
generalallowlist 块允许你全局指定 CVE ID。所有具有匹配 CVE ID 的漏洞都将从扫描报告中排除。
-
images 块允许你为每个容器镜像独立指定 CVE ID。来自给定镜像且具有匹配 CVE ID 的所有漏洞都将从扫描报告中排除。镜像名称从用于指定要扫描的 Docker 镜像的环境变量之一中检索,例如 $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG 或 CS_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)。
容器扫描作业日志格式
你可以通过查看 container_scanning 作业详情中由容器扫描分析器生成的日志,来验证扫描结果和 vulnerability-allowlist.yml 文件的正确性。
日志包含一个找到的漏洞列表,以表格形式呈现,例如:
plaintext1+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+ 2| 状态 | CVE 严重性 | 软件包名称 | 软件包版本 | CVE 描述 | 3+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+ 4| 已批准 | 高 CVE-2019-3462 | apt | 1.4.8 | apt 版本 1.4.8 及更早版本中,HTTP 传输方法中对 302 重定向字段的消毒不 | 5| | | | | 正确,可能允许中间人攻击者注入内容,从而可能导致目标机器上的远程代码 | 6| | | | | 执行。 | 7+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+ 8| 未批准 | 中 CVE-2020-27350 | apt | 1.4.8 | APT 在解析 .deb 包时存在多个整数溢出和下溢,即 GHSL-2020-168 GHSL-2020- | 9| | | | | 169,位于文件 apt-pkg/contrib/extracttar.cc、apt-pkg/deb/debfile.cc 和 | 10| | | | | apt-pkg/contrib/arfile.cc 中。此问题影响:apt 1.2.32ubuntu0 版本(低于 | 11| | | | | 1.2.32ubuntu0.2);1.6.12ubuntu0 版本(低于 1.6.12ubuntu0.2);2.0.2ub | 12| | | | | untu0 版本(低于 2.0.2ubuntu0.2);2.1.10ubuntu0 版本(低于 2.1.10ubunt | 13| | | | | u0.1); | 14+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+ 15| 未批准 | 中 CVE-2020-3810 | apt | 1.4.8 | APT 在 2.1.2 版本之前,在处理特制的 deb 文件时缺少输入验证,可能导致拒绝 | 16| | | | | 服务。 | 17+------------+-------------------------+------------------------+-----------------------+------------------------------------------------------------------------+
当日志中的漏洞对应的 CVE ID 被添加到 vulnerability-allowlist.yml 文件时,该漏洞会标记为 已批准。
离线环境
Tier: 基础版,专业版,旗舰版
Offering: 私有化部署
要在离线环境中运行容器扫描,你必须进行初始设置并执行持续维护。
初始设置:
- 配置 Runner(确保 docker 或 kubernetes 执行器可用)。
- 设置本地容器镜像仓库。有关详细信息,请参见极狐GitLab 容器镜像仓库。
- 将镜像复制到本地容器镜像仓库。
- 为每个使用容器扫描的项目配置 CI/CD。
- 根据你的需求,你可以选择性地配置以下内容:
持续维护:
- 随着新版本的发布,更新本地容器扫描镜像。
配置 Runner
配置 Runner(确保 docker 或 kubernetes 执行器可用)。有关详细信息,请参见入门指南。
默认情况下,Runner 会从极狐GitLab 容器镜像仓库拉取容器镜像,即使本地有副本。如果你更希望仅使用本地容器镜像,可以将 pull_policy 设置为 if-not-present。但是,除非有充分理由,否则你应保持 pull_policy 设置为默认值。
复制容器镜像
将以下镜像从 JihuLab.com 容器镜像仓库导入到你的本地容器镜像仓库。这个镜像必须可以从你的离线极狐GitLab 实例访问。
plaintextregistry.gitlab.com/security-products/container-scanning:8
将镜像导入本地容器镜像仓库的过程取决于你的网络安全策略。请咨询你的 IT 人员,以找到一种可接受且经批准的流程,通过该流程你可以导入或临时访问外部资源。
为每个项目配置 CI/CD
对于所有使用容器扫描的项目,在应用 CI/CD 配置的所有位置进行编辑。这可能包括:
- 各个项目的 .gitlab-ci.yml 文件
- 流水线执行策略
- 扫描执行策略
使用以下变量更新你的容器扫描配置:
- 可选。如果尚未包含容器扫描模板,请将其添加。
- 将 CS_ANALYZER_IMAGE 设置为本地容器镜像仓库中的容器扫描镜像。
- 可选。如果使用非极狐GitLab 容器镜像仓库,请设置 CS_REGISTRY_USER 和 CS_REGISTRY_PASSWORD 以匹配你的镜像仓库凭据。
- 可选。如果为本地容器镜像仓库使用自签名证书,请设置 CS_DOCKER_INSECURE: "true"。
离线环境的 .gitlab-ci.yml 配置示例:
yaml1include: 2 - template: Jobs/Container-Scanning.gitlab-ci.yml 3 4container_scanning: 5 variables: 6 # 容器扫描特定变量 7 CS_ANALYZER_IMAGE: <hostname>:<port>/analyzers/container-scanning:8 8 CS_REGISTRY_USER: <username> 9 CS_REGISTRY_PASSWORD: <password> 10 CS_DOCKER_INSECURE: "true"
更新本地容器镜像
容器扫描镜像会定期更新并推送到 JihuLab.com 镜像仓库。在离线环境中,你必须更新本地容器镜像仓库中的容器扫描镜像,可以是自动(推荐)或手动方式。
- 手动方法:如果无法通过网络访问 JihuLab.com 镜像仓库,请手动更新本地镜像仓库中的容器扫描镜像。使用与初始设置的复制镜像相同的方法。
- 自动方法:如果你的离线极狐GitLab 实例具有对 JihuLab.com 的读取访问权限,请设置一个计划的流水线,以按预设时间表自动更新镜像。
自动镜像更新方法
以下 .gitlab-ci.yml 摘录演示了如何在本地镜像仓库中自动更新容器扫描镜像。此方法定义了源镜像和目标镜像的变量,然后使用 Docker CLI 从 JihuLab.com 镜像仓库拉取镜像,并将其推送到你的本地镜像仓库。
如果你使用的是非极狐GitLab 镜像仓库,请更新 CI_REGISTRY 值,并通过设置 CI_REGISTRY_USER 和 CI_REGISTRY_PASSWORD 变量来配置身份验证,以匹配你的本地镜像仓库凭据。
yaml1variables: 2 SOURCE_IMAGE: registry.gitlab.com/security-products/container-scanning:8 3 TARGET_IMAGE: $CI_REGISTRY/namespace/container-scanning 4 5image: docker:cli 6 7update-scanner-image: 8 services: 9 - docker:dind 10 script: 11 - docker pull $SOURCE_IMAGE 12 - docker tag $SOURCE_IMAGE $TARGET_IMAGE 13 - echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY --username $CI_REGISTRY_USER --password-stdin 14 - docker push $TARGET_IMAGE
扫描存档格式
版本历史
- 在 GitLab 18.0 中引入了 tar 文件扫描功能。
容器扫描支持存档格式(.tar、.tar.gz)的镜像。例如,可以使用 docker save 或 docker buildx build 创建此类镜像。
要扫描存档文件,请将环境变量 CS_IMAGE 设置为格式 archive://path/to/archive:
- archive:// 方案前缀指定分析器要扫描存档文件。
- path/to/archive 指定要扫描的存档的路径,可以是绝对路径或相对路径。
容器扫描支持遵循 Docker 镜像规范 的 tar 镜像文件。不支持 OCI 压缩包。有关支持格式的更多信息,请参阅 Trivy tar 文件支持。
构建支持的 tar 文件
容器扫描使用 tar 文件中的元数据进行镜像命名。在构建 tar 镜像文件时,请确保镜像已打标签:
shell1# 拉取或构建一个带有名称和标签的镜像 2docker pull image:latest 3# 或者 4docker build . -t image:latest 5# 然后使用 docker save 导出为 tar 6docker save image:latest -o image-latest.tar 7 8# 或使用 buildx build 构建一个带有标签的镜像 9docker buildx create --name container --driver=docker-container 10docker buildx build -t image:latest --builder=container -o type=docker,dest=- . > image-latest.tar 11 12# 使用 podman 13podman build -t image:latest . 14podman save -o image-latest.tar image:latest
镜像名称
容器扫描通过首先评估存档的 manifest.json 并使用 RepoTags 中的第一个项目来确定镜像名称。如果未找到,则使用 index.json 来获取 io.containerd.image.name 注释。如果仍未找到,则使用存档文件名。
- manifest.json 在 Docker 镜像规范 v1.1.0 中定义,使用命令 docker save 创建。
- index.json 格式在 OCI 镜像规范 v1.1.1 中定义。io.containerd.image.name 在 containerd v1.3.0 及更高版本中可用,当使用 ctr image export 时。
扫描在先前作业中构建的存档
要扫描在 CI/CD 作业中构建的存档,你必须将存档工件从构建作业传递到容器扫描作业。使用 artifacts:paths 和 dependencies 关键字将一个作业的工件传递给后续作业:
yaml1build_job: 2 script: 3 - docker build . -t image:latest 4 - docker save image:latest -o image-latest.tar 5 artifacts: 6 paths: 7 - "image-latest.tar" 8 9container_scanning: 10 variables: 11 CS_IMAGE: "archive://image-latest.tar" 12 dependencies: 13 - build_job
从项目仓库扫描存档
要扫描在项目仓库中找到的存档,请确保你的 Git 策略 能够访问你的仓库。在 container_scanning 作业中,将 GIT_STRATEGY 关键字设置为 clone 或 fetch,因为它默认设置为 none。
yamlcontainer_scanning: variables: GIT_STRATEGY: fetch
运行独立的容器扫描工具
可以在不依赖于 CI 作业上下文的情况下,针对 Docker 容器运行极狐GitLab 容器扫描工具。要直接扫描镜像,请按照以下步骤操作:
-
运行 Docker Desktop 或 Docker Machine。
-
运行分析器的 Docker 镜像,在 CI_APPLICATION_REPOSITORY 和 CI_APPLICATION_TAG 变量中传递你要分析的镜像和标签:
shell1docker run \ 2 --interactive --rm \ 3 --volume "$PWD":/tmp/app \ 4 -e CI_PROJECT_DIR=/tmp/app \ 5 -e CI_APPLICATION_REPOSITORY=registry.gitlab.com/gitlab-org/security-products/dast/webgoat-8.0@sha256 \ 6 -e CI_APPLICATION_TAG=bc09fe2e0721dfaeee79364115aeedf2174cce0947b9ae5fe7c33312ee019a4e \ 7 registry.gitlab.com/security-products/container-scanning
结果存储在 gl-container-scanning-report.json 中。
报告 JSON 格式
容器扫描工具会发出 JSON 报告,极狐GitLab Runner 通过 CI/CD 配置文件中的 artifacts:reports 关键字识别这些报告。
CI/CD 作业完成后,Runner 将这些报告上传到极狐GitLab,然后可以在 CI/CD 作业工件中找到它们。在极狐GitLab 旗舰版中,可以在相应的流水线和漏洞报告中查看这些报告。
这些报告必须符合容器扫描报告模式。
CycloneDX 软件物料清单
除了 JSON 报告文件外,容器扫描工具还会为已扫描的镜像输出 CycloneDX 软件物料清单 (SBOM)。此 CycloneDX SBOM 名为 gl-sbom-report.cdx.json,并保存在与 JSON 报告文件 相同的目录中。仅在使用 Trivy 分析器时支持此功能。
可以在依赖项列表中查看此报告。
你可以像其他作业工件一样下载 CycloneDX SBOM。
CycloneDX 报告中的许可证信息
版本历史
- 在 GitLab 18.0 中引入。
容器扫描可以在 CycloneDX 报告中包含许可证信息。此功能默认禁用,以保持向后兼容性。
要在容器扫描结果中启用许可证扫描:
- 在你的 .gitlab-ci.yml 文件中设置 CS_INCLUDE_LICENSES 变量:
yamlcontainer_scanning: variables: CS_INCLUDE_LICENSES: "true"
- 启用此功能后,生成的 CycloneDX 报告将包含容器镜像中检测到的组件的许可证信息。
- 你可以在依赖项列表页面或作为可下载的 CycloneDX 作业工件查看此许可证信息。
需要注意的是,仅支持 SPDX 许可证。但是,不符合 SPDX 的许可证仍会被收录,且不会向用户显示任何错误。
操作系统生命周期终止检测
容器扫描包括检测和报告容器镜像何时使用已达到生命周期终止 (EOL) 的操作系统的能力。已达到 EOL 的操作系统将不再接收安全更新,使其容易受到新发现的安全问题的影响。
EOL 检测功能使用 Trivy 来识别不再受其各自发行版支持的操作系统。当检测到 EOL 操作系统时,它会作为漏洞与其他安全发现一起在你的容器扫描报告中报告。
要启用 EOL 检测,请将 CS_REPORT_OS_EOL 设置为 "true"。
对镜像仓库的容器扫描
Tier: 旗舰版
Offering: JihuLab.com,私有化部署
版本历史
- 在 GitLab 17.1 中引入,带有功能标志 enable_container_scanning_for_registry。默认禁用。
- 在 GitLab 17.2 中为私有化部署启用。
- 在 GitLab 17.2 中 GA。移除了功能标志 enable_container_scanning_for_registry。
当使用 latest 标签推送容器镜像时,安全策略机器人会在针对默认分支的新流水线中自动触发容器扫描作业。
与常规容器扫描不同,扫描结果不包含安全报告。取而代之的是,对镜像仓库的容器扫描依赖于持续漏洞扫描来检查扫描检测到的组件。
当识别出安全发现时,极狐GitLab 会使用这些发现填充漏洞报告。漏洞可以在漏洞报告页面的 容器镜像仓库漏洞 选项卡下查看。
对镜像仓库的容器扫描仅在向极狐GitLab 咨询数据库发布新咨询时填充漏洞报告。支持用所有现有咨询数据(而非仅新检测到的数据)填充漏洞报告的功能已在史诗 11219 中提出。
开启对镜像仓库的容器扫描
先决条件:
- 项目的安全管理员、维护者或所有者角色。
- 项目不能为空。如果你使用空项目仅用于存储容器镜像,此功能将无法按预期工作。作为一种解决方法,请确保项目在默认分支上包含一个初始提交。
- 默认情况下,每个项目每天限制 50 次扫描。
- 你必须配置容器镜像仓库通知。
- 你必须配置软件包元数据数据库。在 JihuLab.com 上,默认已配置。
要开启对极狐GitLab 容器镜像仓库的容器扫描:
- 在顶部栏中,选择 搜索或跳转到 并查找你的项目。
- 在左侧边栏中,选择 安全 > 安全配置。
- 向下滚动到 Container Scanning For Registry 部分,然后打开开关。
在离线或气隙环境中使用
要在离线或气隙环境中使用对镜像仓库的容器扫描,你必须使用本地副本的容器扫描分析器镜像。由于此功能由极狐GitLab 安全策略机器人管理,因此无法通过编辑 .gitlab-ci.yml 文件来配置分析器镜像。
相反,你必须通过在极狐GitLab UI 中设置 CS_ANALYZER_IMAGE CI/CD 变量来覆盖默认的扫描器镜像。动态创建的扫描作业会继承在 UI 中定义的变量。你可以使用项目、群组或实例 CI/CD 变量。
先决条件:
- 项目或群组的维护者或所有者角色。
要配置自定义扫描器镜像:
- 在顶部栏中,选择 搜索或跳转到 并查找你的项目或群组。
- 在左侧边栏中,选择 设置 > CI/CD。
- 展开 变量 部分。
- 选择 添加变量 并填写详细信息:
- 键:CS_ANALYZER_IMAGE
- 值:指向你镜像的容器扫描镜像的完整 URL。例如,my.local.registry:5000/analyzers/container-scanning:7。
- 选择 添加变量。
极狐GitLab 安全策略机器人触发扫描时将使用指定的镜像。
漏洞数据库
所有分析器镜像每天更新。
这些镜像使用来自上游咨询数据库的数据:
- AlmaLinux 安全公告
- Amazon Linux 安全中心
- Arch Linux 安全跟踪器
- SUSE CVRF
- CWE 公告
- Debian 安全缺陷跟踪器
- GitHub 安全公告
- Go 漏洞数据库
- CBL-Mariner 漏洞数据
- NVD
- OSV
- Red Hat OVAL v2
- Red Hat 安全数据 API
- Photon 安全公告
- Rocky Linux 更新信息
- Ubuntu CVE 跟踪器(仅限 2021 年中及以后的数据源)
除了这些扫描器提供的源数据外,极狐GitLab 还维护了以下漏洞数据库:
- 专有的极狐GitLab 公告数据库。
- 开源的极狐GitLab 公告数据库(开源版)。
在极狐GitLab 旗舰版中,极狐GitLab 公告数据库的数据会合并进来,以增强外部源数据。在极狐GitLab 专业版和基础版中,极狐GitLab 公告数据库(开源版)的数据会合并进来以增强外部源数据。这种增强仅适用于 Trivy 扫描器的分析器镜像。
其他分析器的数据库更新信息请参考维护表。
漏洞解决方案(自动修复)
Tier: 旗舰版
Offering: JihuLab.com,私有化部署
部分漏洞可以通过应用极狐GitLab 自动生成的解决方案来修复。
要启用修复支持,扫描工具必须能够访问由 CI/CD 变量 CS_DOCKERFILE_PATH 指定的 Dockerfile。为确保扫描工具能够访问该文件,你需要按照本文档覆盖容器扫描模板部分中的说明,在 .gitlab-ci.yml 文件中设置 GIT_STRATEGY: fetch。
阅读更多关于漏洞解决方案的内容。