Trivy 根命令详解:统一安全扫描器 CLI 的全局参数、工作模式与子命令体系
【免费下载链接】trivyFind vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more项目地址: https://gitcode.com/GitHub_Trending/tr/trivy
Trivy 的二进制入口是一个由 Cobra 构建的单根命令(root command)CLI,其官方参考页位于 docs/guide/references/configuration/cli/trivy.md。本文以该参考页为骨架,结合 cmd/trivy/main.go、pkg/commands/app.go 与 pkg/flag/global_flags.go 等源码,系统讲解trivy命令的统一用法、11 个全局选项(Global Flags)的真实行为、环境变量与配置文件优先级,以及全部子命令的组织方式。读完本文,你将能理解trivy [global flags] command [flags] target这条语法每一部分的含义,掌握调试、超时、TLS 证书、缓存目录等全局参数的推荐用法,并清楚在不同扫描目标(镜像、文件系统、仓库、Kubernetes、虚拟机镜像等)之间如何正确选择子命令。
命令总览:一个入口,多种安全扫描能力
trivy根命令被定义为"Unified security scanner"(统一安全扫描器),其完整描述为:
Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues and hard-coded secrets
也就是说,它把四类能力收敛到同一个二进制里:容器镜像 / 文件系统 / Git 仓库的漏洞扫描、配置(IaC)错误扫描、硬编码密钥(secret)扫描,此外还覆盖 SBOM、VEX、Kubernetes、虚拟机镜像等领域。这与项目定位"Find vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more"一一对应。
从源码看,这个"单入口"是由NewApp()组装出来的:它创建全局 flag 组(flag.NewGlobalFlagGroup()),再通过rootCmd.AddCommand(...)挂载全部子命令(见 pkg/commands/app.go)。真正的最小启动链是:
- cmd/trivy/main.go 里的
run()先处理TRIVY_RUN_AS_PLUGIN环境变量(存在时 Trivy 会以指定插件身份运行),随后注册信号处理、执行commands.Run(ctx); commands.Run(pkg/commands/run.go)创建NewApp()并ExecuteContext,集中处理两类典型错误——超时(提示调大--timeout)与 bbolt 缓存/数据库锁超时(提示查阅 troubleshooting 文档)。
统一语法
trivy [global flags] command [flags] target根命令不接受裸参数(Args: cobra.NoArgs)。若不带任何子命令运行,或仅想查看用法,直接执行trivy(或trivy --help)即可,此时根命令的RunE会输出帮助信息;如果携带-v/--version,则输出版本信息(见 pkg/commands/app.go)。
快速上手:四种经典用法
根命令参考页给出的Examples与源码中NewRootCommand的Example字段完全一致(pkg/commands/app.go),代表了四条最典型的启动路径:
# 扫描容器镜像 $ trivy image python:3.4-alpine # 从 tar 归档文件扫描容器镜像(无需本地 Docker 守护进程) $ trivy image --input ruby-3.1.tar # 扫描本地文件系统(等价别名:trivy fs) $ trivy fs . # 以 server 模式运行(对外提供扫描服务) $ trivy server在此基础上,trivy image 等子命令的参考页还展示了更贴近实战的组合,例如按严重级别过滤、忽略未修复漏洞、以 JSON 或 CycloneDX 格式输出报告等,均可与上述基本用法叠加使用。
全局选项(Global Flags)逐项解析
trivy根命令暴露的 11 个选项全部声明在 pkg/flag/global_flags.go,并统一由GlobalFlagGroup管理。下表为完整选项清单:
| 选项 | 简写 | 说明 | 默认值 |
|---|---|---|---|
--cacert string | PEM 编码的 CA 证书文件路径 | 无(使用系统根证书) | |
--cache-dir string | 缓存目录 | 系统用户缓存目录下的trivy子目录 | |
--config string | -c | 配置文件路径 | trivy.yaml |
--debug | -d | 调试模式 | false |
--format string | -f | 版本输出格式 | 仅支持json |
--generate-default-config | 将默认配置写入trivy-default.yaml | false | |
--help | -h | 帮助信息 | |
--insecure | 允许不安全的服务器连接 | false | |
--quiet | -q | 抑制进度条与日志输出 | false |
--timeout duration | 超时时间 | 5m0s | |
--version | -v | 显示版本 | false |
这些 flag 都是persistent(持久)flag,即在 pkg/commands/app.go 中被添加到根命令后,会被所有子命令继承,因此无论执行trivy image ...、trivy fs ...还是trivy server,都可以在其后使用这些全局参数。以下结合源码逐一说明关键行为。
日志与输出控制:-d/--debug、-q/--quiet
-d/--debug打开调试模式,输出更详细的内部日志,便于排查数据库下载、分析器执行等问题;-q/--quiet抑制进度条和日志输出,适合在 CI 流水线中追求干净输出时使用。
两者的真实落点是把值传给日志初始化:根命令的PersistentPreRunE中执行log.InitLogger(opts.Debug, opts.Quiet)(pkg/commands/app.go),因此它们必须在每次命令的 pre-run 阶段生效。从 flag 定义看,这两个选项都被标记为TelemetrySafe: true(即可以被匿名遥测采集而不会泄露敏感信息)。
缓存目录:--cache-dir
--cache-dir用于指定扫描缓存(镜像层、数据库等)的存放位置。源码中的默认值并非固定路径,而是由 pkg/cache/dir.go 的DefaultDir()计算得到:优先取os.UserCacheDir(),取不到则退回os.TempDir(),再拼接trivy子目录。因此不同操作系统上的实际路径各不相同(例如 Linux 上通常是~/.cache/trivy),参考页中展示的(default "/path/to/cache")只是文档生成时的占位符。在多用户、CI、容器内或共享存储场景中,建议显式指定该参数以保证行为可预期。删除缓存的子命令trivy clean也依赖该目录,详见 trivy clean。
配置文件:-c/--config
--config指定配置文件路径,默认读取当前工作目录下的trivy.yaml。配置文件加载逻辑见 pkg/commands/app.go 的initConfig():它使用 Viper 以 YAML 解析该文件;若默认文件不存在则静默忽略(使用内置默认值),只有显式指定-c而文件缺失时才报错;加载成功后日志会输出一行Loaded并带出文件路径。更完整的配置项说明可阅读仓库中的 配置参考。
一键导出默认配置:--generate-default-config
当需要为团队定制基线配置时,可执行:
$ trivy --generate-default-config它会把当前版本完整的默认配置写入工作目录下的trivy-default.yaml,之后你可以基于该文件编辑,再通过-c trivy-default.yaml或重命名为trivy.yaml投入使用。从 pkg/commands/app.go 的validateArgs()可以看到,该参数与--download-db-only等一样属于"不需要 target 参数"的特殊模式——设置后即跳过常规扫描目标校验。
TLS 与私有源:--insecure、--cacert
这两个选项用于控制 Trivy 与远端服务(如私有 OCI 镜像仓库、Trivy Server、数据库下载源等)建立 TLS 连接时的信任行为:
--insecure允许不安全的服务器连接(跳过证书校验)。源码中还保留了历史环境变量TRIVY_NON_SSL做向后兼容:只要该变量非空,效果等同于--insecure(见 pkg/flag/global_flags.go);--cacert指向一个 PEM 编码的 CA 证书文件。加载逻辑loadRootCAs(pkg/flag/global_flags.go)会先取系统根证书池,再把文件中所有证书AppendCertsFromPEM追加进去,用于信任自建 CA 签发的私有仓库证书;文件缺失或追加失败会直接报错。
如果团队自建了 Trivy Server 作为扫描后端,客户端侧也需要通过这类参数建立信任关系,可参考 trivy server 与远程/客户端模式相关文档。
超时:--timeout
--timeout控制单次命令的总超时,默认5m0s(源码中为time.Second * 300,见 pkg/flag/global_flags.go)。扫描大镜像、大仓库或弱网环境时需要调大。值得注意的两点实现细节:
- 若整体执行超时触发
context.DeadlineExceeded,运行层会给出"Provide a higher timeout value"的提示(pkg/commands/run.go); - 特定子命令会改写默认策略,例如
trivy vm在扫描虚拟机镜像时会强制把小于 30 分钟的超时抬升到 30 分钟(见 pkg/commands/app.go),这类命令级差异需以对应子命令参考页为准。
版本输出:-v/--version与-f/--format json
-v/--version打印版本信息。这里有一个容易混淆的点:根命令上的-f/--format并不是报告输出格式,而只用于指定版本输出的格式,当前仅支持json:
$ trivy --version # 纯文本版本信息 $ trivy --format json --version # JSON 结构化的版本信息showVersion()(pkg/commands/app.go)在json分支用 JSON 编码输出version.NewVersionInfo(...)。独立的trivy version子命令也提供相同的--format json支持,见 trivy version。如果你的目标是把报告输出为 JSON/SARIF/CycloneDX 等格式,应使用扫描类子命令自身的--format选项(如trivy image --format json ...),两者作用对象完全不同。
全局参数的三层配置来源与优先级
trivy的全局参数(以及各子命令参数)都可以通过命令行 flag → 环境变量 → 配置文件(trivy.yaml)三个来源设置。实现机制位于 pkg/flag/options.go 的Bind()/BindEnv():
- 每个 flag 先通过
viper.BindPFlag(f.ConfigName, flag)与命令行绑定; - 随后
BindEnv()手工构造环境变量名(不使用AutomaticEnv):规则是把 flag 名中的-换成_并整体大写、加上TRIVY_前缀,例如--cache-dir对应TRIVY_CACHE_DIR、--quiet对应TRIVY_QUIET、--debug对应TRIVY_DEBUG、--config对应TRIVY_CONFIG; - 配置文件则在根命令
PersistentPreRunE阶段通过 initConfig 读取。
因此三种写法的效果等价,例如把超时改为 10 分钟,可以:
$ trivy image --timeout 10m alpine:3.15 # flag $ TRIVY_TIMEOUT=10m trivy image alpine:3.15 # 环境变量 # 或在 trivy.yaml 中设置 timeout: 10m,然后运行 $ trivy -c trivy.yaml image alpine:3.15 # 配置文件在 CI/CD(如 GitLab、GitHub Actions)中,使用TRIVY_*环境变量传递认证信息与运行参数是常见且推荐的做法,可以避免把参数写死在命令行历史中。
子命令体系:按职责分组的 SEE ALSO 索引
根命令参考页的 "SEE ALSO" 列出了全部子命令的参考文档(均位于 docs/guide/references/configuration/cli/ 目录)。从源码NewApp()与分组定义看(pkg/commands/app.go),这些命令被组织成Scanning(扫描)、Management(管理)、Utility(工具)、Plugin四类,其中插件类只在检测到已安装插件时动态出现(loadPluginCommands())。
扫描类命令(Scanning Commands):负责针对不同 target 执行扫描,内部通过artifact.Run(ctx, options, TargetXXX)走同一套工件扫描管线。
| 子命令 | 参考页 | 扫描目标 |
|---|---|---|
trivy image | trivy_image.md | 容器镜像(含 tar 归档输入) |
trivy filesystem | trivy_filesystem.md | 本地文件系统 |
trivy rootfs | trivy_rootfs.md | 已解包的 rootfs(如容器内扫描) |
trivy repository | trivy_repository.md | Git 仓库(本地或远程 URL) |
trivy config | trivy_config.md | 配置文件 / IaC 的 misconfiguration |
trivy sbom | trivy_sbom.md | SBOM 中的漏洞与许可证 |
trivy kubernetes(EXPERIMENTAL) | trivy_kubernetes.md | Kubernetes 集群 |
trivy vm(EXPERIMENTAL) | trivy_vm.md | 虚拟机镜像 |
工具/服务类(Utility):包括以长驻服务方式提供扫描能力的trivy server(见 trivy_server.md,支持trivy server --listen 0.0.0.0:10000)、将 Trivy JSON 报告转换为其他格式的trivy convert、清理缓存的trivy clean以及打印版本的trivy version。
管理类(Management):负责扩展与凭据管理,包括trivy plugin(plugin 系命令,install/uninstall/list/info/run/update/search/upgrade)、trivy module(install/uninstall,用于安装自定义扫描模块)、trivy registry(registry login/logout,管理私有镜像仓库认证,密码建议通过TRIVY_PASSWORD或--password-stdin传入,避免出现在命令行中)以及处于 EXPERIMENTAL 状态的trivy vex(VEX 工具链,含vex repo init/list/download)。
参考页为每个子命令打上了[EXPERIMENTAL]标记的是kubernetes、vm与vex三个命令,使用前应关注其稳定性声明;其余命令则为正式能力。查看任意子命令的完整参数,随时可执行trivy <command> --help。
核心机制:根命令的启动时序
综合源码可以梳理出trivy <command>每次执行的内部时序,这对排查"为什么参数没生效"很有帮助:
- 参数绑定:根命令的
PersistentPreRunE中先globalFlags.Bind(cmd)把全局 flag 绑到 Viper,再读取-c指定的配置文件(initConfig),随后flags.ToOptions()汇总出GlobalOptions并初始化日志(pkg/commands/app.go); - 子命令级 pre-run:各子命令(如
NewImageCommand)在自己的PreRunE中绑定自身专属 flag 组并校验参数——注释明确说明必须放在PreRunE而非Args,因为前者执行时 Viper 尚未配置完成(见 pkg/commands/app.go); - 参数校验:
validateArgs()要求扫描类命令必须提供且只能提供一个 target(或--input),否则直接打印帮助并报 "Require at least 1 argument"(pkg/commands/app.go); - 执行:子命令
RunE把选项转成Options后交给对应实现(镜像扫描统一走artifact.Run管线)。
这套 "flag 声明于pkg/flag、绑定于 pre-run、执行于RunE" 的架构,使得同一组扫描参数能在 image/fs/rootfs/repo/vm 等不同 target 间保持一致性,也解释了为什么全局选项必须为 persistent flag。
小结与延伸阅读
trivy根命令是整套 Trivy 工具链的统一入口:语法trivy [global flags] command [flags] target中的全局选项负责日志、超时、缓存、TLS、配置文件等横切能力,扫描与管理能力则完全由子命令承载。若需进一步深入,建议按以下路径阅读仓库文档与源码:
- 各子命令完整参考页:docs/guide/references/configuration/cli/(本文引用页面的同目录文件);
- 配置文件全量字段说明:docs/guide/references/configuration/config-file.md;
- 全局 flag 的定义与加载:pkg/flag/global_flags.go、pkg/flag/options.go;
- 命令组装与子命令实现:pkg/commands/app.go、cmd/trivy/main.go;
- 缓存目录默认值:pkg/cache/dir.go;
- 程序入口的信号处理与集中错误处理:pkg/commands/run.go、pkg/commands/signal.go。
一份可复制的自检用命令序列如下,用于验证全局参数的三个配置来源是否按预期生效:
# 查看根命令帮助与全部子命令 $ trivy --help # 输出 JSON 格式版本信息 $ trivy --format json --version # 生成默认配置文件后定制化使用 $ trivy --generate-default-config $ trivy -c trivy-default.yaml image alpine:3.15 --timeout 10m --quiet【免费下载链接】trivyFind vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more项目地址: https://gitcode.com/GitHub_Trending/tr/trivy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考