4. Trivy扫描文件系统
文件系统扫描是 Trivy 最基础也是最常用的功能之一。与镜像扫描不同,文件系统扫描直接对本地目录中的文件进行静态分析,无需运行容器或拉取镜像。本章将深入讲解如何对本地目录执行扫描、通过严重级别过滤结果,以及灵活切换三种输出格式(TABLE / JSON / SARIF),为后续门禁联动奠定数据基础。
4.1 文件系统扫描的核心原理
Trivy 的文件系统扫描器会遍历目标目录,识别其中的依赖清单文件(如 package-lock.json、go.sum、requirements.txt 等),并与内置的漏洞数据库进行比对。扫描过程不依赖网络(数据库已本地缓存),因此适合离线环境或 CI/CD 流水线中的安全门禁。
关键特性:
- 支持 20+ 种编程语言和框架的依赖分析
- 自动识别操作系统级软件包(如 APK、DEB、RPM)
- 可扫描配置文件中的密钥泄露(配合
--security-checks) - 扫描结果包含 CVE 编号、严重级别、修复版本、PkgPath 等字段
4.2 基本扫描命令与参数
执行文件系统扫描的基本命令格式如下:
trivy fs [flags] PATH
其中 PATH 可以是相对路径或路径。以下为最常用的参数组合:
| 参数 | 说明 | 示例值 |
|---|---|---|
--severity |
按严重级别过滤,多个级别用逗号分隔 | CRITICAL,HIGH |
--format |
输出格式,支持 table、json、sarif |
json |
--output |
将结果写入文件,而非标准输出 | result.json |
--ignore-unfixed |
仅显示有修复版本的漏洞 | (布尔标志) |
--scanners |
指定扫描器类型(vuln、secret、misconfig) | vuln,secret |
实践建议:在 CI/CD 门禁场景中,建议始终使用
--severity CRITICAL,HIGH 过滤,避免低危漏洞干扰流水线决策。同时配合 --ignore-unfixed 可减少因未发布补丁导致的误报。
4.3 指定严重级别过滤
Trivy 将漏洞严重级别分为四档:CRITICAL、HIGH、MEDIUM、LOW。通过 --severity 参数可以精确控制输出范围。
示例:仅扫描当前项目目录,只显示严重和高危漏洞:
trivy fs --severity CRITICAL,HIGH ./my-project
若需要排除低危和中危,同时输出到文件:
trivy fs --severity CRITICAL,HIGH --format json --output critical-high.json ./my-project
注意:严重级别过滤是在扫描完成后对结果进行筛选,而非跳过扫描过程。因此扫描时间不会因过滤而缩短。若需提升性能,可使用
--skip-dirs 或 --skip-files 排除无关目录。
4.4 三种输出格式详解
Trivy 支持三种主要输出格式,每种格式适用于不同的使用场景:
| 格式 | 适用场景 | 特点 | 门禁联动 |
|---|---|---|---|
| TABLE | 本地调试、人工审查 | 终端友好,彩色高亮,可读性强 | 不推荐,难以程序化解析 |
| JSON | CI/CD 流水线、自定义脚本 | 结构化数据,易于 jq 处理 |
推荐,可提取漏洞数量、级别、路径 |
| SARIF | GitHub Advanced Security、IDE 集成 | 标准静态分析交换格式 | 适合上传至 GitHub/SonarQube |
4.4.1 TABLE 格式(默认)
不指定 --format 时,默认输出 TABLE 格式。适合在终端直接查看:
trivy fs --severity CRITICAL ./app
输出示例:
Total: 3 (CRITICAL: 3)
┌──────────┬────────────────┬──────────┬──────────────────┬───────────────┐
│ Library │ Vulnerability │ Severity │ Installed Version│ Fixed Version │
├──────────┼────────────────┼──────────┼──────────────────┼───────────────┤
│ lodash │ CVE-2023-1234 │ CRITICAL │ 4.17.20 │ 4.17.21 │
│ axios │ CVE-2023-5678 │ CRITICAL │ 0.21.1 │ 0.21.2 │
│ express │ CVE-2023-9012 │ CRITICAL │ 4.17.1 │ 4.18.0 │
└──────────┴────────────────┴──────────┴──────────────────┴───────────────┘
4.4.2 JSON 格式
JSON 格式是门禁联动的首选。通过 jq 可以快速提取关键指标:
trivy fs --severity CRITICAL,HIGH --format json ./app > result.json
# 提取高危漏洞数量
cat result.json | jq '.Results[].Vulnerabilities | length'
# 提取所有 CVE ID 和严重级别
cat result.json | jq '.Results[].Vulnerabilities[] | {CVE: .VulnerabilityID, Severity: .Severity}'
4.4.3 SARIF 格式
SARIF(Static Analysis Results Interchange Format)是 OASIS 标准,被 GitHub Code Scanning、Azure DevOps 等平台原生支持:
trivy fs --severity CRITICAL,HIGH --format sarif --output result.sarif ./app
生成的 SARIF 文件可直接上传至 GitHub:
gh api /repos/{owner}/{repo}/code-scanning/sarifs \
-f sarif=@result.sarif \
-f commit_sha="$(git rev-parse HEAD)"
格式选择建议:
- 本地调试 → TABLE
- 门禁脚本 / 自定义规则 → JSON
- 平台集成(GitHub / Azure DevOps) → SARIF
4.5 实战:完整扫描命令组合
以下是一个生产环境可用的扫描命令,集成了严重级别过滤、JSON 输出和忽略未修复漏洞:
trivy fs \
--severity CRITICAL,HIGH \
--format json \
--output trivy-report.json \
--ignore-unfixed \
--scanners vuln,secret \
--skip-dirs node_modules \
--skip-dirs .git \
./my-application
参数说明:
--scanners vuln,secret:同时扫描漏洞和密钥泄露--skip-dirs:跳过node_modules和.git目录,提升扫描速度--ignore-unfixed:只显示已有修复版本的漏洞,减少噪音
性能优化:对于大型项目,建议先使用
--skip-dirs 排除构建产物和第三方依赖目录。首次扫描后,Trivy 会自动缓存数据库,后续扫描速度会显著提升。
4.6 常见问题与避坑
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 扫描结果为空 | 目标目录没有可识别的依赖文件 | 确认目录包含 package.json、go.mod 等清单文件 |
| 严重级别过滤无效 | 参数拼写错误或大小写不正确 | 使用 --severity CRITICAL,HIGH(大写,逗号无空格) |
| JSON 输出过大 | 未使用 --severity 过滤,包含所有级别 |
添加 --severity CRITICAL,HIGH 缩小输出范围 |
| SARIF 文件上传失败 | 缺少 commit_sha 或格式不匹配 |
确保使用 gh api 时传入正确的 commit SHA |