1.6.7.1. Checkov

Checkov 是由 Bridgecrew 开发、现已归属 Palo Alto Networks Prisma Cloud 平台的开源静态分析工具。它专注于 基础设施即代码(Infrastructure as Code, IaC)的安全检查,通过在云资源部署之前扫描配置代码,及时发现不安全的配置和合规隐患。简单来说,Checkov 会解析 Terraform 等模板代码,在资源实际部署前就找到潜在的错误配置或漏洞,从而充当云环境的“安全守门人”。作为 “策略即代码” (Policy-as-Code) 思想的实践,Checkov 将一系列安全最佳实践和合规要求编写成代码策略,自动化地与基础设施代码进行比对检查。凭借丰富的内置规则库和高度扩展性,Checkov 在 DevSecOps 生态中扮演重要角色——它可以无缝融入开发与CI/CD流程,帮助团队在开发阶段就落实安全政策,避免将风险带到后期环境。

1.6.7.1.1. 功能与用途

作为一款定位于 Terraform 等 IaC 的静态分析工具,Checkov 提供了全面的安全与合规扫描能力。其主要用途在于对 Terraform 模板代码进行静态检查,发现在配置层面的安全漏洞、错误配置以及不符合政策的事项,具体包括:

  • 安全最佳实践检查:内置上千条针对 AWS、Azure、GCP 等云环境的安全基线规则。例如,确保存储桶开启加密、数据库不对公网开放、密码策略符合要求等。Checkov 会将 Terraform 配置与这些业界最佳实践比对,标出不达标之处并给出改进建议。
  • 合规性扫描:支持将代码与合规标准进行对照,如 CIS 基线、PCI-DSS、GDPR 等常见规范。借助这些检查,团队可以及早识别违反合规要求的配置(例如未启用日志审计,保留期限不足等),确保基础设施符合监管和公司内部政策。
  • 策略违规检测:除了行业标准,Checkov 也可执行组织自定义的策略检查。例如要求所有资源必须打标签、禁止使用某些不安全的实例类型等。通过编写自定义规则(支持用 Python 或 YAML 编写策略),企业能够将内部规范固化为自动化检查。
  • 敏感信息扫描:检查 Terraform 代码中是否含有明文的凭证或敏感数据。Checkov 利用正则、关键词匹配和熵算法来检测诸如 AWS 密钥、私有密钥、数据库密码等泄露在代码中的情况。这有助于防止凭证泄漏和配置中包含硬编码敏感信息。
  • 上下文关系分析:借助图形关系引擎,Checkov 不仅逐条资源检查,还能基于资源之间的关系执行上下文感知的策略。例如,它可以发现安全组规则过于宽松是否正好作用于一个公有子网中的实例,从而评估组合配置的风险。这种基于图的分析让检查更智能,覆盖更复杂的场景。
  • 多框架支持:尽管本节聚焦 Terraform,Checkov 实际上支持多种常见 IaC 框架,包括 Terraform Plan、CloudFormation、Kubernetes YAML、Helm、Serverless 等。这意味着无论团队采用何种模板语言,都可以用同一套工具进行安全扫描(无需介绍跨云策略细节,这里不展开)。这种多平台兼容性使 Checkov 成为云原生基础设施代码安全领域的通用工具。
  • 丰富的扫描报告:Checkov 支持将扫描结果输出为多种格式,方便人与系统阅读。除了默认的 CLI 控制台输出外,还可生成 JSON 报告、JUnit XML 测试报告、SARIF 文件以及 GitHub 风格的 Markdown 等。这些多样化的输出形式便于与其他系统集成:例如,将 JUnit 输出供 CI 平台解析展示,或用 SARIF 输出将结果上传至代码托管平台以提供安全分析视图。

通过以上功能,Checkov 能够对 Terraform 模块和配置进行全面的静态分析。在扫描过程中,它会列出每个检测到的问题项,包括违反的规则编号、严重等级、受影响的资源,以及相应的修复指导。对于每条违规,Checkov通常提供参考链接或描述说明如何整改(可通过 --no-guide 参数关闭提示)。这一系列静态检查并不需要实际部署云资源,因而速度快、覆盖面广,为团队提供了及时的反馈和修复建议。

1.6.7.1.2. 我们为什么需要 Checkov

在大型团队和复杂项目中,引入 Checkov 等 IaC 静态扫描工具对 Terraform 模块治理至关重要。下面从几个方面说明其价值:

  • 模块复用的安全保障:Terraform 鼓励通过模块来实现代码复用。然而,一个被广泛复用的模块如果存在配置缺陷,将导致大量环境出现相同的安全隐患。使用 Checkov,可以在模块发布或集成时自动扫描模块代码,及早发现不安全设置(例如某模块未强制加密、开放了默认端口等)。这样,组织在推广复用模块前就能修复隐患,确保共享的模块在各项目中都是安全可靠的。从治理角度看,Checkov 为模块建立了质量门禁,防止不良配置随模块扩散。
  • 团队协作与规范统一:在多人协作编写 Terraform 的场景,不同成员对安全最佳实践的了解和执行可能不一致。Checkov 提供了统一的自动检查标准,相当于为团队配备了一位不会疏漏的“代码审计员”。每次提交代码时,Checkov 都以相同标准审核,确保所有人遵循同一套安全和合规基线。这减少了人工 Code Review 的负担和主观差异,让新人也能立即知道哪些配置不符合团队规范。通过将安全规则制度化为工具,团队协作变得更加顺畅,基础设施代码的风格和质量也更加一致。
  • 降低云配置风险:配置错误是导致云环境安全事故的主要原因之一。许多灾难源于简单的失误,如存储桶权限过于宽松、未开启日志、网络端口裸露在公网等。Checkov 的作用是在风险酿成后果之前就捕获这些错误配置,并阻止其进入部署流程。这一“左移”安全(Shift Left)的做法,大大降低了云环境遭受攻击或违规的概率。相比事后通过云监控或渗透测试发现问题,事前静态扫描不仅更高效成本更低,也避免了错误配置真正暴露在生产环境所带来的潜在损失。总之,Checkov将云安全防线前移,为模块治理和整体基础设施安全提供了关键支撑。

值得一提的是,Checkov 所体现的理念是“预防胜于补救”。通过在部署前执行检查,团队能遵循最佳实践和安全政策,避免后期因为配置漏洞付出高昂代价。越早发现并修复问题,就越能节省时间和资源——Checkov 正是实践这一理念的利器。

1.6.7.1.3. 安装与本地使用

Checkov 基于 Python 实现,因此需要准备好 Python 3.7+ 的运行环境(Terraform 代码本身建议使用 0.12 以上版本)。安装方式相当简便,多数情况下通过 Python 的软件包管理器 pip 即可完成:

# 使用 pip 安装 Checkov(全平台通用)
pip install checkov

或者:

pip3 install checkov
# (可选)使用 Homebrew 安装 Checkov(适用于 macOS)
brew install checkov

对于不方便直接安装的环境(如CI服务器),官方也提供了 Docker 镜像用以运行 Checkov。无需安装,只需拉取镜像并运行命令即可,例如:

# 使用官方 Docker 镜像运行 Checkov 扫描当前目录
docker pull bridgecrew/checkov
docker run --rm -v "$(pwd):/iac" bridgecrew/checkov -d /iac --framework terraform

以上命令会在容器中执行 Checkov,将当前工作目录挂载进去并扫描其中的 Terraform 配置。

安装完成后,就可以通过命令行使用 checkov 命令对 Terraform 模板进行扫描。基本用法十分直观,既可以指定目录扫描整个 Terraform 配置项目,也可以指向具体的文件:

# 扫描某个目录下的所有 Terraform 配置文件
checkov --directory /path/to/terraform/code

# 扫描单个 Terraform 文件
checkov --file /path/to/example.tf

执行上述命令后,Checkov 将解析 Terraform 模板,并对其中的每个资源配置运行内置的检查策略。扫描结果会在终端输出,其中包括通过的检查项和未通过的项。对于未通过的项,Checkov会显示规则的 ID 编号、违规资源的名称和类型、问题简述,以及建议的修复措施或参考链接。

例如一个来自于研究 Terraform 安全配置问题的样本仓库 TerraGoat 的例子:

resource "azurerm_managed_disk" "example" {
  name                 = "terragoat-disk-${var.environment}"
  location             = var.location
  resource_group_name  = azurerm_resource_group.example.name
  storage_account_type = "Standard_LRS"
  create_option        = "Empty"
  disk_size_gb         = 1
  encryption_settings {
    enabled = false
  }
  tags = {
    git_commit           = "d68d2897add9bc2203a5ed0632a5cdd8ff8cefb0"
    git_file             = "terraform/azure/storage.tf"
    git_last_modified_at = "2020-06-16 14:46:24"
    git_last_modified_by = "nimrodkor@gmail.com"
    git_modifiers        = "nimrodkor"
    git_org              = "bridgecrewio"
    git_repo             = "terragoat"
    yor_trace            = "d17da7b3-f1c5-4723-9f77-d1b9069459c7"
  }
}

resource "azurerm_storage_account" "example" {
  name                     = "tgsa${var.environment}${random_integer.rnd_int.result}"
  resource_group_name      = azurerm_resource_group.example.name
  location                 = azurerm_resource_group.example.location
  account_tier             = "Standard"
  account_replication_type = "GRS"
  queue_properties {
    logging {
      delete                = false
      read                  = false
      write                 = true
      version               = "1.0"
      retention_policy_days = 10
    }
    hour_metrics {
      enabled               = true
      include_apis          = true
      version               = "1.0"
      retention_policy_days = 10
    }
    minute_metrics {
      enabled               = true
      include_apis          = true
      version               = "1.0"
      retention_policy_days = 10
    }
  }
  tags = {
    git_commit           = "5c6b5d60a8aa63a5d37e60f15185d13a967f0542"
    git_file             = "terraform/azure/storage.tf"
    git_last_modified_at = "2021-05-02 10:06:10"
    git_last_modified_by = "nimrodkor@users.noreply.github.com"
    git_modifiers        = "Adin.Ermie/nimrodkor"
    git_org              = "bridgecrewio"
    git_repo             = "terragoat"
    yor_trace            = "23861ff4-c42d-495e-80ac-776c74035f43"
  }
}

resource "azurerm_storage_account_network_rules" "test" {
  resource_group_name  = azurerm_resource_group.example.name
  storage_account_name = azurerm_storage_account.example.name

  default_action = "Deny"
  ip_rules       = ["127.0.0.1"]
  bypass         = ["Metrics"]
}

警告!! 该例子是被故意设置成包含多个安全问题,以测试策略检查工具的策略库的。请不要在生产环境这样做!!

我们尝试用 Checkov 检查该文件:

/workspaces/terragoat/terraform/azure (master) $ checkov --file storage.tf 
[ terraform framework ]: 100%|████████████████████|[1/1], Current File Scanned=storage.tf
[ secrets framework ]: 100%|████████████████████|[1/1], Current File Scanned=storage.tf

       _               _
   ___| |__   ___  ___| | _______   __
  / __| '_ \ / _ \/ __| |/ / _ \ \ / /
 | (__| | | |  __/ (__|   < (_) \ V /
  \___|_| |_|\___|\___|_|\_\___/ \_/

By Prisma Cloud | version: 3.2.439 

terraform scan results:

Passed checks: 5, Failed checks: 14, Skipped checks: 0

Check: CKV_AZURE_36: "Ensure 'Trusted Microsoft Services' is enabled for Storage Account access"
        PASSED for resource: azurerm_storage_account.example
        File: /storage.tf:23-60
        Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/azure-policies/azure-networking-policies/enable-trusted-microsoft-services-for-storage-account-access
Check: CKV_AZURE_3: "Ensure that 'enable_https_traffic_only' is enabled"
        PASSED for resource: azurerm_storage_account.example
        File: /storage.tf:23-60
        Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/azure-policies/azure-general-policies/azr-general-3
Check: CKV_AZURE_206: "Ensure that Storage Accounts use replication"
        PASSED for resource: azurerm_storage_account.example
        File: /storage.tf:23-60
        Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/azure-policies/azure-general-policies/azr-general-206
Check: CKV_AZURE_244: "Avoid the use of local users for Azure Storage unless necessary"
        PASSED for resource: azurerm_storage_account.example
        File: /storage.tf:23-60
        Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/azure-policies/azure-general-policies/bc-azure-244
Check: CKV_AZURE_35: "Ensure default network access rule for Storage Accounts is set to deny"
        PASSED for resource: azurerm_storage_account_network_rules.test
        File: /storage.tf:62-69
        Guide: https://docs.prismacloud.io/en/enterprise-edition/policy-reference/azure-policies/azure-networking-policies/set-default-network-access-rule-for-storage-accounts-to-deny
Check: CKV_AZURE_251: "Ensure Azure Virtual Machine disks are configured without public network access"
        FAILED for resource: azurerm_managed_disk.example
        File: /storage.tf:1-21

                1  | resource "azurerm_managed_disk" "example" {
                2  |   name                 = "terragoat-disk-${var.environment}"
                3  |   location             = var.location
                4  |   resource_group_name  = azurerm_resource_group.example.name
                5  |   storage_account_type = "Standard_LRS"
                6  |   create_option        = "Empty"
                7  |   disk_size_gb         = 1
                8  |   encryption_settings {
                9  |     enabled = false
                10 |   }
                11 |   tags = {
                12 |     git_commit           = "d68d2897add9bc2203a5ed0632a5cdd8ff8cefb0"
                13 |     git_file             = "terraform/azure/storage.tf"
                14 |     git_last_modified_at = "2020-06-16 14:46:24"
                15 |     git_last_modified_by = "nimrodkor@gmail.com"
                16 |     git_modifiers        = "nimrodkor"
                17 |     git_org              = "bridgecrewio"
                18 |     git_repo             = "terragoat"
                19 |     yor_trace            = "d17da7b3-f1c5-4723-9f77-d1b9069459c7"
                20 |   }
                21 | }
...

我们可以看到哪些检查通过了,哪些没有,失败的规则检查的描述、触发失败的代码块未知等信息。

Checkov 的 CLI 提供了丰富的参数来自定义扫描行为:

  • 可以使用 -d--directory 来递归扫描目录,或用 -f/--file 针对单一文件。若不指定,默认会扫描当前目录。
  • 利用 --check 参数可以只运行指定的规则检查,例如只检查特定的规则 ID 列表:

    checkov --directory . --check CKV_AWS_20,CKV_AWS_57
    

    上例将仅运行规则编号为 CKV_AWS_20CKV_AWS_57 的检查,用于聚焦特定问题。

  • 相反,使用 --skip-check 参数则可以跳过某些检查

    checkov -d . --skip-check CKV_AWS_20
    

    这将在扫描时忽略 CKV_AWS_20 规则,对于团队有特殊情况不适用的规则,可通过此方式跳过。--skip-check--check 参数也支持指定风险等级关键字(HIGH, MEDIUM 等)以过滤高危或中危问题。

  • 使用 -o/--output 可以指定输出格式,例如 -o json 输出 JSON,-o junitxml 生成 JUnit XML 报告供 CI 消费,-o sarif 生成供代码扫描的平台使用的SARIF格式等。还可以通过 --output-file-path 将结果保存到文件。
  • 默认情况下,如果发现任何未通过的检查,Checkov 进程将以非零退出码结束,从而可用于脚本或 CI 判断扫描失败。若希望即使有违规也不使流程失败,可使用 --soft-fail 参数将退出码设置为 0。这在初始实施阶段或试运行时很有用,避免因扫描未通过而阻塞团队工作。
  • Checkov 也允许通过配置文件来集中管理参数。可以创建一个 config.yaml,在其中写入上述命令行选项(例如要扫描的目录、要跳过的检查、输出格式等),然后运行时用 --config-file config.yaml 加载。借助 --create-config 参数,甚至可以根据给定命令行选项自动生成配置文件模板,方便进一步定制。

除了手动运行检查外,将 Checkov 融入开发者的日常工作流中能显著提高效率。在本地开发环境,Git 钩子(pre-commit)是一种常见集成方式。通过 Git 的 pre-commit 钩子,可以实现在开发者提交代码时自动执行 Checkov 检查,阻止不符合策略的代码进入版本库。实施方法是使用开源的 pre-commit 框架,添加 Bridgecrew 提供的 Checkov 钩子配置。例如,在项目根目录添加 .pre-commit-config.yaml

- repo: https://github.com/bridgecrewio/checkov.git
  rev: '' # change to tag or sha
  hooks:
    - id: checkov
      # - id: checkov_container
      # - id: checkov_diff
      # - id: checkov_diff_container
      # - id: checkov_secrets
      # - id: checkov_secrets_container

然后执行 pre-commit install --install-hooks 安装钩子。此后,每次 git commit 时,Checkov 会自动扫描改动的 Terraform 文件;如有未通过的检查,将拒绝此次提交并报告问题,使开发者在提交前就修复。通过这种机制,安全检查被无形融入了日常编码过程中,降低了后期发现问题的几率。值得注意的是,Checkov 还提供了 VS Code 编辑器插件,可以在开发时实时扫描 Terraform 文件并给出行内的安全建议。无论是使用 IDE 插件还是 Git 钩子,本地集成都确保了问题在第一时间被发现和解决,提升了模块代码质量。

1.6.7.1.4. 集成到 CI/CD 流程

将 Checkov 集成到持续集成/持续部署(CI/CD)流程中,可以在代码合并和部署前设置自动化的安全门禁。下面介绍如何在主流 CI/CD 平台中嵌入 Checkov。

1.6.7.1.4.1. 在 GitHub Actions 中集成

GitHub Actions 提供了方便的机制将 Checkov 纳入工作流。Bridgecrew 官方发布了现成的 Checkov 扫描动作 (Action),可直接用于扫描 Terraform 代码。通过该 Action,我们无需自行安装环境,配置非常简单。例如,新增一个工作流 .github/workflows/checkov.yml

---
name: Checkov
on:
  push:
    branches:
      - master
jobs:
  build:

    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Set up Python 3.8
        uses: actions/setup-python@v4
        with:
          python-version: 3.8
      - name: Test with Checkov
        id: checkov
        uses: bridgecrewio/checkov-action@master
        with:
          directory: example/examplea
          framework: terraform

上述配置将在每次 Pull Request 提交时运行一个 Checkov 作业:首先检出代码,然后使用官方的 Checkov Action 执行扫描。我们通过参数指定扫描当前仓库目录下的 example/examplea` 内的 Terraform 配置。执行效果是:如果 Checkov 检测到任何未通过的规则,Action 将标记检查失败,从而使 GitHub 的 PR 检查状态变为 ❌,阻止不安全配置的更改被合并。开发者在 Pull Request 页面即可看到哪些检查未通过,并可点击详情了解违规的具体资源和原因。借助 GitHub Actions,将安全扫描融入代码审核流程,实现了每次修改的自动安全审计。另外,Checkov 也支持输出 SARIF 格式并结合 GitHub Code Scanning,使扫描结果出现在仓库的安全检测栏中,进一步提升可见性(需另行配置上传 SARIF 的步骤)。

通过以上示例可以看出,仅需在流水线中增加执行 checkov 的步骤,并根据需要配置其参数和报告格式。当扫描发现问题时,让流水线失败(或阻止合并),就能实现对 Terraform 模块的持续治理。在大型项目中,可以将这些 CI 集成配置模板化或集中管理,这样组织内的所有项目都能方便地使用相同的安全扫描标准。持续的自动化检查能够大幅提升Terraform模块的安全基线,配合之前提到的本地扫描手段,真正形成从开发到部署的全方位模块治理流程,确保基础设施即代码的每一步都在安全护航之下。

总结而言,Bridgecrew 的 Checkov 工具为 Terraform 模块治理提供了强有力的支持。从开发者编写代码阶段的本地扫描,到CI管道中的自动审核,Checkov将安全和合规检查深度融入 Terraform 模块的生命周期。借助它,团队可以自信地在大规模复用模块的同时,保持对云环境风险的可控。在模块治理的实践中,引入 Checkov 不仅提高了效率,也显著增强了基础设施代码的安全性和可靠性,为企业的云基础设施保驾护航。

results matching ""

    No results matching ""