云与虚拟化安全
IaaS/PaaS/SaaS、AWS/Azure、Hypervisor。
云安全:IAM、安全组与数据保护
这一课你将能做到
- 用最小权限原则编写 IAM 策略与安全组规则,说清「为什么这样开」
- 加固对象存储:禁止公开列举、防遍历下载、密钥不落代码
- 为 Spring Boot 平台设计云上的密钥管理与操作审计方案
为什么要学
如今大多数安全事故的入口不再是主机漏洞,而是云配置错误:对象存储桶公开可列举、AccessKey 提交进 Git、安全组开了 0.0.0.0/0 的 22 端口、IAM 用 *:* 一把梭。云厂商负责「云本身的安全」,而「云上的配置」责任在你——这个责任分界叫共享责任模型。
人话:云厂商把大楼建得很牢(机房、硬件、物理安全),但房间门锁没锁、钥匙给了谁,全是你的事。
先建立图像
┌─ 账号层 ── 主账号不用来做日常操作;子账号+MFA;RAM/STS 临时凭证
├─ 身份层 ── IAM 用户/角色/策略:谁(service/person) 能对什么(resource) 做什么(action)
├─ 网络层 ── VPC 划分 + 安全组(白名单) + 内网隔离;数据库不给公网 IP
├─ 数据层 ── 对象存储权限、静态加密、密钥托管(KMS)
└─ 审计层 ── 操作审计(CloudTrail/ActionTrail) + 告警规则
安全组 = 有状态的虚拟防火墙(按实例挂规则);IAM = 决定「人/服务」能调哪些 API。两者是云安全的左右手。
跟着做
步骤 1:安全组最小开放(以 AWS CLI 为例,阿里云控制台同理)
# 错误示范:全开(很多人图省事这么干)
aws ec2 authorize-security-group-ingress --group-id sg-123 \
--protocol tcp --port 22 --cidr 0.0.0.0/0 # ❌ 全网可爆破
# 正确:只放办公室/VPN 出口 IP
aws ec2 authorize-security-group-ingress --group-id sg-123 \
--protocol tcp --port 22 --cidr 203.0.113.0/24 # ✅ 仅办公网段
# 数据库安全组:只允许来自应用安全组的流量(引用 sg-id 而非 IP)
aws ec2 authorize-security-group-ingress --group-id sg-db \
--protocol tcp --port 3306 --source-group sg-app
# 自查:列出所有 0.0.0.0/0 规则
aws ec2 describe-security-groups \
--query 'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]].[GroupName,IpPermissions]'
步骤 2:IAM 最小权限策略
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::java-nav-avatars/*"
}]
}
对比错误写法 "Action": "s3:*", "Resource": "*":前者只读特定桶,泄露后攻击者最多看到头像;后者能删桶、能列举所有桶。原则:Action 最小、Resource 精确、Condition 补条件(如限定 IP 或 MFA)。
步骤 3:对象存储加固
# 检查桶是否公开可列举
curl https://java-nav-avatars.s3.amazonaws.com/?list-type=2
# 返回 ListBucketResult XML = 可列举 ❌ → 关闭公开访问
aws s3api put-public-access-block --bucket java-nav-avatars \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
# 静态资源走 CDN + 签名 URL,而不是开公开读
步骤 4:密钥不落代码
# ❌ 错误:application.yml 提交仓库
# access-key: AKIAIOSFODNN7EXAMPLE
# ✅ 正确:环境变量 / KMS / Vault 注入
cloud:
aws:
credentials:
use-default-aws-credentials-chain: true # 走实例角色,代码里零密钥