# Implementing Infrastructure As Code Security Scanning

> 本技能涵盖使用 Checkov、tfsec 和 KICS 等工具为基础设施即代码（IaC）模板实施自动化安全扫描。 内容包括在部署前检测 Terraform、CloudFormation、Kubernetes 清单和 Helm charts 中的配置错误， 建立基于策略的治理，以及将 IaC 扫描集成到 CI/CD 管道中以防止不安全的云资源配置。

- Skill: `killvxk/implementing-infrastructure-as-code-security-scanning` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add killvxk/implementing-infrastructure-as-code-security-scanning`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/implementing-infrastructure-as-code-security-scanning/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/implementing-infrastructure-as-code-security-scanning

---


# 实施基础设施即代码安全扫描

## 使用场景

- 使用 Terraform、CloudFormation 或 Pulumi 配置云基础设施并需要自动化安全验证时
- 合规框架要求在部署前提供基础设施配置审查证据时
- 防止常见的云配置错误，如公开的 S3 存储桶、开放的安全组或未加密的存储时
- 建立在 pull request 中阻止不安全基础设施变更的护栏时
- 管理多云环境并需要在 AWS、Azure 和 GCP 之间保持一致的安全策略时

**不适用于**扫描应用源代码（使用 SAST）、监控已部署基础设施的配置漂移（使用云安全态势管理工具）或容器镜像漏洞扫描（使用 Trivy）。

## 前置条件

- 已安装 Checkov v3.x（`pip install checkov`）或已安装 tfsec
- 仓库中包含 Terraform、CloudFormation 或 Kubernetes IaC 文件
- 可访问 IaC 目录的 CI/CD 管道
- Bridgecrew API 密钥（可选，用于 Checkov 平台集成）

## 操作流程

### 步骤 1：对 Terraform 文件运行 Checkov

```bash
# 扫描目录中的所有 Terraform 文件
checkov -d ./terraform/ --framework terraform --output cli --output json --output-file-path ./results

# 扫描特定文件
checkov -f main.tf --output json

# 扫描 Terraform 计划（对动态值更准确）
terraform init && terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json
checkov -f tfplan.json --framework terraform_plan

# 仅运行特定检查
checkov -d ./terraform/ --check CKV_AWS_18,CKV_AWS_19,CKV_AWS_20

# 跳过特定检查
checkov -d ./terraform/ --skip-check CKV_AWS_145,CKV2_AWS_6
```

### 步骤 2：将 IaC 扫描集成到 GitHub Actions

```yaml
# .github/workflows/iac-security.yml
name: IaC Security Scan

on:
  pull_request:
    paths:
      - 'terraform/**'
      - 'cloudformation/**'
      - 'k8s/**'

jobs:
  checkov:
    name: Checkov IaC Scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Checkov
        uses: bridgecrewio/checkov-action@v12
        with:
          directory: terraform/
          framework: terraform
          output_format: cli,sarif
          output_file_path: console,checkov.sarif
          soft_fail: false
          skip_check: CKV_AWS_145

      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: checkov.sarif
          category: checkov-iac

  tfsec:
    name: tfsec Scan
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run tfsec
        uses: aquasecurity/tfsec-action@v1.0.3
        with:
          working_directory: terraform/
          sarif_file: tfsec.sarif
          soft_fail: false

      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: tfsec.sarif
          category: tfsec
```

### 步骤 3：创建自定义 Checkov 策略

```python
# custom_checks/s3_versioning.py
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
from checkov.common.models.enums import CheckResult, CheckCategories


class S3BucketVersioning(BaseResourceCheck):
    def __init__(self):
        name = "Ensure S3 bucket has versioning enabled"
        id = "CKV_CUSTOM_1"
        supported_resources = ["aws_s3_bucket"]
        categories = [CheckCategories.GENERAL_SECURITY]
        super().__init__(name=name, id=id, categories=categories,
                         supported_resources=supported_resources)

    def scan_resource_conf(self, conf):
        versioning = conf.get("versioning", [{}])
        if isinstance(versioning, list) and len(versioning) > 0:
            if versioning[0].get("enabled", [False])[0]:
                return CheckResult.PASSED
        return CheckResult.FAILED


check = S3BucketVersioning()
```

### 步骤 4：配置基线和抑制

```yaml
# .checkov.yaml
branch: main
compact: true
directory:
  - terraform/
  - cloudformation/
framework:
  - terraform
  - cloudformation
  - kubernetes
output:
  - cli
  - sarif
skip-check:
  - CKV_AWS_145    # 使用 CMK 的 S3 默认加密（SSE-S3 可接受）
  - CKV2_AWS_6     # S3 存储桶请求日志记录（由 CloudTrail 处理）
soft-fail: false
```

### 步骤 5：扫描 Kubernetes 清单和 Helm Charts

```bash
# 扫描 Kubernetes 清单
checkov -d ./k8s/ --framework kubernetes

# 扫描 Helm charts（先渲染模板）
checkov -d ./charts/myapp/ --framework helm

# 使用 KICS 扫描（Keeping Infrastructure as Code Secure）
docker run -v $(pwd)/k8s:/path checkmarx/kics:latest scan \
  --path /path \
  --output-path /path/results \
  --type Kubernetes \
  --report-formats json,sarif
```

## 关键概念

| 术语 | 定义 |
|------|------|
| IaC 扫描 | 对基础设施代码模板进行自动化分析，以在部署前检测安全配置错误 |
| 策略即代码 | 以可执行代码定义的安全策略，可进行版本控制、测试和自动化执行 |
| CKV 检查 ID | Checkov 每个安全检查的唯一标识符（例如，CKV_AWS_18 表示 S3 公共访问） |
| Terraform 计划扫描 | 扫描已解析的 Terraform 计划 JSON，包含计算值和模块展开 |
| 基于图的扫描 | Checkov 分析资源之间关系的能力，而非仅单个资源配置 |
| 配置漂移检测 | 识别 IaC 定义与实际已部署基础设施状态之间的差异 |
| 自定义策略 | 用 Python 或 YAML 编写的组织特定安全检查，用于执行内部标准 |

## 工具与系统

- **Checkov**：Bridgecrew 的开源 IaC 扫描器，拥有 2500+ 内置策略，涵盖主要云服务商
- **tfsec**：Aqua Security 的 Terraform 专注静态分析工具，深度理解 HCL
- **KICS**：Checkmarx 的开源 IaC 扫描器，支持 15+ IaC 框架
- **Terrascan**：支持 OPA Rego 策略自定义的 IaC 扫描器
- **Snyk IaC**：与 Snyk 平台集成的商业 IaC 扫描器

## 常见场景

### 场景：防止 Terraform 中的公共 S3 存储桶

**背景**：某开发团队反复创建没有适当访问控制的 S3 存储桶。最近一次事件通过公共存储桶暴露了客户数据。

**方法**：
1. 在 CI/CD 管道中为所有 Terraform 变更启用 Checkov
2. 强制执行 CKV_AWS_18（无公共读 ACL）、CKV_AWS_19（加密）、CKV_AWS_20（未禁用公共访问块）
3. 创建自定义策略，要求每个 S3 存储桶都有 `aws_s3_bucket_public_access_block` 资源
4. 设置 `soft_fail: false` 以在 S3 安全检查失败时阻止 PR 合并
5. 提供带有安全默认值的 Terraform 模块供团队复用

**注意事项**：仅扫描 `.tf` 文件会遗漏动态计算值。使用 Terraform 计划扫描可获得更高准确性。Checkov 的资源关系检查（CKV2 前缀）需要图分析模式。

## 输出格式

```
IaC 安全扫描报告
==========================
框架：Terraform
目录：terraform/
扫描日期：2026-02-23

Checkov 结果：
  通过：187
  失败：12
  跳过：3
  未知：0

失败检查：
  CKV_AWS_18  [高危]   S3 存储桶具有公共读 ACL
              资源：aws_s3_bucket.data_lake
              文件：terraform/storage.tf:15-28

  CKV_AWS_24  [高危]   CloudWatch 日志组未加密
              资源：aws_cloudwatch_log_group.app
              文件：terraform/monitoring.tf:3-8

  CKV_AWS_79  [中危]   已启用实例元数据服务 v1
              资源：aws_instance.web
              文件：terraform/compute.tf:12-30

质量门禁：失败（2 个高危发现）
```

