713 字
4 分钟
反向代理下 Minio 无法 HeadObject 问题检查

问题描述#

这两天自己部署了一台 MinIO 的服务器,用来提供 S3 的存储相关 API。 (这主要得益于 Alist 的相关性能并不算优秀才用的 Minio。 但是,在于 Directus 进行整合的时候,出现了内部服服务错误。

于此同时,在使用 RClone 进行文件上传的时候,也出现了 Head Object 时,返回 403 的错误。

Head Object 是什么#

Head Object 是 S3 的 API 之一,用于获取对象的元数据,而不需要实际下载对象的内容。

相比于 Get Object 而言,Head Object 的请求头中不包含对象的内容,仅仅只通过一个 HTTP HEAD 请求,就能拿到部分文件内容和基础数据。

与 Get Object 相比,传输量更少,很多时候会被一些 S3 服务用来先期判断文件是否存在,或者上传之后校验文件使用。

问题排查#

一开始曾经怀疑是 Minio 的权限配置存在错误。但是一番调查后发现,即便使用最高权限账户 ConsoleAdmin,且 ACL 全部配置为允许,依然会出现 403 的错误。

网上一番搜索过后,所有的内容都在说 Cloudflare 的缓存策略存在问题。

但是,我的服务中并没有使用任何 Cloudflare 对 S3 服务进行代理。(法律上将,很多人都提到,Cloudflare 代理对象存储是违反 TOS 的)。

同时,我又将服务换成了 Garage 来进行处理 S3 内容,但是问题却消失了……

但这并不是最优解,主要原因在于 Garage 的 Bug 也太多了。

问题解决#

考虑到问题仅仅出现在 HeadObject,而网上并没有针对 Minio 的反馈,那么问题应该就是出现在反向代理上。

在百般折磨后,终于在 1panel 的官方 GitHub 中找到了相关的 Issue。

[QUESTION]OpenResty反代MinIO的API端口无法进行上传等操作 · Issue #3924 · 1Panel-dev/1Panel
请描述您的问题 使用S3 Browser以及Halo的S3服务时,MinIO的API端口反代的域名无法进行上传等操作,但是源站IP+端口的方式一切正常。 1、服务器版本 发行版本 ubuntu-22.04 内核版本 5.15.0-76-generic 系统类型 x86_64 2、环境版本 OpenResty版本 1.21.4.3-0-focal MinIO版本 2023-01-05
[QUESTION]OpenResty反代MinIO的API端口无法进行上传等操作 · Issue #3924 · 1Panel-dev/1Panel favicon https://github.com/1Panel-dev/1Panel/issues/3924
[QUESTION]OpenResty反代MinIO的API端口无法进行上传等操作 · Issue #3924 · 1Panel-dev/1Panel

里面提供了一个解决方法:

proxy_cache_convert_head off;

就这么简单的一行语句即可解决问题。

了解 proxy_cache_convert_head#

调查后发现,1panel 默认配置的 OpenResty 中,做了于 Cloudflare 一样的事情:

将 HEAD 请求转换为 GET 请求并进行缓存

当然我们不是说这个策略是错误的,只是在 S3 的场景下,这个策略是有问题的。

这与 S3 的签名设计有关。

为了防止非法请求, S3 相关的请求,均需要携带内容签名。

签名的一个大概流程可以参考下图:

S3 签名流程

从图中可以看到,签名中需要同时包含 HTTP 的请求方法,请求路径,请求头,参数等等。

这就导致一个问题,Nginx 提供的 proxy_cache_convert_head 策略,会将 HEAD 请求转换为 GET 请求,导致签名无法匹配。

最后 Minio 只能返回一个 Access Denied 的错误。

反向代理下 Minio 无法 HeadObject 问题检查
https://23h.at/posts/反向代理下-minio-无法-headobject-问题检查/
作者
Hyprocritor
发布于
2024-12-30
许可协议
CC BY-NC-SA 4.0