关于 terraform-security-audit
terraform-security-audit 是面向 Terraform 代码库的安全审计技能,逐项检查 IAM、网络、加密、密钥、访问和合规性。它输出各领域的通过或失败状态,并为未通过项提供修复代码。
主要功能
- 01检查六个安全领域
- 02扫描所有 .tf 文件
- 03按严重性突出问题
- 04为失败项提供修复代码
- 05生成分领域审计报告
适用场景
- 01生产部署前审查基础设施
- 02定期检查基础设施安全
- 03验证新服务配置
- 04事故后强化安全设置
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ c0x12c/ ai-toolkit --skill terraform-security-audit安装后在 Claude Code 中输入/terraform-security-audit确认已加载。
详细介绍
Terraform 安全审计
对 Terraform 代码库进行涵盖 6 个领域的安全审计。为每个领域生成通过/未通过报告。
使用时机
- 生产部署前的安全审查
- 定期基础设施安全审计
- 新服务设置验证
- 事件发生后的安全加固检查
流程
1. IAM — 身份与访问管理
- CI/CD 使用 OIDC(不使用长期访问密钥)
- EKS 工作负载使用 IRSA(不使用节点级 IAM)
- ECS 任务角色按服务限定范围(不共享角色)
- IAM 策略遵循最小权限原则
- 不在
*资源上使用*操作 - 不使用内联策略(使用托管策略或客户策略)
- Assume role 条件包含
ExternalId或sts:SourceIdentity
# INSECURE — overly broad permissions
resource "aws_iam_policy" "bad" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = "*"
Resource = "*"
}]
})
}
# SECURE — scoped to specific actions and resources
resource "aws_iam_policy" "good" {
policy = jsonencode({
Statement = [{
Effect = "Allow"
Action = ["s3:GetObject", "s3:PutObject"]
Resource = "${aws_s3_bucket.assets.arn}/*"
}]
})
}
# SECURE — IRSA for EKS pods
module "irsa" {
source = "git::https://github.com/{project}/terraform-modules.git//irsa?ref=v1.0.0"
name = "${local.name_prefix}-irsa"
oidc_provider_arn = var.oidc_provider_arn
namespace = var.service
service_account = var.service
policy_arns = [aws_iam_policy.service.arn]
}
2. 网络 — VPC 和安全组
- 数据库仅位于私有子网中
- 除 443 端口上的 ALB 外,不允许来自
0.0.0.0/0的入站流量 - 安全组使用
source_security_group_id,而非 CIDR - 尽可能限制出站流量
- 已启用 VPC 流日志
- 非堡垒机实例没有公有 IP
# INSECURE — database accessible from anywhere
resource "aws_security_group_rule" "rds_bad" {
type = "ingress"
from_port = 5432
to_port = 5432
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.rds.id
}
# SECURE — database only from app security group
resource "aws_security_group_rule" "rds_good" {
type = "ingress"
from_port = 5432
to_port = 5432
protocol = "tcp"
source_security_group_id = aws_security_group.app.id
security_group_id = aws_security_group.rds.id
description = "PostgreSQL access from application"
}
3. 加密 — 静态数据和传输中的数据
- S3:已启用 SSE(KMS 或 AES-256)
- RDS:
storage_encrypted = true - RDS:通过参数组设置
ssl_enforcement - Redis:
transit_encryption_enabled = true - Redis:
at_rest_encryption_enabled = true - EBS 卷已加密
- Terraform 状态存储桶使用 SSE-KMS 加密
- ALB 仅使用 TLS 1.2+
# INSECURE — no encryption
resource "aws_db_instance" "bad" {
storage_encrypted = false # default
}
# SECURE — encryption enabled
resource "aws_db_instance" "good" {
storage_encrypted = true
kms_key_id = var.rds_kms_key_arn
}
# SECURE — Redis encryption
module "redis" {
source = "git::https://github.com/{project}/terraform-modules.git//elasticache?ref=v1.0.0"
transit_encryption = true
at_rest_encryption = true
auth_token = var.redis_auth_token
}
4. 密钥 — 密钥管理
-
.tf文件或已提交的.tfvars文件中没有密钥 -
secrets.tfvars已加入.gitignore - 敏感变量标记为
sensitive = true - 通过 CI/CD 环境变量注入密钥
- 状态文件中没有明文密码(使用
sensitive输出) - git-secret-protector 或 pre-commit 钩子会阻止意外提交
# INSECURE — password in code
resource "aws_db_instance" "bad" {
password = "SuperSecret123!"
}
# SECURE — from variable, marked sensitive
variable "db_password" {
description = "Database master password"
type = string
sensitive = true
}
resource "aws_db_instance" "good" {
password = var.db_password
}
# SECURE — sensitive output
output "connection_string" {
value = "postgresql://${var.db_user}:${var.db_password}@${aws_db_instance.main.endpoint}/${var.db_name}"
sensitive = true
}
5. 访问 — 集群和控制台访问
- EKS
aws-authConfigMap 将访问权限限制为所需角色 - 控制台访问使用 SSO(不使用带密码的 IAM 用户)
- 堡垒主机位于私有子网中,并使用 Session Manager(不使用 SSH 密钥)
- 已启用 CloudTrail 以记录 API 审计日志
- 人员账户已强制启用 MFA
# EKS access control
resource "kubernetes_config_map" "aws_auth" {
metadata {
name = "aws-auth"
namespace = "kube-system"
}
data = {
mapRoles = yamlencode([
{
rolearn = var.admin_role_arn
username = "admin"
groups = ["system:masters"]
},
{
rolearn = var.node_role_arn
username = "system:node:{{EC2PrivateDNSName}}"
groups = ["system:bootstrappers", "system:nodes"]
}
])
}
}
6. 合规 — 标签、命名和备份
- 所有资源均已添加标签:Project、Service、Environment、ManagedBy
- 命名遵循
{project}-{service}-{env}约定 - 已启用 RDS 自动备份(保留时间 >= 7 天,生产环境为 30 天)
- 已为数据存储桶启用 S3 版本控制
- 已启用 DynamoDB 时间点恢复
- 已为关键指标设置 CloudWatch 警报
- 已配置成本分配标签
# CORRECT — default tags at provider level
provider "aws" {
default_tags {
tags = {
Project = var.project
Service = var.service
Environment = var.env
ManagedBy = "terraform"
}
}
}
# CORRECT — backup retention
resource "aws_db_instance" "main" {
backup_retention_period = var.env == "prod" ? 30 : 7
backup_window = "03:00-04:00"
}
交互方式
- 扫描代码库中的所有
.tf文件 - 检查每个领域,不跳过任何部分
- 优先突出关键问题(IAM 通配符、公开访问、缺少加密)
- 为每项未通过的检查提供修复代码
规则
- 严重:IAM
*/*、数据库公开访问、存储未加密、代码中包含密钥 - 警告:缺少标签、备份保留时间过短、没有流日志
- 信息:缺少描述、未应用可选加固措施
输出
生成安全审计报告:
## Terraform Security Audit: {service}
### Overall: Pass | Fail
| Area | Status | Critical | Warnings | Info |
|------------|----------|----------|----------|------|
| IAM | Pass | 0 | 0 | 1 |
| Network | Fail | 1 | 0 | 0 |
| Encryption | Pass | 0 | 1 | 0 |
| Secrets | Pass | 0 | 0 | 0 |
| Access | Pass | 0 | 0 | 1 |
| Compliance | Warning | 0 | 2 | 0 |
### Critical Findings
- **[Network]** Security group `rds_main` allows ingress from 0.0.0.0/0 on port 5432
- File: `modules/{service}/sg.tf:15`
- Fix: Replace `cidr_blocks` with `source_security_group_id`
### Warnings
- **[Encryption]** Redis `at_rest_encryption` not enabled
- File: `modules/{service}/redis.tf:8`
- Fix: Add `at_rest_encryption = true`
### Remediation Priority
1. Fix critical findings before any deployment
2. Address warnings before production promotion
3. Info items for next sprint
评论
支持 Markdown