Trivy 数据库管理机制与配置指南:漏洞库、Java 库与检查包的下载、更新与清理

【免费下载链接】trivy Find vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more 【免费下载链接】trivy 项目地址: https://gitcode.com/GitHub_Trending/tr/trivy

Trivy 在安装后只包含扫描引擎本身,缺少判定漏洞、配置错误所需的各类安全情报数据;这些被统称为“Trivy Databases”的数据由 Trivy 按需自动下载与维护。本文以官方文档 docs/guide/configuration/db.md 为主体,结合仓库中 pkg/db/db.gopkg/flag/db_flags.gopkg/commands/clean/run.go 等源码实现,系统讲解三类数据库的内容与分发位置、默认拉取顺序、自定义仓库地址、跳过更新、仅下载更新以及清理缓存的完整配置方法。读完本文,你将能够为离线环境、内网镜像源、CI 流水线等场景精确控制 Trivy 的数据获取行为。

认识 Trivy 依赖的三类数据库

Trivy 的核心价值在于扫描,而扫描结论依赖其定期从安全数据源聚合出的“数据库”。这些数据以 OCI 镜像形式发布,Trivy 启动时若检测到本地缺失或过期,会自动从注册中心拉取,因此日常使用时通常无需关心。根据官方文档,Trivy 主要依赖以下三类数据:

数据库制品名内容用途
漏洞数据库(Vulnerabilities DB)trivy-db从多个数据源聚合的 CVE 信息仅用于漏洞扫描
Java 索引数据库(Java DB)trivy-java-dbJava 制品及其哈希摘要的索引仅在 JAR 扫描中用于识别 Java 制品
检查包(Checks Bundle)trivy-checks配置错误(Misconfiguration)检查规则逻辑仅用于 misconfiguration/IaC 扫描

说明:上述清单并非 Trivy 全部外部连通性需求的穷举。某些特定功能还会依赖其他外部资源,完整网络访问清单参见 Advanced Network Scenarios(高级网络场景,air-gap)

值得注意区分两类数据各自的消费方:

  • trivy-dbtrivy-java-db 在源码中分别由 pkg/db/db.gopkg/javadb/client.go 两个客户端负责拉取与校验,本地以 BoltDB(bbolt)数据库文件形式存放,pkg/db/db.go 中定义媒体类型为 application/vnd.aquasec.trivy.db.layer.v1.tar+gzip
  • trivy-checks 则是以 OPA bundle 形式分发的规则集(docs/guide/scanner/misconfiguration/check/builtin.md),由 pkg/policy/policy.go 中的 policy.Client 管理,媒体类型为 application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip

三者虽然同为“数据”,但更新策略、回退逻辑并不相同,下文会逐一说明。

数据库的分发位置与默认拉取顺序

官方发布的三类数据库镜像地址如下:

注册中心镜像地址
GHCRghcr.io/aquasecurity/trivy-db
ghcr.io/aquasecurity/trivy-java-db
ghcr.io/aquasecurity/trivy-checks
Docker Hubaquasec/trivy-db
aquasec/trivy-java-db
aquasec/trivy-checks
AWS ECRpublic.ecr.aws/aquasecurity/trivy-db
public.ecr.aws/aquasecurity/trivy-java-db

此外,这些镜像也通过 Google Container Registry Mirror 等 pull-through 缓存型注册中心提供(例如 mirror.gcr.io)。

Trivy 拉取数据库时会按固定顺序依次尝试以下默认仓库:

  1. mirror.gcr.io/aquasec
  2. ghcr.io/aquasecurity

该默认顺序与源码一一对应。在 pkg/flag/db_flags.go 中,DBRepositoryFlagJavaDBRepositoryFlag 的默认值分别取 db.DefaultGCRRepository/db.DefaultGHCRRepositoryjavadb.DefaultGCRRepository/javadb.DefaultGHCRRepository;而在 pkg/db/db.gopkg/javadb/client.go 中,这两个常量被定义为:

mirror.gcr.io/aquasec/trivy-db:<schema>
ghcr.io/aquasecurity/trivy-db:<schema>

即默认把 GCR 镜像放在首位、GHCR 作为备用。可通过下述“数据库位置配置”一节指定额外的备用仓库。

核心机制:何时判定需要更新

理解各配置项前,先了解 Trivy 判断“数据库是否需要更新”的内部逻辑。以漏洞库为例,pkg/db/db.goClient.NeedsUpdate 的判定依据包括:

  • 本地文件缺失:若 trivy.dbmetadata.json 不存在(如首次运行),必须下载;此时若同时指定跳过更新会直接报错 --skip-db-update cannot be specified on the first run——首次运行无法跳过数据库下载
  • Schema 版本校验db.SchemaVersion(漏洞库 schema 版本号)与本地元数据不一致时强制更新;若本地 schema 高于当前 Trivy 支持版本,会提示升级 Trivy。
  • 更新周期控制:Trivy 通过 metadata.json 中的 DownloadedAtNextUpdate 字段判断是否到期。源码显示,若当前时间早于 NextUpdate,或距上次下载不足 1 小时,会直接跳过更新,避免频繁重复拉取。

Java 库的更新判定逻辑与此类似(见 pkg/javadb/client.go),检查包(trivy-checks)则默认按 24 小时间隔更新(pkg/policy/policy.go)。

这些判定逻辑决定了各“跳过更新”类配置只在已有可用本地缓存的前提下才安全生效,离线环境中务必先手动下载一次。

配置数据库位置(自定义镜像仓库)

trivy-dbtrivy-java-dbtrivy-checks 都支持从备用位置下载,对应三个命令行 flag:

  • --db-repository
  • --java-db-repository
  • --checks-bundle-repository

取值应为容器注册中心中的镜像地址。例如使用自建 GitLab 托管的漏洞库镜像扫描 alpine

trivy image --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db alpine

多仓库回退

--db-repository(及 --java-db-repository支持指定多个值,Trivy 会按给出顺序依次尝试。遇到瞬时错误(如 HTTP 429 或 5xx)时自动回退到下一个仓库:

trivy image --db-repository my.registry.local/trivy-db --db-repository registry.gitlab.com/gitlab-org/security-products/dependencies/trivy-db alpine

回退行为的底层实现在 pkg/oci/artifact.goArtifacts.Download 中:它遍历全部仓库逐个下载,仅当错误被判定为“瞬时/可重试”(如 Temporary()、镜像的 BLOB_UNKNOWN 错误码,见 pkg/oci/artifact.go)时才继续尝试下一个仓库;Unauthorized/Denied 等鉴权类错误不会触发回退,并会提示查阅故障排查文档。

注意:--checks-bundle-repository 不支持多仓库回退。原因是检查包拉取失败时,Trivy 会直接回退到内嵌检查规则(随二进制分发的 built-in checks),无需再试其他镜像源。这正是文档明确“Checks Bundle 不支持多选项回退”的原因。

两个易踩的坑

  • 覆盖即丢失默认值:设置上述仓库位置 flag 会整体覆盖默认值(含官方地址)。若希望保留官方源作为后备,必须把默认仓库地址一并列入你设置的值列表中。例如希望先查内网镜像再回退官方源,应写 --db-repository my.registry.local/trivy-db --db-repository ghcr.io/aquasecurity/trivy-db
  • 未指定 tag 时默认使用 schema 号而非 latest:拉取 trivy-dbtrivy-java-db 时,若不写镜像 tag,Trivy 会默认使用数据库 schema 版本号作为 tag,保证数据库与当前 Trivy 二进制兼容。这在 pkg/flag/db_flags.goparseRepository 中有明确实现:解析仓库引用时若发现 tag 为空,会自动补上 strconv.Itoa(dbSchemaVersion)(漏洞库取 db.SchemaVersion,Java 库取 javadb.SchemaVersion)。

对应地,这些 flag 也都有 trivy.yaml 配置项(ConfigName):--db-repositorydb.repository--java-db-repositorydb.java-repository--checks-bundle-repositorymisconfiguration.checks-bundle-repository(见 pkg/flag/db_flags.gopkg/flag/misconf_flags.go),便于统一写入配置文件。

跳过更新(Skip updates)

在离线/内网环境或明确不想联网时,可分别阻止某一类数据库的下载:

  • --skip-db-update:跳过漏洞库更新
  • --skip-java-db-update:跳过 Java 索引库更新
  • --skip-check-update:跳过检查包更新

示例:

trivy image --skip-db-update --skip-java-db-update --skip-check-update alpine

使用时需牢记:跳过的前提是本地已有匹配 schema 版本的可用数据。结合 pkg/db/db.goNeedsUpdatevalidate 实现可看到两个约束:

  1. 首次运行、本地根本没有数据库文件时,即使指定了 --skip-db-update 也会报错退出;
  2. 本地数据库 schema 与当前 Trivy 不匹配时同样禁止跳过(报 --skip-db-update cannot be specified with the old DB schema)。

另外,--skip-db-update 存在一个已废弃的别名 --skip-update(见 pkg/flag/db_flags.go 中带 Deprecated: true 的 Alias 定义),新写法请统一使用 --skip-db-update

仅下载不扫描(Only update)

若只想保持本地缓存最新而不执行扫描,可用以下两个 flag:

  • --download-db-only:仅下载/更新漏洞数据库
  • --download-java-db-only:仅下载/更新 Java 索引数据库

示例:

trivy image --download-db-only

执行后 Trivy 只更新数据并填充本地缓存,供后续扫描复用——适合在 CI 中预先准备缓存、或在固定维护窗口统一拉取最新情报。目前没有单独“只下载 Checks Bundle”的选项。

源码层面对该组的互斥校验非常严格(pkg/flag/db_flags.go ToOptions):以下组合会直接返回参数错误并退出——

  • --download-db-only--download-java-db-only 同时指定;
  • --skip-db-update--download-db-only 同时指定;
  • --skip-java-db-update--download-java-db-only 同时指定。

即“跳过”与“仅下载”语义上互相矛盾,Trivy 不允许你写出自相矛盾的命令。

清理数据库与缓存(trivy clean)

需要强制重建本地数据时,使用 trivy clean 命令删除各类缓存与数据库。可选择要清理的组件:

选项说明
-a / --all删除全部缓存
--checks-bundle删除检查包
--java-db删除 Java 数据库
--scan-cache删除扫描缓存(容器与 VM 镜像分析结果)
--vuln-db删除漏洞数据库

示例(同时删除漏洞库与 Java 库):

$ trivy clean --vuln-db --java-db
2024-06-24T11:42:31+06:00       INFO    Removing vulnerability database...
2024-06-24T11:42:31+06:00       INFO    Removing Java database...

对照 pkg/commands/clean/run.go 的实现可补充几个源码级细节:

  • 必须显式指定至少一个清理目标:若未指定任何选项,Run 直接返回 no clean option is specified 错误(pkg/commands/clean/run.go)。
  • --all 是其余选项的聚合:指定 --all 后,内部会把 --scan-cache--vuln-db--java-db--checks-bundle--vex-repo 全部置为 truepkg/commands/clean/run.go)。
  • 当前源码中 clean 命令还额外支持 --vex-repo(清理 VEX 仓库缓存),其 flag 定义位于 pkg/flag/clean_flags.go
  • 历史上的 --reset 全局 flag 已废弃,统一改用 trivy clean --allpkg/flag/db_flags.go 中标记 Removed: Use "trivy clean --all" instead.)。
  • 各类清理操作的落点:漏洞库存放在 <cache-dir>/db 目录(pkg/db/db.goDir 函数),检查包位于 <cache-dir>/policypkg/policy/policy.go),清理即删除对应目录(如 os.RemoveAll(c.dbDir),见 pkg/db/db.go)。缓存根目录的具体取值与修改方式见 docs/guide/configuration/cache.md

底层下载流水线一览

无论哪类数据库,最终下载都收敛到统一的 OCI artifact 下载链路(pkg/oci/artifact.go):

  1. populate 阶段将仓库地址解析为 OCI reference,并通过 remote.Image 拉取远程镜像的 manifest;
  2. 校验镜像必须为单 layer OCI artifact,且媒体类型需与预期一致(漏洞库为 application/vnd.aquasec.trivy.db.layer.v1.tar+gzip,检查包为 application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip);
  3. 将 layer 流式下载到临时目录(带进度条,--no-progress 可抑制),再做本地解压拷贝到目标缓存目录,全程对文件名做了路径穿越防护。

这条链路同时解释了文档中的两个关键结论:多仓库按序回退仅适用于可重试瞬时错误;而 Checks Bundle 因失败后可回退内嵌规则,因此无需为其配置多仓库回退。

常见问题与最佳实践小结

  • 首跑即断网的环境:先在有网机器上执行一次 trivy image --download-db-only --download-java-db-only(或直接扫描一次)填充缓存,再以 --skip-db-update --skip-java-db-update --skip-check-update 离线运行;完整的 air-gap 部署方案参见 docs/guide/advanced/air-gap.md
  • 内网镜像源:将三组 *repository flag 指向内网私有仓库并显式保留官方源作后备;记得处理“未写 tag 默认用 schema 号”的约定,避免内网镜像只同步了 latest 而拉取失败。
  • 数据异常/版本升级:遇到 schema 不匹配或缓存损坏警告时,用 trivy clean --all 清空后重新下载即可;若 DB 元数据缺失 DownloadedAt(例如用 oras 手动灌入的 DB),Trivy 会判定可能损坏并重新下载,此时离线场景需使用 --skip-db-update(见 pkg/db/db.go 的注释说明)。
  • 配置沉淀:以上所有 flag 均有对应的 trivy.yaml 配置键(如 db.repositorydb.skip-updateclean.vuln-db 等),建议将仓库地址与跳过策略写入统一配置文件,保证团队与 CI 行为一致。

【免费下载链接】trivy Find vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more 【免费下载链接】trivy 项目地址: https://gitcode.com/GitHub_Trending/tr/trivy

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐