首页
/ Trivy 新增漏洞通告源实战:vuln-list-update → trivy-db → Trivy 三仓库协同流程全解析

Trivy 新增漏洞通告源实战:vuln-list-update → trivy-db → Trivy 三仓库协同流程全解析

2026-09-05 22:03:58作者:史锋燃Gardner

本篇技术指南围绕 Trivy 官方文档 Add Vulnerability Advisory Source 展开,讲解如何为一个全新的操作系统或软件生态向 Trivy 漏洞数据库贡献新的漏洞通告源(vulnerability advisory source)。你将完整掌握横跨三个仓库(vuln-list-update、trivy-db、trivy)的改造步骤、每一步的关键任务清单,以及分层验证数据抓取、数据库构建和最终扫描结果的完整测试命令,并结合本仓库中 Echo OS 支持的真实源码(OS 检测分析器、漏洞扫描器、测试用例)理解这些改造点在实际代码中的落位。

背景:Trivy 漏洞数据库的多仓库流水线

要新增一个漏洞通告源,首先需要理解 Trivy 漏洞数据库的构建流水线。根据官方 Vulnerability Data Sources 概览,数据流如下:

graph LR
    A[Advisory Sources] -->|vuln-list-update| B[vuln-list]
    B --> C["trivy-db<br/>(Trivy DB)"]
    C --> D["trivy<br/>(Trivy CLI)"]
    E[GitHub-managed<br/>Advisories] --> C

整条链路分为四个角色:

  1. 通告收集(vuln-list-update 仓库):定时(cron)运行抓取脚本,从上游 API 或 Web 源拉取原始漏洞通告,存入 vuln-list 仓库。如果通告本身已经在 Git 仓库中管理(例如 GitHub Security Advisories),可以跳过这一步。
  2. 数据库构建(trivy-db 仓库):内置针对每个数据源的解析器(parser),将原始通告转换为 Trivy 的数据库格式(BoltDB),并定时发布。
  3. 数据库消费(trivy 主仓库,即本仓库):扫描时下载最新漏洞数据库,结合 OS 分析器识别目标系统,再执行漏洞检测。

把原始通告存入 vuln-list 仓库还带来几个实际收益:变更透明可追溯、可通过 Web 界面浏览、在上游服务器不稳定时提供缓冲、提供稳定的通告引用 URL、在入库前校验数据质量避免脏数据破坏 Trivy DB、并在上游格式变化时保留历史数据。需要特别注意:vuln-list 仓库不接受手动贡献,不直接接受针对它的 PR,所有数据变更必须经由 vuln-list-update 脚本完成。

前置条件

开始改造前,官方文档要求你确认三件事:

  1. 已确定上游通告源及其 API/数据格式;
  2. 已确认该数据源尚未被 Trivy 收录;
  3. 已在 Trivy 仓库创建 GitHub Discussion 或 Issue 讨论新增事宜(社区沟通先行的原则)。

Step 1:新增抓取脚本(vuln-list-update 仓库)

如果你的通告源已经在 Git 仓库中管理(如 GitHub、GitLab 托管的安全通告),可以跳过本步骤。

在 vuln-list-update 仓库中创建抓取脚本,负责从上游源收集通告。关键任务包括:

  • 从上游 API 或数据源抓取通告;
  • 校验通告格式与数据内容;
  • 按照 vuln-list 仓库的目录结构,将通告保存为 JSON 文件;
  • 尽可能原样存储原始数据:避免对通告字段做预处理或修改,按上游提供的形态保存(出于一致性考虑,YAML 转 JSON 这类格式转换是允许的);
  • 包含所有必要的元数据(CVE ID、受影响版本、严重级别等)。

官方文档给出的参考实现是 Echo OS 支持在 vuln-list-update 中的首个 PR(vuln-list-update#350)。

Step 2:新增解析器(trivy-db 仓库)

在 trivy-db 仓库中创建解析器,把原始通告转换为 Trivy 数据库格式。关键任务包括:

  • pkg/vulnsrc/ 目录下新建一个漏洞源(vulnerability source)包;
  • 实现通告解析逻辑;
  • 将通告字段映射到 Trivy 的漏洞 schema;
  • 正确处理版本区间与受影响软件包;
  • 如有可用的 CVE 映射,一并存储;
  • 为解析器编写单元测试。

参考实现是 Echo 支持的 trivy-db PR(trivy-db#528)。一个可印证的细节:trivy 主仓库通过 Go module 依赖 trivy-db,Echo 的扫描器直接导入其通告源接口:

// pkg/detector/ospkg/echo/echo.go
import (
    "github.com/aquasecurity/trivy-db/pkg/db"
    dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
    echoDb "github.com/aquasecurity/trivy-db/pkg/vulnsrc/echo"
    ...
)

也就是说,Step 2 在 trivy-db 中写好的 vulnsrc/echo 解析器,正是 Step 3 中 trivy 主仓库扫描器通过 echoDb.NewVulnSrc() 消费的数据入口。

Step 3:新增 OS/生态支持(Trivy 主仓库)

回到本仓库,为新操作系统或包生态补齐扫描端能力。关键任务包括:

  • pkg/fanal/analyzer/os/ 下新增 OS 分析器以检测该 OS;
  • 如有特殊处理需求,实现漏洞检测逻辑;
  • 增加带测试数据的集成测试;
  • 更新文档,收录新的数据源。

源码印证:Echo OS 支持的完整落位

Echo 是 trivy 仓库中一个完整的"新增 OS 支持"范例,可以从源码中看清三个改造点各自落在哪里。

1. OS 识别:os-release 分析器。Trivy 通过 os-release 分析器 解析 etc/os-release 等文件的 ID 字段来判定 OS 家族,Echo 的支持就是在这里把 ID=echo 映射为 types.Echo

// pkg/fanal/analyzer/os/release/release.go
case "echo":
    return types.Echo

该分析器关注的文件清单包括 etc/os-releaseusr/lib/os-release 等(见同文件中的 requiredFiles 变量),并配有对应的检测测试数据 release/testdata/echo

2. 漏洞扫描器:按 OS 分派的 driver。OS 包漏洞检测的总入口是 pkg/detector/ospkg/detect.go,其中维护了一张 OS 家族到扫描器的 drivers 映射表,Echo 的注册项为:

// pkg/detector/ospkg/detect.go
drivers = map[ftypes.OSType]driver.Driver{
    ftypes.Alpine: alpine.NewScanner(),
    ...
    ftypes.Echo:   echo.NewScanner(),
    ...
}

3. 扫描器实现:pkg/detector/ospkg/echo/echo.go 展示了新增 OS 扫描器需要实现的核心逻辑,可以从中读出三处值得注意的设计决策:

  • 通告查询与版本比较Detect 方法遍历安装列表中的每个包,调用 trivy-db 的 VulnSrc.Get 获取该包的通告,再使用 go-deb-version 库比较已安装版本与修复版本——只有当 installedVersion.LessThan(fixedVersion) 时才判定为存在漏洞;通告自带的严重级别会被标注 SeveritySource = vulnerability.Echo,表明严重度直接来自 Echo 通告源而非通用评级;
  • 滚动发行版的版本处理IsSupportedVersion 恒返回 true,源码注释解释原因是 "Echo is a rolling distro, meaning there are no versions"——滚动发行版没有固定的版本支持窗口,因此无需校验 OS 版本是否在支持范围内;
  • 不过滤软件包FilterPackages 直接原样返回全部包。注释说明 Echo 的通告 feed 并不绑定某个基础 OS 发行商的软件仓库,它甚至会构建并修补 Debian 本身不提供的软件(如 docker-compose-plugin、gitlab-runner、gh),按仓库类别过滤包反而可能丢掉 feed 实际覆盖的检测结果。

4. 测试与数据。Echo 扫描器配有完整的单元测试 echo_test.go 与测试夹具 testdata/fixtures/data-source.yaml,夹具中声明了数据源名称 Echo,正是 Step 2 中 trivy-db 解析器写入数据库的 DataSource 字段在扫描结果中的对应体现。

完整示例:Echo OS 支持的三个协调 PR

Echo OS 支持正是按上述流程分三个 PR 协同完成的,可作为新增任何 OS/生态支持的时间线模板:

  1. vuln-list-update:从 https://advisory.echohq.com/data.json 抓取 Echo 通告(PR: vuln-list-update#350);
  2. trivy-db:解析 Echo 通告并写入数据库(PR: trivy-db#528);
  3. Trivy:识别 Echo OS 并执行漏洞扫描(PR: trivy#8833,对应本仓库 pkg/fanal/analyzer/os/release/release.gopkg/detector/ospkg/echo/ 等改动)。

测试你的改动:三层验证流程

文档给出自下而上的三层测试路径,建议逐层通过后再进入下一层。

1. 测试 vuln-list-update

先抓取全部已有通告(构建数据库的前提):

cd vuln-list-update
go run main.go -vuln-list-dir /path/to/vuln-list

然后只针对你的新数据源抓取,隔离验证:

go run main.go -target your-source -vuln-list-dir /path/to/vuln-list

确认新通告按预期保存到 vuln-list 目录结构中。

2. 测试 trivy-db

cd trivy-db
make db-build CACHE_DIR=/path/to/cache

确认数据库构建无错误且包含你的通告。

注意:CACHE_DIR 应指向 vuln-list 目录的父目录。例如 vuln-list 位于 /tmp/test/vuln-list 时,应设置 CACHE_DIR=/tmp/test

可以使用 BoltDB 可视化工具(如 boltwiz)检查构建产物:

# 打开数据库
boltwiz out/trivy.db

借此直观验证你的漏洞数据是否被正确写入数据库(桶结构、键值内容)。

3. 测试 Trivy

# 使用你的改动构建 Trivy
mage build

# 使用本地数据库扫描测试镜像
./trivy image --skip-db-update --cache-dir /path/to/cache your-test-image

其中 --skip-db-update 让 Trivy 跳过在线拉取,改用 --cache-dir 指定的本地数据库,从而验证的是你本地构建的漏洞数据而非官方发布版。最终确认来自新数据源的漏洞能被正确检出——对 Echo 这类实现,可对照 echo_test.go 中的用例核对检测结果的严重级别、修复版本与 DataSource 字段。

获取帮助

新增过程中遇到问题时,官方文档建议:

  1. 先参考 vuln-list-update、trivy-db 中已有数据源的实现作为参照(本仓库 pkg/detector/ospkg/ 下各 OS 扫描器目录同样是良好的结构范例);
  2. 在 Trivy 仓库发起 Discussion 与社区讨论。

综上,向 Trivy 贡献一个新漏洞通告源是一项跨三个仓库的工程:抓取层保证数据可追溯地入库,解析层保证数据符合 Trivy schema,扫描层保证 OS 可识别、漏洞可匹配。以 Echo OS 为例,从 ID=echo 的 OS 识别、到 drivers 表中的扫描器注册、再到滚动发行版特化的版本与包过滤策略,每一步都有明确的源码位置与测试覆盖,可以作为你的实现蓝本完整复现。

登录后查看全文
热门项目推荐
相关项目推荐