AWS 计算服务安全加固完全指南:EC2、Lambda、ECS/EKS、Auto Scaling 与 LightSail 的纵深防御体系
> 关键词:AWS安全最佳实践、EC2安全加固、Lambda权限最小化、ECS/EKS容器安全、Auto Scaling安全组、LightSail安全配置、IAM策略设计、VPC网络隔离、云安全纵深防御、AWS安全审计
- 引言:你的计算实例跑起来了,但它安全吗?
- IAM 权限设计:为每个计算服务打造"最小权限堡垒"
- 网络隔离:构建多层次安全边界
- 数据加密:从静态到传输的全链路保护
- 审计与监控:让每一次操作都可追溯
- 五大服务安全加固总览与优先级矩阵
- 安全检查脚本:一键审计你的 AWS 账号
关键词:AWS安全最佳实践、EC2安全加固、Lambda权限最小化、ECS/EKS容器安全、Auto Scaling安全组、LightSail安全配置、IAM策略设计、VPC网络隔离、云安全纵深防御、AWS安全审计
引言:你的计算实例跑起来了,但它安全吗?
在 AWS 上启动一台 EC2 实例、部署一个 Lambda 函数或创建一个 ECS 集群,通常只需要几分钟。但如果问你:这个资源的攻击面有多大?谁能访问它?敏感数据是否加密?出事了能不能追溯?——大多数团队的答案并不令人安心。
根据 Verizon《2026 数据泄露调查报告》,云配置错误连续第四年位列数据泄露根本原因前三。AWS 提供了强大的安全工具链,但默认配置并不等于安全配置——Shared Responsibility Model(责任共担模型)意味着 AWS 负责"云的安全",而你负责"云中的安全"。
本文将围绕 EC2、Lambda、ECS/EKS、Auto Scaling 和 LightSail 五大计算服务,从 IAM 权限设计、网络安全隔离、数据加密、密钥管理与审计日志 五个维度,构建一套可落地的纵深防御体系。
一、IAM 权限设计:为每个计算服务打造"最小权限堡垒"
AWS 安全的第一道防线永远是 IAM(Identity and Access Management)。每条权限放得太宽,等于给攻击者递了一把万能钥匙。
1.1 EC2 的 IAM 最佳实践
EC2 通过 Instance Profile 获取临时凭证,避免在代码中硬编码 Access Key。
反面案例(危险):
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
正确做法——按需授权:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-app-bucket/*"
},
{
"Effect": "Allow",
"Action": [
"cloudwatch:PutMetricData",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ssm:GetParameter",
"ssm:GetParametersByPath"
],
"Resource": "arn:aws:ssm:us-east-1:123456789012:parameter/myapp/*"
}
]
}
关键原则:
- 使用 Resource 限定而非
"Resource": "*"——精确到 ARN。 - 用 Condition 子句限制来源 IP、VPC 或 MFA 状态。
- 定期运行 IAM Access Analyzer 检查未使用的权限并自动收紧。
1.2 Lambda 的执行角色设计
Lambda 的最大坑是 "一个函数承担所有权限"。大型 Serverless 应用中的单个 Lambda 函数常被赋予 S3、DynamoDB、SQS、SNS、KMS 等全量权限——一旦代码出现 SSRF 漏洞,攻击者就能横向移动。
最小权限模板(单功能 Lambda——仅写入 DynamoDB):
{
"Effect": "Allow",
"Action": ["dynamodb:PutItem", "dynamodb:UpdateItem"],
"Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/Orders",
"Condition": {
"StringEquals": {
"dynamodb:LeadingKeys": "${aws:userid}"
}
}
}
进阶策略:按函数功能拆分角色
| 函数类型 | 需要的权限 | 风险等级 |
|---|---|---|
| API 入口(API Gateway 触发) | 仅写入 SQS | 低 |
| 业务处理 Worker | 读写 DynamoDB、调用 KMS | 中 |
| 文件处理(S3 触发) | 读写特定 S3 前缀、调用 Rekognition | 中高 |
| 管理函数(定时触发器) | 读写多处资源、EC2 操作 | 高 |
Lambda 权限加固检查清单:
- [ ] 每个 Lambda 使用独立的执行角色,禁止共享
- [ ] 检查
cloudwatch:PutMetricData和logs:*之外是否有过度权限 - [ ] 禁止在环境变量中存放明文密钥(改用 Secrets Manager 或 Parameter Store)
- [ ] 启用 Lambda 代码签名(Code Signing)防止未授权代码部署
1.3 ECS/EKS 的任务角色与服务角色分离
ECS/EKS 中存在两级 IAM 角色:
| 角色类型 | 用途 | 权限范围 |
|---|---|---|
| Task Execution Role | 拉取 ECR 镜像、写入 CloudWatch Logs | 最小——仅镜像拉取 + 日志写入 |
| Task Role | 容器内应用的业务权限 | 按应用需求授予 |
| ECS Service Role | ECS 服务自身操作(注册/注销目标组) | 由 ECS 管理 |
常见错误:把 Task Role 的权限直接写到 Task Execution Role。 攻击者如果控制了容器镜像的 entrypoint,就能利用 Execution Role 的权限做超出业务范围的操作。
EKS Pod 安全进阶——IRSA(IAM Roles for Service Accounts):
在 EKS 中,不应直接将 IAM 凭证挂载到 Node 级别。应通过 IRSA 为每个 Pod 的 Service Account 绑定独立的 IAM 角色:
apiVersion: v1
kind: ServiceAccount
metadata:
name: payment-processor
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/PaymentProcessorRole
1.4 Auto Scaling 的 IAM 角色需求
Auto Scaling Group(ASG)需要两个层面的权限:
- 服务相关角色(Service-Linked Role):AWS 托管,自动创建,权限为
autoscaling:SetDesiredCapacity等——你通常无需手动配置。 - 实例的 Instance Profile:扩容出的新 EC2 实例所绑定的 IAM 角色。这里是最容易出问题的地方——如果启动模板中 Instance Profile 包含过高权限,扩容就等于批量制造高权限节点。
安全规则:
- ASG 使用的启动模板中,Instance Profile 权限 = 所有该实例需要的权限并集的最小值。
- 禁止在启动模板里使用 AdministratorAccess 之类的托管策略。
- 对生产环境 ASG,在 Lifecycle Hook 中加入 IAM 合规检查脚本。
1.5 LightSail 的访问控制
LightSail 的权限模型比其他服务简化很多,但仍有几个关键点:
- LightSail 实例底层运行在 AWS 账号内,通过 LightSail 服务角色操作。
- 如果需要从 LightSail 实例访问 S3 或 DynamoDB,应通过 VPC Endpoint 而非公网,避免开放不必要的出站流量。
- LightSail 的 SSH 密钥管理独立于 EC2 Key Pair,需单独审计。
二、网络隔离:构建多层次安全边界
2.1 统一网络架构:各服务在 VPC 中的位置
| 服务 | 网络模型 | 默认暴露面 | 推荐防护 |
|---|---|---|---|
| EC2 | VPC 内,支持安全组 + NACL | 取决于安全组配置 | 仅开放必要端口,SSH 限制 IP |
| Lambda | 默认在 AWS 托管 VPC 中运行(无 VPC 时),有公网出站 | 出站可达公网 | 放入私有子网的 VPC 内运行 |
| ECS (Fargate) | 每个任务分配 ENI,支持 awsvpc 网络模式 | 取决于安全组 | 前端放公有子网 + ALB,后端放私有子网 |
| EKS | Pod 获得独立 IP(VPC CNI) | 取决于 NetworkPolicy | NetworkPolicy + Calico/Cilium 实现微隔离 |
| LightSail | 自带防火墙(非安全组) | 初始仅 SSH 开放 | 按需开放端口,启用 HTTPS 强制 |
2.2 Lambda 联网安全:何时放入 VPC?
Lambda 默认不跑在你的 VPC 里——它运行在 AWS 托管的 VPC 中,可以自由访问公网,但无法访问你 VPC 内的 RDS、ElastiCache 等私有资源。
许多团队为了让 Lambda 访问 RDS,直接把 RDS 暴露到公网——这是灾难性的错误。
正确做法:将 Lambda 挂载到私有子网。
aws lambda update-function-configuration \
--function-name OrderProcessor \
--vpc-config SubnetIds=subnet-abc123,subnet-def456,SecurityGroupIds=sg-lambda-01
代价与对策:
- 放入 VPC 的 Lambda 会失去公网出站能力(除非子网有 NAT Gateway)。
- 如需同时访问 RDS 和外部 API,必须配置 NAT Gateway——每个 AZ 一个,注意 NAT Gateway 的流量费。
- 对于不需要 RDS 的纯对外 API,保持 Lambda 在默认网络中反而更简单安全。
2.3 ECS/EKS 的网络安全分层
推荐三级架构:
┌─────────────────────────────────────────────┐
│ Internet │
└─────────────────┬───────────────────────────┘
│
┌────────▼────────┐
│ ALB (公网) │ ← 唯一公网入口
└────────┬────────┘
│
┌────────────┴────────────┐
│ 公有子网(Web 层) │
│ ECS Service: nginx │
│ 安全组: 仅 443 + 80 │
└────────────┬────────────┘
│
┌────────────▼────────────┐
│ 私有子网(应用层) │
│ ECS Service: app │
│ 安全组: 仅来自 Web 层 │
└────────────┬────────────┘
│
┌────────────▼────────────┐
│ 数据子网(持久层) │
│ RDS / ElastiCache │
│ 安全组: 仅来自应用层 │
└─────────────────────────┘
安全组规则示例(最小开放原则):
| 来源 | 目标 | 协议/端口 | 用途 |
|---|---|---|---|
| 0.0.0.0/0 | ALB | TCP/443 | 公网 HTTPS |
| ALB 安全组 | Web 层 | TCP/3000 | 反向代理 |
| Web 层安全组 | 应用层 | TCP/8080 | 内部转发 |
| 应用层安全组 | 数据库 | TCP/5432 | PostgreSQL |
2.4 LightSail 防火墙的"陷阱"
LightSail 使用基于实例的简化防火墙而非安全组。其默认规则是 "仅开放 SSH 22"——这本身是安全的起点,但部署时往往被人"临时全开"然后忘记。
LightSail 防火墙加固命令:
# 查看当前规则
aws lightsail get-instance-port-states --instance-name my-wp-server
# 关闭不必要的端口(如关闭 3306 MySQL 公网)
aws lightsail close-instance-public-ports \
--instance-name my-wp-server \
--port-info fromPort=3306,toPort=3306,protocol=TCP
# 开放 HTTPS(WordPress 必备)
aws lightsail open-instance-public-ports \
--instance-name my-wp-server \
--port-info fromPort=443,toPort=443,protocol=TCP
致命错误:将数据库端口(3306/5432/6379)开放到 0.0.0.0/0。 这是勒索软件扫描的首要目标。
三、数据加密:从静态到传输的全链路保护
3.1 各服务加密能力对比
| 服务 | 静态加密(存储层) | 传输加密 | 密钥管理 |
|---|---|---|---|
| EC2 | EBS 加密(KMS)、实例存储加密 | ALB/NLB TLS 终结、应用层 TLS | AWS KMS、CloudHSM |
| Lambda | 环境变量加密(KMS)、临时存储 /tmp 加密 | API Gateway TLS、VPC 内 AWS 服务默认加密 | KMS 默认服务密钥或 CMK |
| ECS/EKS | ECR 镜像加密、EFS 加密、Fargate 临时存储加密(默认) | ALB TLS、服务网格 mTLS(App Mesh/Istio) | KMS、Secrets Manager |
| LightSail | 快照加密、附加磁盘加密 | 需自行配置 Let's Encrypt 或上传证书 | 无原生 KMS 集成,建议用 Parameter Store |
3.2 EC2 EBS 加密——一个必须养成的习惯
新 EBS 卷默认不加密。 最佳实践是在账号级别启用 EBS 默认加密:
aws ec2 enable-ebs-encryption-by-default
设置后,该区域所有新创建的 EBS 卷将自动使用指定的 KMS 密钥加密。
3.3 Lambda 环境变量加密
Lambda 的环境变量在存储时可以使用 KMS 加密,但运行时解密后仍以明文存在于内存中——所以不要把环境变量当成密钥保险箱。
# 创建带加密的 Lambda 函数时指定 KMS 密钥
aws lambda create-function \
--function-name SecureProcessor \
--runtime python3.12 \
--role arn:aws:iam::123456789012:role/lambda-exec-role \
--handler index.handler \
--zip-file fileb://function.zip \
--kms-key-arn arn:aws:kms:us-east-1:123456789012:key/abc-123 \
--environment "Variables={DB_HOST=rds.internal,DB_SECRET_ARN=arn:aws:secretsmanager:...}"
最佳实践:不在环境变量中存任何密钥,改用 Secrets Manager 或 Parameter Store 运行时拉取。
import boto3
import json
def get_secret():
client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId='prod/db-credentials')
return json.loads(response['SecretString'])
3.4 ECS/EKS 的密钥注入
不要在 Dockerfile 或任务定义的 environment 字段中硬编码密钥。 应通过以下方式注入:
- Secrets Manager + ECS 任务定义的
secrets字段:
{
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:us-east-1:123456789012:secret:prod/db-credentials:password::"
}
]
}
- EKS 中使用 External Secrets Operator 自动同步 AWS Secrets Manager 到 Kubernetes Secret。
四、审计与监控:让每一次操作都可追溯
4.1 统一审计架构
所有服务 ──→ CloudTrail(API 操作日志)
──→ CloudWatch Logs(应用日志)
──→ VPC Flow Logs(网络流日志)
│
┌──────▼──────┐
│ CloudWatch │
│ Alarms + │
│ SNS 告警 │
└──────┬──────┘
│
┌──────▼──────┐
│ Slack / │
│ PagerDuty │
└─────────────┘
4.2 各服务必须启用的审计项
| 服务 | 必开审计项 | 告警条件示例 |
|---|---|---|
| EC2 | CloudTrail + VPC Flow Logs + OS 级别 auditd | 安全组规则被修改、非工作时间 SSH 登录 |
| Lambda | CloudTrail 数据事件 + X-Ray Tracing | 执行超时率 > 5%、IAM 权限拒绝事件 |
| ECS/EKS | CloudTrail + GuardDuty EKS Protection | 容器以 root 运行、特权模式 Pod 创建 |
| Auto Scaling | CloudTrail + 伸缩活动通知 | 频繁扩缩容(潜在 DDOS 或配置错误) |
| LightSail | CloudTrail(有限)+ 实例 Metrics | SSH 暴力破解检测、异常流量 spike |
4.3 CloudTrail 数据事件——容易被忽略的宝藏
管理事件默认开启,但数据事件(如 S3 对象级操作、Lambda 调用)默认不记录。 尽管数据事件会产生额外费用,但它在安全事件溯源中价值巨大。
# 为所有 S3 桶启用数据事件(在 CloudTrail Trail 中)
aws cloudtrail put-event-selectors \
--trail-name SecurityTrail \
--event-selectors '[{
"ReadWriteType": "All",
"IncludeManagementEvents": true,
"DataResources": [{
"Type": "AWS::S3::Object",
"Values": ["arn:aws:s3:::"]
}]
}]'
4.4 针对 Auto Scaling 的安全告警策略
伸缩活动异常往往是安全事件的前兆:
# 创建 CloudWatch Alarm——当 ASG 在 15 分钟内扩缩超过 50% 时触发
aws cloudwatch put-metric-alarm \
--alarm-name "ASG-Rapid-Scaling-Alert" \
--metric-name GroupTotalInstances \
--namespace AWS/AutoScaling \
--statistic Average \
--period 300 \
--evaluation-periods 3 \
--threshold 50 \
--comparison-operator GreaterThanThreshold \
--alarm-actions arn:aws:sns:us-east-1:123456789012:Security-Team
五、五大服务安全加固总览与优先级矩阵
5.1 安全能力全景对比
| 安全维度 | EC2 | Lambda | ECS/EKS | Auto Scaling | LightSail |
|---|---|---|---|---|---|
| IAM 细粒度权限 | ★★★★★ | ★★★★☆ | ★★★★☆ | ★★★☆☆ | ★★☆☆☆ |
| 网络安全组/防火墙 | ★★★★★ | ★★★☆☆ | ★★★★★ | ★★★★☆ | ★★★☆☆ |
| 静态数据加密 | ★★★★★ | ★★★★☆ | ★★★★★ | ★★★☆☆ | ★★★☆☆ |
| 传输加密 | ★★★★★ | ★★★★☆ | ★★★★★ | ★★★★☆ | ★★★☆☆ |
| 审计日志 | ★★★★★ | ★★★★☆ | ★★★★☆ | ★★★☆☆ | ★★☆☆☆ |
| 密钥管理集成 | ★★★★★ | ★★★★★ | ★★★★★ | ★★★★☆ | ★★★☆☆ |
| 容器/代码签名 | N/A | ★★★★☆ | ★★★★☆ | N/A | N/A |
5.2 按投入产出比的优先级排序
| 优先级 | 措施 | 适用服务 | 投入 | 安全收益 |
|---|---|---|---|---|
| 🔴 P0 | 禁止使用 "Resource": "*" 的 IAM 策略 | 全部 | 低 | 极高 |
| 🔴 P0 | 关闭数据库端口对公网的暴露 | EC2, LightSail | 极低 | 极高 |
| 🔴 P0 | 启用 EBS 默认加密 | EC2 | 极低 | 高 |
| 🟡 P1 | Lambda 放入 VPC 私有子网(如需访问 RDS) | Lambda | 中 | 高 |
| 🟡 P1 | 启用 CloudTrail 数据事件 | 全部 | 中(有费用) | 高 |
| 🟡 P1 | ECS Task Role 与 Execution Role 分离 | ECS | 低 | 高 |
| 🟢 P2 | VPC Flow Logs 全覆盖 | EC2, ECS, Lambda(VPC) | 中 | 中 |
| 🟢 P2 | Kubernetes NetworkPolicy + Pod Security Standards | EKS | 中 | 中 |
| 🟢 P2 | LightSail 定期快照 + 加密 | LightSail | 低 | 中 |
六、安全检查脚本:一键审计你的 AWS 账号
以下脚本可以快速扫描常见的安全配置问题。请在只读权限下运行,生产环境务必先在测试账号验证。
#!/bin/bash
# AWS Compute Security Quick Audit
# 用法: bash aws-security-audit.sh
echo "=== 1. 检查 S3 桶是否公开可读 ==="
aws s3 ls | awk '{print $3}' | while read bucket; do
status=$(aws s3api get-bucket-acl --bucket "$bucket" --query "Grants[?Grantee.URI=='http://acs.amazonaws.com/groups/global/AllUsers']" --output text 2>/dev/null)
if [ -n "$status" ]; then
echo "⚠️ 公开桶: $bucket"
fi
done
echo ""
echo "=== 2. 检查安全组是否对 0.0.0.0/0 开放敏感端口 ==="
SENSITIVE_PORTS="22,3389,3306,5432,6379,27017"
aws ec2 describe-security-groups \
--filters Name=ip-permission.cidr,Values=0.0.0.0/0 \
--query "SecurityGroups[?IpPermissions[?FromPort>=22 && ToPort<=3389]].{GroupName:GroupName,GroupId:GroupId}" \
--output table
echo ""
echo "=== 3. 检查 IAM 用户是否超过 90 天未轮换密钥 ==="
aws iam list-users --query "Users[*].UserName" --output text | tr '\t' '\n' | while read user; do
aws iam list-access-keys --user-name "$user" --query "AccessKeyMetadata[?CreateDate<=\`$(date -d '90 days ago' +%Y-%m-%d)\`].[UserName,AccessKeyId,CreateDate]" --output table
done
echo ""
echo "=== 4. 检查是否有未加密的 EBS 卷 ==="
aws ec2 describe-volumes \
--filters Name=encrypted,Values=false \
--query "Volumes[*].[VolumeId,Size,State]" \
--output table
echo ""
echo "完成扫描。请根据上述输出逐一修复。"
结语:安全不是一次性工作
AWS 计算服务的安全加固没有终点——它是一个持续的过程。每周可能都有新实例被创建、新安全组被添加、新 IAM 角色被授予权限。安全团队真正的挑战不是"配置一次做对",而是"始终保持正确"。
三个持续改进的核心措施:
- 将安全检查集成到 CI/CD 管线中——使用 cfn-nag、Checkov 或 tfsec 扫描 IaC 模板。
- 启用 AWS Config 规则——自动检测不合规资源(如
ec2-security-group-attached-to-eni)。 - 建立 Incident Response Runbook——每个计算服务的应急预案都应在文档中就绪,确保出事时每个人都知道第一步该做什么。
安全没有银弹,但纵深防御可以让攻击者的每一步都充满阻力——这才是实实在在的保护。
本文由 5.chengzicloud.cloud 提供,点击访问首页了解更多