如何快速上手Park UI:5分钟完成React组件集成
Trivy 数据库管理机制与配置指南:漏洞库、Java 库与检查包的下载、更新与清理
Trivy 在安装后只包含扫描引擎本身,缺少判定漏洞、配置错误所需的各类安全情报数据;这些被统称为“Trivy Databases”的数据由 Trivy 按需自动下载与维护。本文以官方文档 docs/guide/configuration/db.md 为主体,结合仓库中 pkg/db/db.go、pkg/flag/db_flags.go、pkg/commands/clean/run.go 等源码实现,系统讲解三类数据库的内容与分发位置、默认拉取顺序、自定义仓库地址、跳过更新、仅下载更新以及清理缓存的完整配置方法。读完本文,你将能够为离线环境、内网镜像源、CI 流水线等场景精确控制 Trivy 的数据获取行为。
认识 Trivy 依赖的三类数据库
Trivy 的核心价值在于扫描,而扫描结论依赖其定期从安全数据源聚合出的“数据库”。这些数据以 OCI 镜像形式发布,Trivy 启动时若检测到本地缺失或过期,会自动从注册中心拉取,因此日常使用时通常无需关心。根据官方文档,Trivy 主要依赖以下三类数据:
| 数据库 | 制品名 | 内容 | 用途 |
|---|---|---|---|
| 漏洞数据库(Vulnerabilities DB) | trivy-db | 从多个数据源聚合的 CVE 信息 | 仅用于漏洞扫描 |
| Java 索引数据库(Java DB) | trivy-java-db | Java 制品及其哈希摘要的索引 | 仅在 JAR 扫描中用于识别 Java 制品 |
| 检查包(Checks Bundle) | trivy-checks | 配置错误(Misconfiguration)检查规则逻辑 | 仅用于 misconfiguration/IaC 扫描 |
说明:上述清单并非 Trivy 全部外部连通性需求的穷举。某些特定功能还会依赖其他外部资源,完整网络访问清单参见 Advanced Network Scenarios(高级网络场景,air-gap)。
值得注意区分两类数据各自的消费方:
trivy-db与trivy-java-db在源码中分别由 pkg/db/db.go 与 pkg/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。
三者虽然同为“数据”,但更新策略、回退逻辑并不相同,下文会逐一说明。
数据库的分发位置与默认拉取顺序
官方发布的三类数据库镜像地址如下:
| 注册中心 | 镜像地址 |
|---|---|
| GHCR | ghcr.io/aquasecurity/trivy-db |
ghcr.io/aquasecurity/trivy-java-db | |
ghcr.io/aquasecurity/trivy-checks | |
| Docker Hub | aquasec/trivy-db |
aquasec/trivy-java-db | |
aquasec/trivy-checks | |
| AWS ECR | public.ecr.aws/aquasecurity/trivy-db |
public.ecr.aws/aquasecurity/trivy-java-db |
此外,这些镜像也通过 Google Container Registry Mirror 等 pull-through 缓存型注册中心提供(例如 mirror.gcr.io)。
Trivy 拉取数据库时会按固定顺序依次尝试以下默认仓库:
mirror.gcr.io/aquasecghcr.io/aquasecurity
该默认顺序与源码一一对应。在 pkg/flag/db_flags.go 中,DBRepositoryFlag 与 JavaDBRepositoryFlag 的默认值分别取 db.DefaultGCRRepository/db.DefaultGHCRRepository 与 javadb.DefaultGCRRepository/javadb.DefaultGHCRRepository;而在 pkg/db/db.go 与 pkg/javadb/client.go 中,这两个常量被定义为:
mirror.gcr.io/aquasec/trivy-db:<schema>
ghcr.io/aquasecurity/trivy-db:<schema>
即默认把 GCR 镜像放在首位、GHCR 作为备用。可通过下述“数据库位置配置”一节指定额外的备用仓库。
核心机制:何时判定需要更新
理解各配置项前,先了解 Trivy 判断“数据库是否需要更新”的内部逻辑。以漏洞库为例,pkg/db/db.go 中 Client.NeedsUpdate 的判定依据包括:
- 本地文件缺失:若
trivy.db或metadata.json不存在(如首次运行),必须下载;此时若同时指定跳过更新会直接报错--skip-db-update cannot be specified on the first run——首次运行无法跳过数据库下载。 - Schema 版本校验:
db.SchemaVersion(漏洞库 schema 版本号)与本地元数据不一致时强制更新;若本地 schema 高于当前 Trivy 支持版本,会提示升级 Trivy。 - 更新周期控制:Trivy 通过
metadata.json中的DownloadedAt、NextUpdate字段判断是否到期。源码显示,若当前时间早于NextUpdate,或距上次下载不足 1 小时,会直接跳过更新,避免频繁重复拉取。
Java 库的更新判定逻辑与此类似(见 pkg/javadb/client.go),检查包(trivy-checks)则默认按 24 小时间隔更新(pkg/policy/policy.go)。
这些判定逻辑决定了各“跳过更新”类配置只在已有可用本地缓存的前提下才安全生效,离线环境中务必先手动下载一次。
配置数据库位置(自定义镜像仓库)
trivy-db、trivy-java-db 与 trivy-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.go 的 Artifacts.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-db或trivy-java-db时,若不写镜像 tag,Trivy 会默认使用数据库 schema 版本号作为 tag,保证数据库与当前 Trivy 二进制兼容。这在 pkg/flag/db_flags.go 的parseRepository中有明确实现:解析仓库引用时若发现 tag 为空,会自动补上strconv.Itoa(dbSchemaVersion)(漏洞库取db.SchemaVersion,Java 库取javadb.SchemaVersion)。
对应地,这些 flag 也都有 trivy.yaml 配置项(ConfigName):--db-repository ↔ db.repository,--java-db-repository ↔ db.java-repository,--checks-bundle-repository ↔ misconfiguration.checks-bundle-repository(见 pkg/flag/db_flags.go 与 pkg/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.go 的 NeedsUpdate 与 validate 实现可看到两个约束:
- 首次运行、本地根本没有数据库文件时,即使指定了
--skip-db-update也会报错退出; - 本地数据库 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全部置为true(pkg/commands/clean/run.go)。- 当前源码中
clean命令还额外支持--vex-repo(清理 VEX 仓库缓存),其 flag 定义位于 pkg/flag/clean_flags.go。 - 历史上的
--reset全局 flag 已废弃,统一改用trivy clean --all(pkg/flag/db_flags.go 中标记Removed: Use "trivy clean --all" instead.)。 - 各类清理操作的落点:漏洞库存放在
<cache-dir>/db目录(pkg/db/db.go 的Dir函数),检查包位于<cache-dir>/policy(pkg/policy/policy.go),清理即删除对应目录(如os.RemoveAll(c.dbDir),见 pkg/db/db.go)。缓存根目录的具体取值与修改方式见 docs/guide/configuration/cache.md。
底层下载流水线一览
无论哪类数据库,最终下载都收敛到统一的 OCI artifact 下载链路(pkg/oci/artifact.go):
populate阶段将仓库地址解析为 OCI reference,并通过remote.Image拉取远程镜像的 manifest;- 校验镜像必须为单 layer OCI artifact,且媒体类型需与预期一致(漏洞库为
application/vnd.aquasec.trivy.db.layer.v1.tar+gzip,检查包为application/vnd.cncf.openpolicyagent.layer.v1.tar+gzip); - 将 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。 - 内网镜像源:将三组
*repositoryflag 指向内网私有仓库并显式保留官方源作后备;记得处理“未写 tag 默认用 schema 号”的约定,避免内网镜像只同步了latest而拉取失败。 - 数据异常/版本升级:遇到 schema 不匹配或缓存损坏警告时,用
trivy clean --all清空后重新下载即可;若 DB 元数据缺失DownloadedAt(例如用oras手动灌入的 DB),Trivy 会判定可能损坏并重新下载,此时离线场景需使用--skip-db-update(见 pkg/db/db.go 的注释说明)。 - 配置沉淀:以上所有 flag 均有对应的 trivy.yaml 配置键(如
db.repository、db.skip-update、clean.vuln-db等),建议将仓库地址与跳过策略写入统一配置文件,保证团队与 CI 行为一致。
更多推荐
所有评论(0)