Trivy 误配置扫描配置指南:自定义检查、命名空间与内联忽略规则详解
2026/9/10 3:54:12 网站建设 项目流程

Trivy 误配置扫描配置指南:自定义检查、命名空间与内联忽略规则详解

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

Trivy 的 misconfiguration(误配置)扫描器支持高度可定制的运行方式:你可以只启用特定的配置扫描器子集、加载自定义 Rego 检查与数据、控制 Rego 编译错误的容忍度,并通过行内注释精确忽略某条资源的误配置发现。本文基于 Trivy 官方文档与源码实现,系统讲解这些配置项的用法、参数含义与底层原理,帮助你针对 Terraform、CloudFormation、Helm、Dockerfile 以及任意 JSON/YAML 配置文件构建贴合自身业务的扫描策略。

启用误配置扫描器的子集

默认情况下,Trivy 会启用所有内置的配置扫描器。如果你只想关注特定类型的配置文件,可以通过--misconfig-scanners选项指定一个逗号分隔的扫描器类型列表:

trivy config --misconfig-scanners=terraform,dockerfile .

上面的命令只会扫描与 Terraform 和 Dockerfile 相关的误配置,其他类型的配置文件将被跳过。

从源码看,该选项在 pkg/flag/misconf_flags.go 中定义为MisconfigScannersFlag,其配置项名称为misconfiguration.scanners,也就是说你同样可以在 Trivy 配置文件(trivy.yaml)中以如下形式固化默认值:

misconfiguration: scanners: - terraform - dockerfile

该 flag 的默认值是analyzer.TypeConfigFiles中除去 YAML 与 JSON 之外的全部配置类型,这正与下文“JSON/YAML 默认不扫描”的行为相呼应。当你显式传入--misconfig-scanners时,会覆盖这一默认集合。

加载自定义检查(Checks)

内置检查(内置在builtin.*命名空间下)之外,你可以通过--config-check加载自己的 Rego 检查文件或目录。该选项可以重复指定,以加载多个文件或目录:

trivy config --config-check custom-policy/policy --config-check combine/policy --config-check policy.rego --namespaces user myapp

此外,你还可以把检查打包成 OCI 镜像托管在容器镜像仓库中,通过--checks-bundle-repository直接加载整个检查包:

trivy config --checks-bundle-repository myregistry.local/mychecks --namespaces user myapp

在 pkg/flag/misconf_flags.go 中,ChecksBundleRepositoryFlag的默认值是policy.BundleRepositorypolicy.BundleVersion组合出的官方仓库地址;你只需要把它替换成自己的私有仓库即可加载自定义的检查集合。

传递自定义数据(Custom Data)

部分检查在做判断时需要额外的参考数据(例如“允许创建的端口列表”“可信容器镜像仓库列表”)。你可以通过--config-data(原文档中的--data)传入包含 JSON(*.json)与 YAML(*.yaml)文件的目录,Trivy 会递归搜索这些目录。该选项可以重复指定多个目录:

cd examples/misconf/custom-data trivy config --config-check ./my-check --data ./data --namespaces user ./configs

例如,把允许的服务端口维护在独立的 YAML 文件中,然后在 Rego 检查里通过import data.services引入(详见 Custom Data):

services: ports: - "20" - "20/tcp" - "23"
import data.services ports := services.ports

自定义数据也可以用来覆盖内置检查的默认值,例如ksv0125.trusted_registries(可信容器镜像仓库列表)与ds031.included_envs(允许的环境变量列表),只需按相同的键路径在数据文件中给出即可。

指定检查命名空间(Namespaces)

默认情况下 Trivy 只评估定义在builtin.*包中的检查。如果你的自定义检查写在其他包(例如package user.mycheck)里,就必须通过--namespaces告知 Trivy 需要评估的包前缀。该选项可重复指定多个包前缀:

trivy config --config-check ./my-check --namespaces main --namespaces user ./configs

对应到源码 pkg/iac/rego/scanner.go 中,Scanner维护了一个ruleNamespaces集合,初始时克隆builtinNamespaces,随后在ScanInput遍历策略时通过getModuleNamespace(module)取出每个 Rego 模块的包名,仅当顶层包名存在于ruleNamespaces中才会执行该模块。这就是为什么没有显式指定--namespaces时自定义包下的检查不会生效。

限制 Rego 编译错误数量

Trivy 默认会容忍一定数量的 Rego 编译错误,超过阈值即终止编译并结束扫描。你可以通过--rego-error-limit调整该上限:

trivy config --rego-error-limit 20 ./configs
  • 当编译错误数量超过该上限时,Trivy 会终止扫描;
  • 设为--rego-error-limit 0表示严格模式,不允许任何编译错误。

该默认值定义在源码 pkg/iac/rego/scanner.go 中:

// DefaultAllowedRegoErrors defines the default number of Rego compile errors // that the scanner will tolerate. This value is set explicitly instead of // relying on OPA's ast.CompileErrorLimitDefault to avoid depending on upstream changes. const DefaultAllowedRegoErrors = 10

可见默认容忍上限为 10 个编译错误,且刻意没有依赖 OPA 上游的默认常量,以避免上游变更影响 Trivy 的行为。Scanner结构体中的maxAllowedErrors字段即承载这一限制。

私有 Terraform 注册中心

Trivy 可以从私有 Terraform registry 下载模块代码。凭证只能通过TF_TOKEN_前缀的环境变量传递,目前不支持.terraformrcterraform.rc文件。

命名规则(引自 Terraform 官方文档)如下:

  • 环境变量名 =TF_TOKEN_+ 域名,域名中的句点编码为下划线。例如变量TF_TOKEN_app_terraform_io的值会作为app.terraform.io主机的 Bearer 授权令牌;
  • 含非 ASCII 字符的域名必须转换为带 ACE 前缀的 punycode。例如例えば.com的令牌必须设置在TF_TOKEN_xn--r8j3dr99h_com中;
  • 主机名中的连字符通常不是合法的变量名字符,可编码为双下划线。例如域名café.fr可写作TF_TOKEN_xn--caf-dma_frTF_TOKEN_xn____caf__dma_fr

如果多个变量解析到同一个主机名,Trivy 会优先选择“连字符未编码为双下划线”的那个变量名。

扫描任意 JSON 与 YAML 配置

Trivy 内置检查并不覆盖任意 JSON/YAML 配置,因此默认禁用对这两类文件的扫描。需要时,把jsonyaml加入--misconfig-scanners

trivy config --misconfig-scanners=json,yaml --config-check ./serverless.rego --check-namespaces user ./iac

启用后,Trivy 会把每个文件“原样”作为输入传给 Rego 检查。下面是一个完整的可运行示例:扫描一个 Serverless Framework 的 YAML 配置,用自定义检查约束服务名必须以aws-开头。

iac/serverless.yaml

service: serverless-rest-api-with-pynamodb frameworkVersion: ">=2.24.0" plugins: - serverless-python-requirements

serverless.rego

# METADATA # title: Serverless Framework service name not starting with "aws-" # description: Ensure that Serverless Framework service names start with "aws-" # schemas: # - input: schema["serverless-schema"] # custom: # avd_id: AVD-SF-0001 # severity: LOW package user.serverless001 deny[res] { not startswith(input.service, "aws-") res := result.new( sprintf("Service name %q is not allowed", [input.service]), input.service ) }

执行结果:

$ trivy config --misconfig-scanners=json,yaml --config-check ./serverless.rego --check-namespaces user ./iac serverless.yaml (yaml) Tests: 4 (SUCCESSES: 3, FAILURES: 1) Failures: 1 (UNKNOWN: 0, LOW: 1, MEDIUM: 0, HIGH: 0, CRITICAL: 0) LOW: Service name "serverless-rest-api-with-pynamodb" is not allowed ═════════════════════════════════════════════════════════════════════════════════════════════════════════ Ensure that Serverless Framework service names start with "aws-"

通过 Schema 做类型检查

在上述示例中,检查的元数据声明了输入 schema:input: schema["serverless-schema"],这使 Trivy 能对传入的 IaC 文件做类型检查,从而在 Rego 求值前发现结构不符的问题。除了在检查元数据中声明 schema,你还可以用--config-file-schemas显式传入 schema 文件:

trivy config --misconfig-scanners=json,yaml --config-check ./serverless.rego --check-namespaces user --config-file-schemas ./serverless-schema.json ./iac

几点行为说明:

  • 一旦指定--config-file-schemas,Trivy 会确保每个输入 IaC 文件都通过 schema 类型检查;如果输入文件不匹配任何传入的 schema,它将被忽略;
  • 如果 schema 定义在检查的元数据中,且位于--config-check指定的目录内,则会被自动加载(详见 Input Schema),并仅用于 Rego 类型检查;
  • 当你暂时不想做类型检查时,不必传输入 schema——这对于“为 Trivy 尚未支持的新服务快速编写 Rego 检查并直接喂入 IaC 输入”的场景非常有用;
  • --config-file-schemas也支持逗号分隔的文件路径列表或一个目录作为输入;指定多个 schema 时,每个 schema 都会与所有输入文件逐一比对。

从 pkg/flag/misconf_flags.go 可以看到,该 flag 的配置项名称为misconfiguration.config-file-schemas,其用途描述正是“指定 JSON 配置 schema 路径,用于判断文件是否匹配某种配置,并把 schema 传给 Rego 检查做类型检查”。

通过内联注释忽略误配置资源

Trivy 支持对Terraform、CloudFormation、Helm 与 Dockerfile这四种配置文件,用紧邻资源定义的内联注释忽略误配置发现。这与.trivyignore(对整个扫描目录生效)不同,内联忽略只作用于单条资源定义。

忽略注释的格式为trivy:ignore:<rule>,紧跟在格式对应的行注释标记之后。忽略规则中必须包含检查元数据中存在的标识符之一:ID、long id 或别名,且均不区分大小写,例如AWS-0089aws-0089或任意大小写组合都可以。

例如忽略 Terraform HCL 中的AVD-GCP-0051

#trivy:ignore:AVD-GCP-0051 resource "google_container_cluster" "example" { name = var.cluster_name location = var.region }

同一行可以写多条忽略规则:

#trivy:ignore:AVD-GCP-0051 trivy:ignore:AVD-GCP-0053 resource "google_container_cluster" "example" { name = var.cluster_name location = var.region }

也可以使用 long id,其格式为<provider>-<service>-<short-code>。例如对下面的检查元数据:

# custom: # id: AVD-AWS-0089 # avd_id: AVD-AWS-0089 # provider: aws # service: s3 # severity: LOW # short_code: enable-logging

其 long id 为aws-s3-enable-logging

CloudFormation 示例(#trivy:ignore:*表示忽略该资源上的所有检查):

AWSTemplateFormatVersion: "2010-09-09" Resources: #trivy:ignore:* S3Bucket: Type: 'AWS::S3::Bucket' Properties: BucketName: test-bucket

Helm 示例——忽略规则必须放在 YAML 对象之前,因为只有对象位置才携带忽略所需的定位数据:

serviceAccountName: "testchart.serviceAccountName" containers: # trivy:ignore:KSV018 - name: "testchart" securityContext: runAsUser: 1000 runAsGroup: 3000 image: "your-repository/your-image:your-tag" imagePullPolicy: "Always"

注意:基于“缺失资源”的检查无法内联忽略

内联忽略只对与已有资源关联的检查生效。对于那些由“资源缺失”触发的检查(例如 Dockerfile 缺少USER指令触发的AVD-DS-0002),无法通过内联注释忽略,请改用 .trivyignore.yaml 文件处理。

忽略规则的过期时间

可以为忽略规则指定yyyy-mm-dd格式的过期时间,确保被忽略的问题不会被遗忘,值得在未来重新审视:

#trivy:ignore:aws-s3-enable-logging:exp:2024-03-10 resource "aws_s3_bucket" "example" { bucket = "test" }

aws-s3-enable-logging这条检查会在2024-03-10之前一直被忽略,过期后重新生效。

对应到源码 pkg/iac/ignore/parse.go,expiryDateParser使用time.Parse("2006-01-02", str)解析该字段;一旦过期时间早于当前时间,规则即失效。在 pkg/iac/ignore/rule.go 中,exp段通过time.Now().Before(expiry)判断是否仍在有效期内。

按属性值忽略资源

对于使用for-each元参数批量创建的资源,你可以按属性值精确忽略某一条。注意:属性值不要加引号(即使该属性实际是字符串):

locals { ports = ["3306", "5432"] } #trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=3306] resource "aws_security_group_rule" "example" { for_each = toset(local.ports) type = "ingress" from_port = each.key to_port = each.key protocol = "TCP" cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.example.id source_security_group_id = aws_security_group.example.id }

aws-ec2-no-public-ingress-sgr这条检查只会对端口3306的资源实例被忽略(示例中5432仍会被报告)。若要忽略不同属性值的多个资源,可以写多条规则:

#trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=3306] #trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=5432]

也可以在同一条规则中按多个属性组合忽略:

locals { rules = { first = { port = 1000 type = "ingress" }, second = { port = 1000 type = "egress" } } } #trivy:ignore:aws-ec2-no-public-ingress-sgr[from_port=1000,type=egress] resource "aws_security_group_rule" "example" { for_each = { for k, v in local.rules : k => v } type = each.value.type from_port = each.value.port to_port = each.value.port protocol = "TCP" cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.example.id source_security_group_id = aws_security_group.example.id }

上面的规则只会忽略type=egressfrom_port=1000的那条资源。检查同样支持嵌套属性

#trivy:ignore:*[logging_config.prefix=myprefix] resource "aws_cloudfront_distribution" "example" { logging_config { include_cookies = false bucket = "mylogs.s3.amazonaws.com" prefix = "myprefix" } }

忽略模块(Module)内部的问题

第三方模块源码可能无法修改,此时无法在模块内部加忽略注释。你可以在module块上方添加忽略规则:

#trivy:ignore:aws-s3-enable-logging module "s3_bucket" { source = "terraform-aws-modules/s3-bucket/aws" bucket = "my-s3-bucket" }

也可以按属性值精确忽略模块实例化的某个 bucket:

locals { bucket = ["test1", "test2"] } #trivy:ignore:*[bucket=test1] module "s3_bucket" { for_each = toset(local.bucket) source = "terraform-aws-modules/s3-bucket/aws" bucket = each.value }

通配符支持

忽略规则中的idws(workspace)段支持通配符*

# trivy:ignore:aws-s3-*:ws:dev-*

该规则会忽略所有以aws-s3-开头的检查,且仅对匹配dev-*模式的工作区生效。

从实现层面看,pkg/iac/ignore/rule.go 中的MatchPattern会把通配符模式编译为大小写不敏感的正则表达式(*对应.*)再做匹配;pkg/iac/ignore/parse.go 则负责把trivy:ignore:...行解析为idexpws等分段,其中checkIDParser会截断[之后的部分以分离属性条件。相关的解析与匹配逻辑均有对应测试覆盖,参见 pkg/iac/ignore/rule_test.go 与 pkg/iac/scanners/terraform/ignore_test.go。

小结

Trivy 的 misconfiguration 配置体系围绕“扫描什么、用什么检查、如何放行”三条主线展开:--misconfig-scanners控制扫描器子集与是否启用 JSON/YAML;--config-check--checks-bundle-repository--config-data--namespaces共同构成自定义检查生态的加载与运行机制;--rego-error-limit--config-file-schemas则分别保障了 Rego 编译的稳定性与输入的规范性。内联注释忽略规则为 Terraform、CloudFormation、Helm 与 Dockerfile 提供了粒度精确到单条资源的豁免能力,配合过期时间、属性匹配、模块级忽略与通配符,足以覆盖绝大多数误报治理场景。

相关参考资料:

  • misconfiguration 配置文档
  • 自定义数据 Custom Data
  • 输入 Schema 文档
  • 过滤与 .trivyignore.yaml
  • flag 定义源码
  • Rego 扫描器源码
  • 忽略规则解析源码
  • 忽略规则匹配源码

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

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询