免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

为 Checkov 贡献 YAML 自定义策略:从声明式语法到图扫描测试的完整实战指南

为 Checkov 贡献 YAML 自定义策略:从声明式语法到图扫描测试的完整实战指南 为 Checkov 贡献 YAML 自定义策略从声明式语法到图扫描测试的完整实战指南【免费下载链接】checkovPrevent cloud misconfigurations and find vulnerabilities during build-time in infrastructure as code, container images and open source packages with Checkov by Bridgecrew.项目地址: https://gitcode.com/GitHub_Trending/ch/checkovYAML 自定义策略是 Checkov 中一类以纯 YAML 声明式表达的策略借助策略定义语法与资源关系图graph它能够对资源的属性Attribute、资源间的连接状态Connection进行组合判定并支持 AND/OR/NOT 复杂逻辑适合表达“备份覆盖”“安全组关联”“WAF 挂载”这类跨资源校验。本文以仓库中的 Contribute YAML-based Policies.md 为骨架结合源码与真实示例AWS EBS 备份覆盖策略CKV2_AWS_9完整讲解 YAML 策略的语法、入库贡献流程、测试资源编写与测试方法注册读完即可动手为 Checkov 提交一条可扫描、可回归验证的 YAML 策略。YAML 策略是什么与 Python 策略的定位差异Checkov 内置策略分为两类实现路径Python 策略以 Python 类实现通常针对单一资源的属性做判定适合精确控制扫描逻辑参考 Contribute Python-Based PoliciesYAML 策略Graph Policy存放在checkov/terraform/checks/graph_checks等目录下由通用解析器GraphCheckParser读取基于资源关系图做判定天然支持跨资源连接校验与复合逻辑。从仓库目录结构可以确认除 Terraform 外Ansible、ARM、Bicep、CloudFormation、Dockerfile、GitHub Actions、Kubernetes 等多个框架都拥有各自的 YAML 策略目录与对应的test_yaml_policies.py测试文件例如 tests/terraform/graph/checks/test_yaml_policies.py。这说明 YAML 策略是 Checkov 多框架统一的策略编写范式。在开始贡献前建议先通读 YAML Custom Policies它定义了 YAML 策略的完整语法。下图展示了 YAML 策略的两大组成部分![Checkov YAML 策略结构示意图metadata 元数据与 definition 策略定义](https://raw.gitcode.com/GitHub_Trending/ch/checkov/raw/2637543b885a08d3bd61a3855719a20871fa6dde/docs/3.Custom Policies/policy-definition.png?utm_sourcegitcode_repo_files)YAML 策略文件的基本结构一条 YAML 策略由两大部分组成metadata: id: CKV2_CUSTOM_1 name: Ensure bucket has versioning and owner tag category: BACKUP_AND_RECOVERY guideline: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/aws-policies/aws-general-policies/ckv2_custom_1 severity: HIGH definition: # 单个定义块或 and/or/not 组合metadata 字段说明字段必填说明name是策略名称人类可读的描述id是唯一标识格式为CKV2_provider_number例如CKV2_AWS_9category是策略分类可选值包括GENERAL_SECURITY、LOGGING、ENCRYPTION、NETWORKING、IAM、BACKUP_AND_RECOVERY、CONVENTION、SECRETS、KUBERNETES、APPLICATION_SECURITY、SUPPLY_CHAIN、API_SECURITYguideline否策略说明链接severity否严重级别可选INFO、LOW、MEDIUM、HIGH、CRITICALdefinition 的组成definition顶层必须是一个单一对象不能是列表可以是以下任意一种Attribute Block属性块判定资源的某个配置属性是否等于/不等于/包含某个值或存在/不存在Connection State Block连接块判定资源是否与另一类资源存在连接Resource Type Block资源类型块判定资源类型是否被允许allowlist或禁止blocklist逻辑运算符and、or、not用于组合多个定义块Filter过滤器限定条件适用的资源子集通常与连接块配合使用仅支持在顶层 AND 逻辑中使用。属性操作符全集属性块支持丰富的操作符下表为完整清单来自 YAML Custom Policies 的官方定义按当前仓库文档原样收录YAML 值描述值类型equals精确值匹配String, Int, Boolnot_equals不等于给定值String, Int, Boolregex_match值必须匹配正则String (RegEx)not_regex_match值必须不匹配正则String (RegEx)exists属性或连接出现在资源定义中Nonenot_exists属性或连接不出现在资源中Noneone_exists至少存在一条指定类型的连接Nonecontains属性值包含指定值支持嵌套结构Stringnot_contains属性值不包含指定值支持嵌套结构Stringwithin属性值在给定列表内(List) Stringnot_within属性值不在给定列表内(List) Stringsstarting_with属性值以给定字符串开头Stringnot_starting_with属性值不以给定字符串开头Stringending_with属性值以给定字符串结尾Stringnot_ending_with属性值不以给定字符串结尾Stringgreater_than属性值大于给定值String, Intgreater_than_or_equal属性值大于等于给定值String, Intless_than属性值小于给定值String, Intless_than_or_equal属性值小于等于给定值String, Intsubset属性值是给定列表的子集(List) Stringnot_subset属性值不是给定列表的子集(List) Stringis_empty属性必须没有值Noneis_not_empty属性必须有值Nonelength_equals属性列表长度等于该值String, Intlength_not_equals属性列表长度不等于该值String, Intlength_less_than属性列表长度小于该值String, Intlength_less_than_or_equal属性列表长度小于等于该值String, Intlength_greater_than属性列表长度大于该值String, Intlength_greater_than_or_equal属性列表长度大于等于该值String, Intis_false属性值必须为 falseNoneis_true属性值必须为 trueNoneintersects两个值存在交集(List) Stringsnot_intersects两个值不存在交集(List) Stringsequals_ignore_case忽略大小写相等Stringnot_equals_ignore_case忽略大小写不相等Stringrange_includes值或属性的范围包含给定值/范围String, Intrange_not_includes值或属性的范围不包含给定值/范围String, Intnumber_of_words_equals属性值单词数等于该值String, Intnumber_of_words_not_equals属性值单词数不等于该值String, Intcidr_range_subset_attribute_solver值必须在给定 CIDR 范围内(List) Stringcidr_range_not_subset_attribute_solver值必须在给定 CIDR 范围外(List) String补充说明以上所有操作符都支持 JSONPath 属性表达式只需给操作符加上jsonpath_前缀例如jsonpath_length_equals。这一能力在仓库源码 base_attribute_solver.py 与 checks_parser.py 中均有对应实现从源码结构看前缀处理发生在解析与求解器的分发阶段。列表属性的通配符求值当属性是列表时可用*通配符对列表内所有项求值多个*可嵌套使用只要任意一个列表项匹配该条件即通过。例如cond_type: attribute resource_types: - aws_security_group attribute: ingress.*.cidr_blocks operator: contains value: 0.0.0.0/0对于上述配置只要任意一个ingress块的cidr_blocks包含0.0.0.0/0即返回 true。注意若改用not_contains由于列表中同时存在不包含0.0.0.0/0的项结果依然为 true若要表达“没有任何 CIDR 包含该值”应配合not逻辑使用。连接块与过滤器连接块示例——要求aws_lb或aws_elb必须连接到aws_security_group或aws_default_security_groupdefinition: cond_type: connection resource_types: - aws_elb - aws_lb connected_resource_types: - aws_security_group - aws_default_security_group operator: exists连接块的操作符仅支持exists、not_exists、one_exists三种。过滤器用于把条件限定到某个资源子集常与连接块组合且只在顶层 AND 逻辑中生效。例如“所有 ELB 必须挂载安全组”definition: and: - cond_type: filter attribute: resource_type value: - aws_elb operator: within - cond_type: connection resource_types: - aws_elb connected_resource_types: - aws_security_group - aws_default_security_group operator: exists资源类型块allowlist / blocklistdefinition: cond_type: resource resource_types: - aws_cloudhsm_v2_cluster operator: not_exists使用exists定义白名单、not_exists定义黑名单上例即禁止创建 CloudHSM 集群。AND / OR / NOT 组合规则顶层逻辑运算符是definition下的第一个键绝大多数策略以and或or开头and/or的值必须是列表列表每个元素自身必须是合法定义属性块、连接块、嵌套 AND/OR 等not可包裹任意块用于取反其值可以是单个定义块也可以是恰好包含一个元素的列表。贡献流程三步将策略合入仓库根据 Contribute YAML-based Policies.md为 Checkov 贡献一条 YAML 策略遵循以下三步定义策略按上文语法或参考 YAML Custom Policies 与 Examples编写策略 YAML创建分支在checkov仓库 fork 上创建开发分支并提交改动放置策略文件将policy_name.yaml放入 checkov/terraform/checks/graph_checks 下与策略匹配的 provider 目录aws/、azure/、gcp/、github/等。从当前仓库可以确认checkov/terraform/checks/graph_checks 下已存在alicloud、aws、azure、azuredevops、gcp、github、ibm、ncp、oci等 provider 子目录选择时应与策略id中的 provider 保持一致。完整示例AWS EBS 备份覆盖策略 CKV2_AWS_9策略文件仓库中真实存在的示例位于 checkov/terraform/checks/graph_checks/aws/EBSAddedBackup.yaml内容如下metadata: name: Ensure that EBS are added in the backup plans of AWS Backup id: CKV2_AWS_9 category: BACKUP_AND_RECOVERY definition: and: - cond_type: connection resource_types: - aws_backup_selection connected_resource_types: - aws_ebs_volume operator: exists - cond_type: filter attribute: resource_type value: - aws_ebs_volume operator: within策略语义逐条解读and表示两条子条件必须同时成立第一个子条件是连接块aws_backup_selection必须存在到aws_ebs_volume的连接即 EBS 卷必须被纳入某个备份选择计划第二个子条件是过滤器把判定范围限定在aws_ebs_volume类型资源上避免扫描结果把aws_backup_selection也列为受检对象。这正是 YAML 策略相对 Python 策略的优势用声明式语法表达“A 资源必须被 B 资源覆盖”这类跨资源约束无需编写图遍历代码。为策略编写测试贡献策略必须配套测试测试数据与测试用例的约定如下对应原文档第 37 行起的 “YAML Format Testing” 一节第一步创建测试资源目录在 tests/terraform/graph/checks/resources 下创建与策略同名的目录例如EBSAddedBackup/目录内包含Terraform 文件构造 pass/fail 两类场景的资源定义expected.yaml声明哪些资源应当通过、哪些应当失败。仓库中该目录实际存在tests/terraform/graph/checks/resources/EBSAddedBackup 下包含 main.tf 与 expected.yaml。Terraform 测试资源示例resource aws_ebs_volume ebs_good { availability_zone us-west-2a size 40 tags { Name HelloWorld } } resource aws_ebs_volume ebs_bad { availability_zone us-west-2a size 40 tags { Name HelloWorld } } resource aws_backup_selection backup_good { iam_role_arn arn name tf_example_backup_selection plan_id 123456 resources [ aws_ebs_volume.ebs_good.arn ] } resource aws_backup_selection backup_bad { iam_role_arn arn name tf_example_backup_selection plan_id 123456 resources [ ] }这里的测试设计思路是ebs_good被backup_good通过resources引用构成“已纳入备份计划”的合规场景ebs_bad没有被任何aws_backup_selection引用是不合规场景backup_bad的resources为空列表用于验证策略不会把空备份选择误判为覆盖。expected.yaml 示例pass: - aws_ebs_volume.ebs_good fail: - aws_ebs_volume.ebs_badexpected.yaml支持pass、fail、skip三个键分别列出应当通过、失败与被跳过的资源实体格式为resource_type.name。测试框架会对三者逐一断言。第二步注册测试用例在 tests/terraform/graph/checks/test_yaml_policies.py 中添加测试方法def test_EBSAddedBackup(self): self.go(EBSAddedBackup)仓库中的真实代码位于 tests/terraform/graph/checks/test_yaml_policies.py#L214-L215def test_EBSAddedBackup(self): self.go(EBSAddedBackup)测试机制源码级解读一次 go() 调用发生了什么test_yaml_policies.py的go()方法tests/terraform/graph/checks/test_yaml_policies.py#L595-L621封装了完整的端到端校验其关键步骤为定位资源目录dir_path resources/{dir_name}即上一步创建的测试目录定位策略文件递归遍历checkov/terraform/checks下所有目录找到与check_name同名的yaml文件加载策略与期望值通过load_yaml_data()读取策略 YAML 与expected.yaml执行图扫描调用get_policy_results(dir_path, [policy[metadata][id]])内部创建 checkov/terraform/runner.py 的Runner()并以RunnerFilter(checkscheck_ids)只运行目标策略逐项断言assert_entities()分别比较pass/fail/skip三个列表与报告中的passed_checks、failed_checks、skipped_checks要求实体数量一致且每个实体都能在结果中找到。get_policy_results()的实现tests/terraform/graph/checks/test_yaml_policies.py#L637-L641验证了 YAML 策略最终通过 Terraform Runner 执行而 Runner 依赖图扫描Runner.run()调用 checkov/terraform/graph_manager.py 中的build_multi_graph_from_source_directory()先由TFParser解析 HCL 文件再构建TerraformLocalGraph资源关系图checkov/terraform/graph_manager.py#L25-L59随后策略的 connection 条件才会在图结构上求解。这就是连接类策略能够工作的底层原理。此外策略文件由Registry(parserGraphCheckParser(), checks_dir...)统一加载见测试中的test_registry_loadtests/terraform/graph/checks/test_yaml_policies.py#L589-L593解析器实现在 checkov/common/checks_infra/checks_parser.py。各框架对 YAML 策略的支持范围YAML 策略不仅限于 Terraform。根据 YAML Custom Policies各框架支持情况如下框架resource_types连接支持备注Terraform全部资源支持任意资源间连接CloudFormation全部资源支持任意资源间连接Bicep全部资源支持任意资源间连接Ansibleblock、tasks.[module name]—无参数模块可用特殊属性__self__查询ARM全部资源不支持仅属性校验Dockerfile全部 Docker 指令不支持属性content为指令原始内容value为清洗后内容GitHub Actionspermissions、steps、jobs、onsteps→jobspermissions可为 map 或字符串Kubernetes全部资源不支持仅属性校验各框架在仓库中均有对应测试文件例如 tests/ansible/checks/graph_checks/test_yaml_policies.py、tests/cloudformation/graph/checks/test_yaml_policies.py、tests/github_actions/checks/graph_checks/test_yaml_policies.py贡献非 Terraform 框架策略时可参考对应目录的结构。贡献检查清单完成贡献前逐项确认以下内容策略id遵循CKV2_provider_number格式且不与既有策略冲突category使用文档列出的合法枚举值策略文件位于checkov/terraform/checks/graph_checks/provider/下或对应框架的 graph_checks 目录测试资源目录与策略同名位于 tests/terraform/graph/checks/resources或对应框架的 resources 目录测试资源同时覆盖 pass 与 fail 场景可包含 skip 场景expected.yaml中实体 ID 与 Terraform 资源type.name完全一致在对应 test_yaml_policies.py 中注册了测试方法并本地跑通。# 本地运行单个策略的测试 python -m pytest tests/terraform/graph/checks/test_yaml_policies.py::TestYamlPolicies::test_EBSAddedBackup总结YAML 策略为 Checkov 提供了声明式、可组合、跨资源的策略编写能力metadata负责身份与分类definition通过属性块、连接块、资源类型块与 AND/OR/NOT 逻辑描述合规约束贡献一条策略只需三件事——写好 YAML、按 provider 放入 checkov/terraform/checks/graph_checks、配好测试资源并在 test_yaml_policies.py 中注册用例。从go()方法的实现可以看到测试链路完整覆盖了策略加载、图构建与结果断言确保每一条合入的策略都能被持续回归验证。【免费下载链接】checkovPrevent cloud misconfigurations and find vulnerabilities during build-time in infrastructure as code, container images and open source packages with Checkov by Bridgecrew.项目地址: https://gitcode.com/GitHub_Trending/ch/checkov创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表