资讯详情

资讯详情

使用 Checkov 扫描 Terraform 第三方模块与私有模块

使用 Checkov 扫描 Terraform 第三方模块与私有模块【免费下载链接】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/checkovCheckov 在扫描 Terraform 配置时默认只覆盖当前目录下直接定义的资源而生产环境大量使用第三方模块如官方 AWS EKS 模块将资源抽象在模块内部导致常规扫描出现覆盖盲区。本文以 docs/7.Scan Examples/Terraform.md 为核心结合 checkov/terraform/module_loading 目录下的加载器源码完整讲解如何通过--download-external-modules让 Checkov 下载并扫描外部模块、如何调整下载路径、如何使用 Terraform 已下载的模块实验特性以及如何为私有仓库、私有 Terraform Registry 和自建 VCS 配置认证凭据最终实现对第三方与私有 Terraform 模块的全面策略覆盖。一、问题背景为什么第三方模块会逃过常规扫描第三方 Terraform 模块的价值在于把由多个对象组成的复杂服务封装成少量配置。以官方 AWS EKS 模块为例原本需要大量资源配置的集群在配置文件中只需几行module声明module eks { source terraform-aws-modules/eks/aws cluster_name my-cluster cluster_version 1.24 subnets [subnet-abcde012, subnet-bcde012a, subnet-fghi345a] vpc_id vpc-1234556abcdef worker_groups [ { instance_type m4.large asg_max_size 5 } ] }这种封装带来的副作用是模块内部的 Terraform 配置被“抽象”掉了常规的checkov -d .只能看到module块本身无法触及模块内部定义的资源如 EKS 节点组的 IAM 角色、安全组、自动扩缩组等从而漏掉这些资源上的安全策略检查。从源码结构看这一覆盖盲区的根因在于 Checkov 的模块加载机制ModuleLoaderRegistry见 checkov/terraform/module_loading/registry.py在load()时会对每个 loader 判断if not self.download_external_modules and loader.is_external: continue即默认download_external_modulesFalse时会直接跳过所有外部加载器loader.is_external True见 checkov/terraform/module_loading/loader.py。因此只有显式开启外部模块下载模块内部的资源才会被拉取并纳入扫描图。二、启用外部模块下载--download-external-modules要让 Checkov 下载配置文件中引用的外部模块在扫描时增加--download-external-modules truecheckov -d . --download-external-modules true该参数对应的 CLI 定义位于 checkov/common/util/ext_argument_parser.py帮助文本为“download external terraform modules from public git repositories and terraform registry”即支持从公开 Git 仓库与 Terraform Registry 下载模块默认值为None同时支持通过环境变量DOWNLOAD_EXTERNAL_MODULES传入。执行后Checkov 会将配置文件中引用的外部模块下载到当前目录下的.external_modules文件夹默认目录常量DEFAULT_EXTERNAL_MODULES_DIR .external_modules定义于 checkov/common/util/consts.py随后对这些模块内部的资源执行与本地资源相同的策略检查。下载路径的确定方式从 registry.py 的源码可以看到下载目标路径由root_dir external_modules_folder_name source拼接而成在 Windows 上由于路径命名字符限制会改用模块source的 MD5 哈希值作为目录名在 Linux/macOS 上直接使用模块 source如terraform-aws-modules/eks/aws作为子目录名。而 Registry 类模块例如terraform-aws-modules/eks/aws的下载路径还包含 host 名与版本号external_modules_folder_name / tf_host_name / module_source / best_version见 loaders/registry_loader.py从而保证不同来源、不同版本的模块可以并存。三、自定义外部模块下载路径如果默认的.external_modules目录不符合项目约定可通过--external-modules-download-path指定其他路径checkov -d . --download-external-modules true --external-modules-download-path example/path该参数定义于 checkov/common/util/ext_argument_parser.py默认值即DEFAULT_EXTERNAL_MODULES_DIR并支持环境变量EXTERNAL_MODULES_DIR覆盖。对应的运行时读取逻辑在 checkov/common/util/env_vars_config.pyEXTERNAL_MODULES_DIR os.getenv(EXTERNAL_MODULES_DIR, DEFAULT_EXTERNAL_MODULES_DIR)。也就是说除了命令行参数你也可以通过环境变量统一配置export EXTERNAL_MODULES_DIRexample/path checkov -d . --download-external-modules true四、实验特性直接复用 Terraform 已下载的模块对于已经在本地执行过terraform init的项目.terraform目录中已包含模块源码。此时不必让 Checkov 重复下载可以通过实验性环境变量启用对 Terraform 托管模块的复用CHECKOV_EXPERIMENTAL_TERRAFORM_MANAGED_MODULESTrue checkov -d .使用该模式时需要注意以下前提与限制原文档明确说明可与源码互相印证该特性目前标记为Experimental实验性行为可能随版本演进发生变化仅适用于对根目录的扫描且该目录必须已执行过terraform init启用后 Checkov 不会重新下载外部模块而是直接读取.terraform中 Terraform 已经拉取好的模块内容。该环境变量的解析位于 checkov/common/util/env_vars_config.pyCHECKOV_EXPERIMENTAL_TERRAFORM_MANAGED_MODULES convert_str_to_bool(os.getenv(CHECKOV_EXPERIMENTAL_TERRAFORM_MANAGED_MODULES, False))默认关闭。在 registry.py 的load()中开启该开关后当模块版本为latest时会优先从module_latest缓存中查找对应版本的模块内容从而避免向 Registry 发起版本查询与下载请求。五、扫描私有 Terraform 模块环境变量认证体系如果模块存放在私有仓库或私有 Terraform RegistryTerraform Cloud、Terraform Enterprise或 GitLab 等第三方托管平台Checkov 可通过环境变量中的访问令牌尝试克隆并扫描这些模块。下表完整列出支持的凭据变量变量名说明GITHUB_PAT具备私有仓库读取权限的 GitHub personal access tokenBITBUCKET_TOKEN具备私有仓库读取权限的 Bitbucket personal access tokenTF_HOST_NAMETerraform Registry 主机名默认app.terraform.io。例如gitlab.com/example.comTFC_TOKEN*已弃用请改用TF_REGISTRY_TOKEN可访问私有 Registry 的 Terraform Cloud tokenTF_REGISTRY_TOKEN私有 Registry 访问令牌支持 Terraform Cloud / Enterprise 及第三方 RegistryBITBUCKET_USERNAMEBitbucket 用户名只能与BITBUCKET_APP_PASSWORD配合使用BITBUCKET_APP_PASSWORDBitbucket app password只能与BITBUCKET_USERNAME配合使用这些环境变量的实际消费位置与源码一一对应便于排查问题TF_HOST_NAME与TF_REGISTRY_TOKEN由 loaders/registry_loader.py 的discover()读取其中TF_HOST_NAME默认取TFC_HOST_NAME即app.terraform.io。若同时设置了已弃用的TFC_TOKEN源码会打印弃用警告并将其值覆盖给module_params.token。GITHUB_PAT由 loaders/github_access_token_loader.py 读取并将其转换为git::https://x-access-token:tokengithub.com/org/repo形式通过 HTTP 基本认证克隆仓库同时 loaders/git_loader.py 在普通 Git 加载器因“could not read Username for”失败时会判断是否设置了GITHUB_PAT并转入 token 加载流程。BITBUCKET_TOKEN/BITBUCKET_USERNAME/BITBUCKET_APP_PASSWORD由 loaders/bitbucket_access_token_loader.py 读取设置了BITBUCKET_TOKEN时用户名固定为x-token-auth否则使用BITBUCKET_USERNAMEBITBUCKET_APP_PASSWORD组合。自建self-hostedVCS 仓库的认证变量如果模块托管在自建 VCS 上还需配置以下三个环境变量变量名说明VCS_BASE_URL自建 VCS 的基础 URL例如https://example.comVCS_USERNAME基本认证使用的用户名VCS_TOKEN基本认证使用的密码对应读取逻辑位于 loaders/git_loader.py 的discover()设置VCS_BASE_URL后模块 source 前缀会变成git::https://example.com当同时提供VCS_USERNAME与VCS_TOKEN时在_is_matching_loader()见 loaders/git_loader.py中会把认证信息嵌入模块 URL形如git::https://username:tokenexample.com/org/repo。常用场景配置示例Terraform Cloud Registry 私有模块扫描TF_HOST_NAME缺省即app.terraform.io# TF_HOST_NAME will default to app.terraform.io export TF_REGISTRY_TOKENxxxxxx checkov -d . --download-external-modules trueTerraform Enterprise Registry 私有模块扫描export TF_HOST_NAMEtfe.example.com export TF_REGISTRY_TOKENxxxxxx checkov -d . --download-external-modules trueGitLab 公共 Registry 模块扫描export TF_HOST_NAMEgitlab.com checkov -d . --download-external-modules trueGitLab 自建 Registry 私有模块扫描需要 read_api 权限的 job token 或个人访问令牌# A job token or a personal access token with the read_api scope is required export TF_HOST_NAMEgitlab.example.com export TF_REGISTRY_TOKENxxxxxx checkov -d . --download-external-modules true六、模块加载器机制与下载流程了解加载器的分工有助于理解为何不同的模块 source 需要不同的凭据配置。Checkov 的模块加载采用“注册表 多个加载器”的架构ModuleLoaderRegistrycheckov/terraform/module_loading/registry.py维护加载器列表loaders与模块内容缓存module_content_cache在load()中依次尝试每个加载器直到某个加载器成功返回模块内容或给出下一个待解析 URL重复模块通过缓存避免重复下载。抽象基类ModuleLoadercheckov/terraform/module_loading/loader.py定义discover()从环境变量发现凭据、_is_matching_loader()判断能否处理该 source 类型、_load_module()实际下载与_find_module_path()查找已存在路径所有加载器实例在构造时自动注册进全局module_loader_registry。具体加载器与其负责的 source 类型对应如下均位于 checkov/terraform/module_loading/loaders加载器文件匹配的模块 source 类型registry_loader.pyTerraform Registry 模块如terraform-aws-modules/eks/aws支持 Registry API 版本查询、X-Terraform-Get重定向下载、//子模块内层模块解析与归档zip/tgz 等解压github_loader.pygithub.com/org/repo、gitgithub.com:...、git::gitgithub.com:...等 GitHub sourcegithub_access_token_loader.py设置GITHUB_PAT后将 GitHub SSH/HTTP source 转为 token 认证形式bitbucket_loader.pybitbucket.org/...公开仓库bitbucket_access_token_loader.py设置BITBUCKET_TOKEN或用户名 app password 后的 Bitbucket 私有仓库git_loader.pygit::通用 Git source并支持自建 VCS 的VCS_BASE_URL/VCS_USERNAME/VCS_TOKENlocal_path_loader.py本地路径引用的模块无需下载从加载流程看registry.py 中的if not self.download_external_modules and loader.is_external: continue是全局开关只有开启--download-external-modules上述外部加载器才会被尝试。因此无论扫描公有还是私有模块第一步都是先带上该参数。七、扫描效果验证与使用建议验证覆盖范围开启下载后检查.external_modules或自定义路径目录中是否生成了对应模块的源码目录即可确认下载是否成功模块内部的资源随后会出现在 Checkov 的扫描报告中。版本锁定与缓存Registry 加载器会对每个模块源查询可用版本并按语义化版本约束选择最优版本见 loaders/registry_loader.py版本列表会被缓存modules_versions_cache因此同一项目重复扫描不会反复触发网络请求。凭据最小化私有模块仅需授予“可读”权限的令牌GitLab 自建 Registry 场景按官方要求使用带read_apiscope 的令牌。与 CI/CD 集成上述环境变量与 CLI 参数均可直接放入 CI 任务如 GitHub Actions、GitLab CI、Jenkins的步骤中也可通过DOWNLOAD_EXTERNAL_MODULES、EXTERNAL_MODULES_DIR等环境变量统一管理配置。八、小结要让 Checkov 的 Terraform 扫描真正覆盖到第三方与私有模块核心动作有三步一是通过--download-external-modules true显式开启外部模块下载二是按模块来源配置对应的认证环境变量TF_REGISTRY_TOKEN、GITHUB_PAT、BITBUCKET_TOKEN、VCS_*等三是对自建 Registry 额外指定TF_HOST_NAME。在此基础上还可通过--external-modules-download-path定制下载目录或利用实验性的CHECKOV_EXPERIMENTAL_TERRAFORM_MANAGED_MODULES复用terraform init已下载的模块。这些行为均可在 checkov/terraform/module_loading 的加载器源码与 checkov/common/util/ext_argument_parser.py 的参数定义中得到印证相关示例与测试可进一步参考 tests/terraform/module_loading 目录下的用例。【免费下载链接】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),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →