大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
安全扫描与测试
这一课你将能做到
- 用 Trivy(tfsec) 和 Checkov 在提交前扫描 Terraform 的错误配置与合规问题
- 用 gitleaks 防止密钥进 Git,并给 Terraform 建立分层安全基线
- 用 IAM Access Analyzer 校验策略、按最小权限治理 Terraform 执行角色
为什么要学
Terraform 让创建云资源变得极快——快到一个错误配置也能在几秒钟内复制到所有环境:安全组对全世界开 22 端口、S3 桶默认关闭加密、RDS 公网可达、角色策略里的 Resource: "*"。这类问题靠人工评审很难每次发现,必须用自动化策略扫描在代码进入流水线时就拦住。这是「左移」在基础设施领域的具体含义。
同时要破除一个常见误解:扫描器不是安全的全部。密钥管理、state 保护、最小权限、云厂商侧护栏(Guardrails/SCP)共同构成防线。本课是整门课的收束,把前面散落的安全点串成体系,并说明 HCP Terraform 这类托管方案在其中的位置。
先建立图像
Terraform 的四层防线:
第 1 层 提交前:IDE / pre-commit(tflint + trivy + gitleaks)
第 2 层 CI verify:Checkov/Trivy 策略门禁,不过不允许合并
第 3 层 云账号边界:SCP / Guardrails / S3 公网块 / IAM 权限边界
第 4 层 运行与审计:CloudTrail、Config 漂移检测、Access Analyzer 告警
扫描关注点分类:
misconfig 配置违规(公网暴露、未加密、日志未开)
secret 代码中的密钥(AK/SK、私钥、令牌)
compliance 对照 CIS/NIST/等保基线的缺口
iam 策略过于宽松、可提权语句
跟着做
步骤 1:用 Trivy 扫描配置
Trivy 已合并原 tfsec,是 Aqua 维护的开源扫描器。安装:
# macOS
brew install trivy
# 或直接用容器运行,免安装
在配置目录执行:
trivy config --scanners misconfig,secret ./
对这样一段有问题的配置:
resource "aws_security_group" "bad" {
name = "bad"
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
}
输出会类似:
main.tf:1 MEDIUM Security group allows ingress from 0.0.0.0/0 to 22
AVD-AWS-0101
https://avd.aquasec.com/nvd/...
只看高危、设置非零退出码(CI 门禁必需):
trivy config --severity HIGH,CRITICAL --exit-code 1 ./
步骤 2:用 Checkov 做合规基线扫描
Checkov(Bridgecrew/Prisma 出品)内置 CIS AWS Benchmark 等数百策略:
pip install checkov
checkov -d ./
按框架输出合规率:
checkov -d ./ --framework terraform --output cli
# Passed checks: 24, Failed checks: 2, Skipped checks: 0
工程实践中 Trivy 和 Checkov 二选一作为主力即可,规则集互补时可都跑。误报要显式抑制而不是关掉检查:
resource "aws_security_group" "bastion" {
#checkov:skip=CKV_AWS_20:堡垒机设计上需要对公网开放 22,另有 MFA 与审计
name = "bastion"
# ...
}
抑制注释必须写理由(#checkov:skip=ID:理由),评审时一眼可查,避免静默放过。
步骤 3:gitleaks 防密钥进历史
brew install gitleaks
gitleaks detect --source ./ --verbose # 扫描 Git 历史
gitleaks protect --staged --verbose # pre-commit 只扫暂存区
pre-commit 框架配置(.pre-commit-config.yaml):
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.88.0
hooks:
- id: terraform_fmt
- id: terraform_tflint
- id: terraform_trivy
安装:pre-commit install。这样本地提交就过格式、lint、配置扫描和密钥检查,CI 再做一次防绕过。如果密钥已经进了 Git 历史,删除文件不够,要用 gitleaks 定位并轮换密钥、清理历史。
步骤 4:IAM 治理与 Access Analyzer
Terraform 执行角色最容易被写成「管理员一把梭」。治理方法:
- 写策略时用 IAM Access Analyzer 校验语法与过度权限:
aws accessanalyzer validate-policy \
--policy-document file://deploy-role.json --policy-type IDENTITY_POLICY
findings 里会标出 PASS_ROLE_WITH_STAR_IN_RESOURCE 这类风险。
-
按 CloudTrail 实际调用生成最小策略:AWS 控制台基于访问记录生成策略(或用
tf-iam-viz等工具审计),把 Terraform 实际用到的 action 收敛成白名单。 -
用
aws_iam_policy_document数据源而不是手写 JSON:
data "aws_iam_policy_document" "tf_apply" {
statement {
effect = "Allow"
actions = [
"ec2:RunInstances", "ec2:TerminateInstances",
"ec2:CreateSecurityGroup", "ec2:AuthorizeSecurityGroupIngress",
]
resources = ["arn:aws:ec2:ap-northeast-1:123456789012:*"]
}
}
结构化生成可避免 JSON 逗号、通配符笔误,也更易按条件收窄。plan 角色与 apply 角色继续分离。
步骤 5:账号护栏与 HCP Terraform
扫描器管「代码里写了什么」,管不住「有人绕过 Terraform 在控制台干了什么」,所以账号层补:
- SCP(组织服务控制策略):禁止关闭 CloudTrail、禁止非加密桶、禁止区域外操作;
- S3 账户级公网访问块、EBS 默认加密、GuardDuty/Config 全账号开启;
- Config 规则做持续漂移检测,发现非 Terraform 变更即告警。
HCP Terraform(HashiCorp 托管)提供远程执行环境、私有模块注册表、策略即代码(Sentinel)和状态加密托管,适合不想自建 Atlantis/后端的团队;免费层即可小规模使用。它不改变本课方法论,只是把后端、锁、策略运行托管出去。本站自建 S3 后端 + OIDC 流水线,能力等价、成本更低。
讲清楚要点
- 扫描必须门禁化:只生成报告不阻断合并等于没做;非零退出码接 CI,例外显式带理由。
- 三个「不是」:sensitive 不是加密、扫描器不是全部安全、Terraform 防不住控制台旁路——四层防线缺一不可。
- 密钥问题以轮换为终点:一旦泄露进历史,扫描、清历史之外必须轮换,旧值在日志/缓存中早已扩散。
- 最小权限是持续过程:初期角色偏宽可以接受,但要用 CloudTrail/Access Analyzer 定期收敛,并把策略本身纳入 Terraform 管理。
- 策略即代码可进阶:Checkov custom checks、Sentinel、OPA 让团队自定义「必须打成本标签」「只能用私有子网」等组织规则。
你可能会懵的地方
-
扫描器误报太多,团队想整体关掉怎么办? 不要关。先升级到最新规则,再按资源逐条
skip=ID:理由抑制;误报集中在某类资源(如堡垒机)可写自定义策略缩小范围。 -
Checkov 和 Trivy 有什么区别?要都装吗? 规则来源与合规框架不同:Checkov 强在多框架(Terraform/K8s/CFN)与合规报表,Trivy 统一了镜像/依赖/密钥/IaC 扫描。入门选一个主力即可,团队成熟后互补。
-
state 加密了,为什么还担心机密泄露? 加密防存储介质泄露,但任何有 state 读权限的人都能读到明文;读权限收口、机密托管在 Secrets Manager(state 里只存 ARN)才是根本。
-
最小权限一开始怎么知道要列哪些 action? 先按模块文档和实际 plan 收集,apply 时看 CloudTrail 的 Denied 事件逐步补;AWS 的「基于访问活动生成策略」可自动化,季度复核一次。
-
HCP Terraform 和自建后端如何取舍? 看运维成本与合规要求:多团队、要私有注册表与策略治理选 HCP;账号体系独立、预算敏感选自建 S3 + OIDC + Atlantis/原生 CI。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 安全组开放 0.0.0.0/0 到管理端口 | 直接暴露可被爆破 | 限堡垒机 CIDR/VPN,管理走 SSM |
| 密钥写进 tfvars 提交 | Git 历史永久泄露 | Secrets Manager/TF_VAR,gitleaks 兜底 |
| Terraform 角色用 AdministratorAccess | 一个角色失守全账号沦陷 | 分环境/分 plan-apply,收敛 action |
| CI 扫描结果只发通知不阻塞 | 错误配置照样合并 | --exit-code 1 门禁化 |
| skip 检查不写理由 | 例外失控、审计困难 | 抑制注释必须附原因 |
卡点急救
- Trivy/Checkov 报数百个失败、无法起步:先用
--severity HIGH,CRITICAL只门禁高危,中低危登记成 backlog 分批治理,避免一上来卡死所有流水线。 - gitleaks 阻断提交但确认是测试假值:确认值确实无效后用允许规则(
gitleaks allow)或.gitleaks.toml精确放行该路径,不要全局关闭。 - apply 角色权限不足导致半套资源:看 CloudTrail 的 AccessDenied 事件补最小 action 后重跑 apply(资源操作幂等,可安全继续);不要临时给管理员权限再忘了收。
面试常问
-
你们如何保障 Terraform 代码安全? 分层回答:pre-commit(fmt/tflint/trivy/gitleaks)+ CI 门禁(Checkov/Trivy 高危即失败,例外带理由)+ state 加密锁与 OIDC 临时凭证 + IAM 最小权限与 Access Analyzer 审计 + SCP/Config 账号护栏与漂移检测。
-
发现 Access Key 被提交到 Git 怎么办? 立即轮换/作废密钥(第一步!),gitleaks 确认泄露范围,清理历史或接受「密钥已作废」的现实,排查 CloudTrail 是否被滥用,最后补上 pre-commit 与 CI 防护防止再发。
-
策略扫描器报了误报,处理流程是什么? 升级规则核实 → 资源级 skip 并写明业务理由(评审留痕)→ 必要时写自定义检查替代;禁止全局禁用规则。
自测三问
- 说清楚四层防线分别防什么?为什么只有扫描层不够?
- 为什么
sensitive = true不能替代 Secrets Manager? - 给你一个新项目仓库,从 0 到 1 你会接入哪些安全检查,顺序如何?
小结一句话
Terraform 安全靠「提交前扫描 + CI 策略门禁 + 账号级护栏 + 审计最小权限」四层协同,工具拦住配置错误,流程和边界拦住旁路与滥用。
延伸
- Trivy IaC 扫描文档
- Checkov 官方文档与策略索引
- IAM Access Analyzer 策略校验
- 课程收官:回到 Terraform 路线图 标记已掌握节点;下一步推荐学习 helm-gitops-essentials,把应用交付推进到 Kubernetes 与 GitOps 工作流。