-
Notifications
You must be signed in to change notification settings - Fork 27
Description
问题描述
在使用 Halo S3 插件连接通过 Cloudflare Tunnel 反向代理的 MinIO 服务时,对象存储验证及文件上传操作均失败,报错信息为 403 Forbidden (SignatureDoesNotMatch)。
排查过程
-
使用
aws-cli在相同网络环境下(通过 Cloudflare Tunnel)使用相同的 Access Key 和 Endpoint 进行上传测试,操作成功,排除了网络连通性和 MinIO 权限配置错误的可能。 -
初步推测是反向代理导致的 Host 头不匹配引起签名错误。在 Cloudflare Tunnel 的配置中强制指定正确的
Host头,测试结果依旧为 403 错误。 -
查阅插件源代码
src/main/java/run/halo/s3os/S3OsAttachmentHandler.java,发现在构建 S3 Client 时硬编码关闭了分块编码:// S3OsAttachmentHandler.java 第 227 行左右 .serviceConfiguration(S3Configuration.builder() .chunkedEncodingEnabled(false) // 硬编码为 false .pathStyleAccessEnabled(properties.getEnablePathStyleAccess()) .build())
该配置强制 AWS SDK 在计算签名时包含
Content-Length头。 -
Cloudflare Tunnel(以及常见的流式反向代理)默认会对 HTTP/1.1 回源请求启用
Transfer-Encoding: chunked以优化传输,此过程会移除Content-Length头。如果客户端签名包含了Content-Length,但服务端收到的请求中该头被代理移除并替换为 chunked 编码,则会导致服务端计算签名不匹配,因而返回403错误。后续在 Cloudflare Tunnel 设置中开启 "禁用分块编码",强制代理透传原始Content-Length头后,Halo S3 插件的对象存储验证与上传功能恢复正常。
建议
考虑到现代云原生架构中广泛使用 Cloudflare、Kubernetes Ingress 等反向代理中间件,且中间件修改传输编码属于常见行为,硬编码关闭分块编码限制了插件在复杂网络环境下的兼容性。
建议在 S3 插件的存储策略配置中增加一个 “启用分块传输编码” 的开关选项,默认值为关闭,当用户开启该选项时,将chunkedEncodingEnabled 设置为 true,允许 SDK 使用分块传输并调整签名策略,从而兼容 Cloudflare 等反向代理环境。