AWS S3 IAM策略Deny IP规则异常:为何0.0.0.0/0会拒绝所有IP?
你的问题出在对IAM策略中NotIpAddress条件运算符的逻辑理解,以及可能的IP类型匹配问题上,具体拆解如下:
1. 策略的实际逻辑
你写的这条Deny策略逻辑是:当请求的源IP不属于0.0.0.0/0(所有IPv4地址)范围时,拒绝所有S3操作。
按正常逻辑,所有IPv4发起的请求都符合0.0.0.0/0,这条Deny的条件应该永远不满足,不会触发拒绝。但实际出现Access Denied,核心原因可能有两个:
原因一:请求使用了IPv6地址
0.0.0.0/0仅覆盖所有IPv4地址,不包含任何IPv6地址。如果你的客户端优先使用IPv6连接S3,请求的源IP是IPv6格式,自然不在0.0.0.0/0范围内,此时NotIpAddress条件成立,触发Deny规则,导致访问被拒绝。
原因二:对IAM权限模型的误解
IAM的权限判断逻辑是默认拒绝所有操作,只有存在明确的Allow策略时,才会允许对应操作。如果你的IAM用户仅绑定了这条Deny策略,没有任何Allow策略,那么即使这条Deny不触发,也没有允许的规则,最终还是会返回Access Denied。而你移除这条Deny后能正常访问,说明移除后用户有生效的Allow策略(比如继承了组策略、或附加了S3全权限策略)。
2. 真实IP数组策略的问题
你提到用真实IP数组的类似策略也出现相同问题,比如指定自己的IPv4地址后仍被拒绝,可能的原因:
- 填写的IP不是请求的真实源IP:比如你处于公司网络、使用VPN或NAT网关,实际请求S3的公网IP并非你本地的内网IP或你以为的IP地址。可以通过能显示公网IP的服务确认当前访问AWS的真实IP。
- 存在IPv6优先的情况:即使你指定了IPv4地址,客户端仍可能用IPv6发起请求,导致
NotIpAddress条件成立(IPv6不在你指定的IPv4列表里),触发Deny。
3. 修正方案
如果你想实现“仅允许指定IP访问S3,其他IP拒绝”的需求,正确的策略写法应该是用Allow加IP条件(更直接):
{ "Effect": "Allow", "Action": "s3:*", "Resource": "*", "Condition": { "IpAddress": { "aws:SourceIp": [ "你的公网IP/32", "其他允许的IP范围" ] } } }
如果要用Deny兜底,配合Allow策略的写法:
{ "Effect": "Deny", "Action": "s3:*", "Resource": "*", "Condition": { "NotIpAddress": { "aws:SourceIp": [ "你的公网IP/32", "其他允许的IP范围" ] } } }
若需要兼容IPv6,在aws:SourceIp中同时添加IPv6的CIDR范围即可,比如::/0代表所有IPv6地址(如果需要允许所有IPv6的话)。
内容的提问来源于stack exchange,提问作者davewy

