AWS Athena查询S3存储的Nginx日志报403 Access Denied的修复
Athena查询S3日志报403 Access Denied修复方案
核心原因说明
你遇到的Access Denied错误不是单一配置问题,是Athena访问S3的两层权限校验、路径匹配环节出现错配导致的,你之前配置的S3桶策略本身存在多处硬伤,是问题长期未解决的核心原因。
你现有S3策略的硬伤
你当前配置的桶策略存在4个会直接导致权限失效的问题:
- 策略版本使用了老旧的
2008-10-17语法,这类旧语法在部分S3权限校验场景下不会被识别生效,需替换为官方推荐的2012-10-17版本 Principal设置为*(代表所有匿名公共用户),会直接触发S3默认开启的*阻止公共访问(Block Public Access)*规则,S3会强制拦截该策略下的所有Allow授权,哪怕语法正确也不会生效- 把
ListBucket操作绑定到了my-bucket/*的对象路径资源上,这个操作的合法授权资源只能是桶本身(即arn:aws:s3:::my-bucket),绑定到对象路径的权限属于无效配置 - 授权范围和实际日志路径不匹配,从报错信息看你的表LOCATION指向了ALB日志的存储路径,但你实际存储的是Nginx日志,路径不一致会进一步放大权限校验的问题
分步修复操作
1. 修正源日志桶的桶策略
需要把策略调整为同账户的定向授权,不要做公共开放:
- 移除
Principal: *的配置,将授权对象限定为你登录Athena控制台时使用的IAM用户/角色,避免触发公共访问拦截规则 - 修正操作和资源的匹配关系:
ListBucket操作只绑定桶本身的ARN,读对象的操作绑定桶下所有对象的ARN - 可以通过Condition条件限定允许访问的日志前缀路径,缩小权限范围
参考的正确策略结构:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::你的12位账户ID:user/你登录Athena使用的IAM用户名" }, "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::你的Nginx日志存储桶", "arn:aws:s3:::你的Nginx日志存储桶/*" ], "Condition": { "StringLike": { "s3:prefix": [ "你在Athena表中配置的日志父路径/*" ] } } } ] }
调整完成后,确认桶的公共访问拦截规则没有拦截同账户的授权——S3的公共访问规则只会拦截面向匿名/跨账户的开放授权,同账户内的IAM身份授权不受该规则影响。
2. 补全IAM身份的权限缺口
你之前仅配置了桶策略,容易遗漏IAM侧的权限校验要求,登录Athena使用的IAM用户/角色需要具备三类权限:
- 源日志桶的读权限:允许执行
s3:GetObject、s3:ListBucket操作,资源范围覆盖你的Nginx日志存储桶和对应路径下的所有对象 - Athena查询结果输出桶的读写权限:允许执行
s3:PutObject、s3:GetBucketLocation、s3:ListBucketMultipartUploads操作,授权Athena把查询结果写入指定的输出桶,这部分权限缺失是高频的403触发点,很多用户仅配置了源日志桶权限,忘记给结果桶授权 - 元数据访问权限:允许访问Glue数据目录的库、表元数据,保障Athena能正确加载表结构
3. 校验S3路径匹配关系
从报错信息看,你配置的表LOCATION指向了ALB日志的专属路径s3://your-alb-logs-directory/AWSLogs/xxxx/elasticloadbalancing/eu-central-1,但你实际存储的是Nginx日志,路径完全不匹配。
需要注意:S3对无权访问的不存在路径,不会返回“路径不存在”的提示,而是统一返回Access Denied,避免泄露桶内的路径结构。你可以先执行最简单的测试SQL验证:
SELECT * FROM alb_logs LIMIT 10
如果查询依然报403,就去Athena的表详情页核对LOCATION字段的S3路径,和你Nginx日志实际存储的路径保持完全一致,避免多写、少写路径层级。
内容的提问来源于stack exchange,提问作者Mathias Lund
相关产品推荐
相关产品推荐

