Terraform 安全扫描实战:tfsec 配置指南

适用场景

Terraform IaC 安全扫描适用于以下场景:

  • 基础设施代码合入前自动检测高危配置:S3 桶公开访问、安全组放行 0.0.0.0/0、磁盘未加密等;
  • 在 CI/CD 流水线中设置质量门禁,阻止不合规的 Terraform 计划进入生产环境;
  • 接手存量基础设施代码时做一次全面基线体检;
  • 满足等保、ISO 27001 等合规审计对云资源配置的留痕要求。

前置条件

  • Terraform 1.5+(terraform -version 验证);
  • tfsec 与 Checkov 任选其一或都装:tfsec 提供 Docker/二进制安装,Checkov 依赖 Python 3.8+;
  • 一个包含风险配置的测试模块(下文提供);
  • CI 环境(本文以 GitHub Actions 为例)。

原理说明

两类工具都属于静态分析:不调用云 API,直接解析 .tf 文件构建的资源图,对照内置策略库(CIS Benchmark、AWS/Azure/GCP 最佳实践)逐项检查。tfsec(现已并入 Aqua Trivy,命令保留)专注 Terraform、速度快、输出友好;Checkov 支持面更广,覆盖 Terraform、CloudFormation、Kubernetes、Dockerfile 等框架,并支持用 Python/YAML 编写自定义策略。两者都返回非零退出码表示存在高危问题,这正是 CI 门禁的判定依据。

操作步骤

1. 准备含风险的示例代码

resource "aws_s3_bucket" "data" {
  bucket = "wafai-demo-data"
}

resource "aws_s3_bucket_public_access_block" "data" {
  bucket                  = aws_s3_bucket.data.id
  block_public_acls       = false
  block_public_policy     = false
}

resource "aws_security_group_rule" "open_ssh" {
  type              = "ingress"
  from_port         = 22
  to_port           = 22
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = "sg-0123456789abcdef0"
}

resource "aws_ebs_volume" "app" {
  availability_zone = "ap-northeast-1a"
  size              = 100
}

示例包含三个典型问题:S3 允许公开访问、SSH 对全网开放、EBS 卷未加密

2. 安装并运行 tfsec

# macOS
brew install tfsec

# Linux 一键安装
curl -s https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash

# Docker 方式运行
docker run --rm -v "$PWD:/scan" aquasec/tfsec /scan

tfsec .

tfsec 会输出每条问题的严重级别、规则编号(如 aws-s3-enable-bucket-encryption)与修复建议链接。

3. 安装并运行 Checkov

pip install checkov

checkov -d .

# 只输出失败项,降低日志噪音
checkov -d . --compact

Checkov 输出带 CKV_AWS_* 编号的检查结果,可用 -c CKV_AWS_20,CKV_AWS_23 只跑指定规则。

4. 处理误报:行内豁免

resource "aws_ebs_volume" "app" {
  availability_zone = "ap-northeast-1a"
  size              = 100
  # checkov:skip=CKV_AWS_3:临时卷不存敏感数据,季度评审
  # tfsec:ignore:aws-ebs-encrypt-encrypted-volume
}

豁免注释必须写明理由,便于后续审计复查,避免豁免被无限期滥用。

5. 集成到 GitHub Actions

name: iac-security
on:
  pull_request:
    paths: ["**/*.tf"]
jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: tfsec
      uses: aquasecurity/tfsec-pr-commenter-action@v1.3.1
      with:
        github_token: ${{ github.token }}
    - name: Checkov
      uses: bridgecrewio/checkov-action@v12
      with:
        directory: .
        framework: terraform
        output_format: cli

配置验证

按建议修复示例问题(开启 S3 block_public_acls、收紧安全组 CIDR、给 EBS 加 encrypted = true)后重新运行:

tfsec . && echo "tfsec PASS"
checkov -d . ; echo "checkov exit=$?"

两个命令退出码均为 0、输出 “0 failures” 即代表门禁通过。可以将此步骤设为 PR 必检项,实现”不通过则不可合入”。

常见问题

FAQ 1:扫描结果误报太多,团队开始无视告警怎么办?

采用分级策略:CRITICAL/HIGH 阻断合入,MEDIUM 以下先告警;确属误报的用行内豁免并注明到期日期。每月复查豁免清单,删除已失效的豁免项。

FAQ 2:tfsec 和 Checkov 应该选哪个?

纯 Terraform 项目追求速度与 CI 集成简洁,选 tfsec;技术栈包含 CloudFormation、Kubernetes、Helm 等多类 IaC,或需要自定义 Python 策略与对接 Bridgecrew 平台,选 Checkov。两者同时运行成本不高,互为补充可以覆盖更多规则。

总结

Terraform IaC 安全扫描把基础设施风险拦截在”计划尚未执行”的阶段,成本远低于事后整改。落地三步走:先用 tfsec/Checkov 对存量代码做基线体检,再把扫描嵌入 PR 流水线设置严重级别门禁,最后通过带备注的行内豁免机制控制误报影响。持续维护策略库版本与豁免清单,才能让 IaC 安全真正成为研发流程的一部分而非摆设。