2. 策略语法详解:版本、语句、Effect、Action、Resource、Condition
嗯,策略语法这东西,说白了就是IAM的“配置文件语言”。你写的每一行,都决定了谁能在什么条件下干什么。我刚开始接触IAM时,觉得它跟JSON区别不大——直到有一次因为搞混了Effect,差点把生产环境的写权限全开放出去……从那以后我就明白了:语法细节,一条都含糊不得。
2.1 策略的整体骨架
一个标准的IAM策略长这样:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "192.168.0.0/24"
}
}
}
]
}
我最喜欢把这个结构拆成两部分:头部(Version)和主体(Statement数组)。你想想看,每个Statement就像一条独立的小规则,而所有规则拼起来,就是这个策略的完整意图。
2.2 Version——别小看它
Version字段目前只有两个有效值:2012-10-17 和 2008-10-17(旧版)。我很奇怪,为什么有人写策略时会直接删掉Version?我个人习惯是一定留着,并且只用最新的。为什么?因为旧版本有些特性不支持,比如Condition的某些运算符。
2.3 Statement——策略的核心容器
Statement是一个数组,每个元素包含Effect、Action、Resource、Condition四个部分。注意:数组里可以有多个语句,它们之间是逻辑或的关系。即,只要有一条语句匹配,整个策略就生效。
我通常建议:把权限分成小而明确的语句,而不是堆砌成一条庞然大物。你想想看,一条语句十几个Action和几十个Resource,排查问题时会疯掉的。
2.4 Effect——最关键的决策
| Effect值 | 含义 | 典型使用场景 |
|---|---|---|
Allow | 允许操作 | 授予权限 |
Deny | 拒绝操作 | 覆盖其他允许项、安全护栏 |
很多人以为“Allow+Deny”同时出现时,Deny一定会赢。没错,显式Deny优先级最高。但我要提醒你:默认隐式Deny才是坑。如果你的策略既没有Allow也没有Deny,结果就是拒绝。我在项目中遇到过:某个团队写了一条只包含Condition的语句,忘了加Effect,结果所有请求都被默默拒绝,查了一整天。
2.5 Action——具体允许或拒绝的操作
Action的格式通常是服务名:操作名,可以有多条。比如:
"Action": [
"s3:GetObject",
"s3:PutObject"
]
也可以用通配符*,但我不推荐滥用。为什么?因为它会让你失去对细粒度权限的控制。我个人习惯:先写最小需要的Action列表,后续再通过测试逐步放宽。说实话,一开始就写"Action": "*"的做法,除了Demo环境,在生产里就是定时炸弹。
2.6 Resource——权限作用的对象
Resource指定了哪些资源可以被操作。ARN的格式因服务而异,但通用模板是:
arn:partition:service:region:account-id:resource-type/resource-id
比如S3的ARN:arn:aws:s3:::my-bucket/*。注意那个/*——它表示桶内所有对象。如果只写arn:aws:s3:::my-bucket,那只能操作桶本身(比如列出桶),而不能操作对象。
在实际项目中,最容易出问题的地方就是Resource写得太宽了。我记得有一次,团队给一个Lambda函数的执行角色配了Resource: "*",结果它就能访问所有人的S3桶。虽然短期内没出事,但安全审计时直接被标红。我们后来强制要求:Resource必须明确到具体的桶或路径。
2.7 Condition——控制条件
Condition可以让你在特定条件下才生效。常见的有:IP地址限制、时间范围、是否使用MFA、资源标签等。语法结构是:
"Condition": {
"条件运算符": {
"条件键": "条件值"
}
}
举个例子,只允许从公司内网访问:
"Condition": {
"IpAddress": {
"aws:SourceIp": "203.0.113.0/24"
}
}
Condition里有个比较容易踩的坑:条件键的大小写。比如aws:SourceIp中间的SourceIp,S是大写的。如果写成小写,条件永远不会匹配。嗯,这里要注意。
2.8 它们如何协作?一张SVG结构图
下面这张图帮你串起整个语法结构。每个字段各自扮演什么角色,一目了然。
2.9 实战总结:写策略时的四个检查点
- Version——确保是
2012-10-17,不要用旧版。 - Effect + Action 组合——别漏写Effect,也别写超范围的Action。
- Resource——宁可写多个具体ARN,也别用“*”代替一切。
- Condition——条件键的大小写、运算符的选取都要核对。
我个人习惯:写完策略先做安全评审。把策略贴到内部工具或AWS IAM模拟器里测试一遍。别偷懒,我曾经就因为少写了一个Condition,差点让非内网IP也能访问敏感数据。测试就是成本最小的保险。
2.10 常见陷阱一览表
| 陷阱 | 表现 | 解决方法 |
|---|---|---|
| Effect默认不含Deny | 权限意外泄露 | 显式声明Deny语句 |
| Resource中桶名不包含“/*” | 无法访问桶内对象 | 检查ARN,对象权限加“/*” |
| Condition条件键大小写错 | 条件永不生效 | 查阅官方文档复制写法 |
| 多条Statement不按字面顺序执行 | 逻辑混乱 | 依赖显式Deny,不依赖顺序 |