云基础设施安全(Cloud Infrastructure Security)
来源: affaan-m/everything-claude-code 原始文件: skills/security-review/cloud-infrastructure-security.md 类别: E-安全保障
激活时机
- 将应用部署到云平台(AWS、Vercel、Railway、Cloudflare)
- 配置 IAM 角色和权限
- 设置 CI/CD 管道
- 实现基础设施即代码(Infrastructure as Code,IaC)(Terraform、CloudFormation)
- 配置日志和监控
- 在云环境中管理密钥
- 设置 CDN 和边缘安全
- 实施灾难恢复和备份策略
云安全检查清单
1. IAM 与访问控制
最小权限原则(Principle of Least Privilege)
# 正确:最小权限
iam_role:
permissions:
- s3:GetObject # 仅读取权限
- s3:ListBucket
resources:
- arn:aws:s3:::my-bucket/* # 仅限特定存储桶
# 错误:过于宽泛的权限
iam_role:
permissions:
- s3:* # 所有 S3 操作
resources:
- "*" # 所有资源
多因素认证(MFA)
# 始终为 root/admin 账户启用 MFA
aws iam enable-mfa-device \
--user-name admin \
--serial-number arn:aws:iam::123456789:mfa/admin \
--authentication-code1 123456 \
--authentication-code2 789012
验证步骤
- 生产环境不使用 root 账户
- 所有特权账户已启用 MFA
- 服务账户使用角色,而非长期凭据
- IAM 策略遵循最小权限原则
- 定期进行访问审查
- 未使用的凭据已轮换或删除
2. 密钥管理(Secrets Management)
云密钥管理器
// 正确:使用云密钥管理器
import { SecretsManager } from '@aws-sdk/client-secrets-manager';
const client = new SecretsManager({ region: 'us-east-1' });
const secret = await client.getSecretValue({ SecretId: 'prod/api-key' });
const apiKey = JSON.parse(secret.SecretString).key;
// 错误:硬编码或仅使用环境变量
const apiKey = process.env.API_KEY; // 不轮换,不审计
密钥轮换
# 设置数据库凭据自动轮换
aws secretsmanager rotate-secret \
--secret-id prod/db-password \
--rotation-lambda-arn arn:aws:lambda:region:account:function:rotate \
--rotation-rules AutomaticallyAfterDays=30
验证步骤
- 所有密钥存储在云密钥管理器中(AWS Secrets Manager、Vercel Secrets)
- 数据库凭据已启用自动轮换
- API 密钥至少每季度轮换
- 代码、日志或错误消息中无密钥
- 已启用密钥访问的审计日志
3. 网络安全
VPC 和防火墙配置
# 正确:受限的安全组
resource "aws_security_group" "app" {
name = "app-sg"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"] # 仅限内部 VPC
}
egress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # 仅限 HTTPS 出站
}
}
# 错误:对互联网开放
resource "aws_security_group" "bad" {
ingress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"] # 所有端口,所有 IP!
}
}
验证步骤
- 数据库不可公开访问
- SSH/RDP 端口仅限 VPN/堡垒机(Bastion)
- 安全组遵循最小权限
- 网络 ACL 已配置
- VPC 流日志已启用
4. 日志与监控
CloudWatch/日志配置
// 正确:全面日志记录
import { CloudWatchLogsClient, CreateLogStreamCommand } from '@aws-sdk/client-cloudwatch-logs';
const logSecurityEvent = async (event: SecurityEvent) => {
await cloudwatch.putLogEvents({
logGroupName: '/aws/security/events',
logStreamName: 'authentication',
logEvents: [{
timestamp: Date.now(),
message: JSON.stringify({
type: event.type,
userId: event.userId,
ip: event.ip,
result: event.result,
// 绝不记录敏感数据
})
}]
});
};
验证步骤
- 所有服务已启用 CloudWatch/日志
- 已记录失败的认证尝试
- 管理员操作已审计
- 日志保留已配置(合规要求 90 天以上)
- 已配置可疑活动告警
- 日志已集中化且防篡改
5. CI/CD 管道安全
安全管道配置
# 正确:安全的 GitHub Actions 工作流
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: read # 最小权限
steps:
- uses: actions/checkout@v4
# 扫描密钥
- name: Secret scanning
uses: trufflesecurity/trufflehog@main
# 依赖审计
- name: Audit dependencies
run: npm audit --audit-level=high
# 使用 OIDC,而非长期令牌
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/GitHubActionsRole
aws-region: us-east-1
供应链安全
// package.json - 使用锁文件和完整性检查
{
"scripts": {
"install": "npm ci", // 使用 ci 确保可复现的构建
"audit": "npm audit --audit-level=moderate",
"check": "npm outdated"
}
}
验证步骤
- 使用 OIDC 替代长期凭据
- 管道中包含密钥扫描
- 依赖漏洞扫描
- 容器镜像扫描(如适用)
- 分支保护规则已实施
- 合并前需要代码评审
- 签名提交(Signed Commits)已强制
6. Cloudflare 与 CDN 安全
Cloudflare 安全配置
// 正确:带安全头的 Cloudflare Workers
export default {
async fetch(request: Request): Promise<Response> {
const response = await fetch(request);
// 添加安全头
const headers = new Headers(response.headers);
headers.set('X-Frame-Options', 'DENY');
headers.set('X-Content-Type-Options', 'nosniff');
headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
headers.set('Permissions-Policy', 'geolocation=(), microphone=()');
return new Response(response.body, {
status: response.status,
headers
});
}
};
WAF 规则
# 启用 Cloudflare WAF 托管规则
# - OWASP 核心规则集
# - Cloudflare 托管规则集
# - 速率限制规则
# - Bot 防护
验证步骤
- WAF 已启用 OWASP 规则
- 速率限制已配置
- Bot 防护已激活
- DDoS 防护已启用
- 安全头已配置
- SSL/TLS 严格模式已启用
7. 备份与灾难恢复
自动化备份
# 正确:自动化 RDS 备份
resource "aws_db_instance" "main" {
allocated_storage = 20
engine = "postgres"
backup_retention_period = 30 # 保留 30 天
backup_window = "03:00-04:00"
maintenance_window = "mon:04:00-mon:05:00"
enabled_cloudwatch_logs_exports = ["postgresql"]
deletion_protection = true # 防止意外删除
}
验证步骤
- 已配置每日自动备份
- 备份保留期满足合规要求
- 已启用时间点恢复(Point-in-Time Recovery)
- 每季度执行备份恢复测试
- 灾难恢复计划已文档化
- RPO 和 RTO 已定义并经过测试
部署前云安全检查清单
在任何生产云部署之前:
- IAM:未使用 root 账户,已启用 MFA,最小权限策略
- 密钥:所有密钥在云密钥管理器中并已配置轮换
- 网络:安全组受限,无公开数据库
- 日志:CloudWatch/日志已启用并配置保留
- 监控:已配置异常活动告警
- CI/CD:OIDC 认证、密钥扫描、依赖审计
- CDN/WAF:Cloudflare WAF 已启用 OWASP 规则
- 加密:静态和传输中数据已加密
- 备份:自动备份且恢复已测试
- 合规:满足 GDPR/HIPAA 要求(如适用)
- 文档:基础设施已文档化,运维手册已创建
- 事件响应:安全事件应对计划已就绪
常见云安全配置错误
S3 存储桶暴露
# 错误:公开存储桶
aws s3api put-bucket-acl --bucket my-bucket --acl public-read
# 正确:私有存储桶,特定访问
aws s3api put-bucket-acl --bucket my-bucket --acl private
aws s3api put-bucket-policy --bucket my-bucket --policy file://policy.json
RDS 公开访问
# 错误
resource "aws_db_instance" "bad" {
publicly_accessible = true # 绝不这样做!
}
# 正确
resource "aws_db_instance" "good" {
publicly_accessible = false
vpc_security_group_ids = [aws_security_group.db.id]
}
参考资源
切记:云配置错误是数据泄露的主要原因。一个暴露的 S3 存储桶或过于宽松的 IAM 策略就可能危及整个基础设施。始终遵循最小权限和纵深防御原则。