未配代理时aws s3 ls正常但aws s3 cp报403错误的原因
问题描述
客户向我方共享了一个S3存储桶,执行如下列举对象的命令可正常运行:
AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... aws s3 ls s3://bucket/company4/obj1
但执行下载操作时返回403错误,对应执行命令如下:
AWS_ACCESS_KEY_ID=... AWS_SECRET_ACCESS_KEY=... aws s3 cp s3://bucket/company4/obj1 .
报错信息:
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
经排查,该问题由未配置代理导致,执行export http_proxy=...配置代理后cp命令即可正常运行。疑问点:为何aws s3 ls命令无需配置代理即可正常执行?
原因解答
核心差异来自两个命令的请求寻址规则、访问端点不同,刚好命中了内网的访问控制策略:
- 两类命令调用的S3接口、默认寻址模式存在区别:
aws s3 ls调用的是ListObjects/ListObjectsV2列举接口,旧版本AWS CLI对这类列举请求默认使用路径风格寻址:请求直接发往对应区域的S3固定根端点,Host头为s3.<region>.amazonaws.com,存储桶名放在URL路径段中。这类固定域名的S3基础管控请求,通常会被企业内网出口策略放通,直连就能正常响应。aws s3 cp下载对象前必须先调用HeadObject接口获取对象元数据(也就是报错信息里提到的失败调用),后续拉取文件内容还要调用GetObject接口,这两个接口默认使用虚拟托管风格寻址:请求的Host头为<bucket-name>.s3.<region>.amazonaws.com,存储桶名作为子域名前缀拼接在S3根域名前。
- 内网拦截规则导致直连行为差异:所在网络的内网DNS、出口防火墙没有放通所有S3动态子域名的直连权限,未配置代理时,访问带桶名前缀的S3子域名请求会被内网网关拦截,网关直接返回403 Forbidden响应,被AWS CLI误判为S3服务端返回的权限错误。而ls命令访问的固定S3根端点在直连放通列表里,所以不需要代理就能正常执行。
- 配置代理后,所有S3请求都通过代理出口访问,绕过了内网网关对S3子域名的拦截,因此cp命令可以正常运行。
内容的提问来源于stack exchange,提问作者ca9163d9
相关产品推荐
相关产品推荐

