记录一次自建S3服务HEAD请求403的问题

背景

想使用思源笔记的S3同步功能,于是自建了一个S3服务,采用nginx作为反向代理,配置了https安全传输。

搭建完之后基本同步功能都正常,S3作为对象存储,读取、创建、修改、删除文件都没有问题。

直到在思源笔记上查询云端快照时出现了问题,排查nginx日志后发现了403错误。

排查S3服务

403错误,一般是没有权限,但这很快就被排除了。原因是:

  1. 同步功能一直很正常,只有HEAD请求出现了错误。
  2. 由于使用自建的minio对象存储,也只有自己一个人在用,所以权限开的非常大,没有限制存储桶和操作。

思源笔记作为客户端,支持S3协议的服务端。思源笔记官方也采用七牛云存储来作为服务端的,所以大概率客户端没有问题。由于不太了解minio,担心是自己搭建的minio有什么问题,或者哪里没配置对,于是考虑换一个服务端。

接着搭建了一套alist服务,开启了它的S3协议功能,发现依旧如此。同步正常,但查询快照使用的HEAD请求依旧是403 。

排查nginx问题

由于客户端和服务端中间存在一个nginx,那就直接先下掉nginx,看看究竟S3服务有没有问题。使用ip+端口直接访问S3服务端,一切正常,快照也是正常的,HEAD请求也正常了。

在下掉nginx时影响了2个内容:

  1. 没有了nginx反向代理
  2. 没有了https安全协议

为了验证究竟是哪个影响了HEAD请求,又搭建了一个存在nginx但不配置https协议的代理配置。测试结果一切正常,至此可以初步判断是nginx的反向代理对HEAD请求做了一些处理,导致了403的结果。

网上搜索相关问题,发现了这个issues

有人说尝试将proxy_cache_convert_head 设置为off

原因在nginx的反向代理模块参数上也有说明

nginx会默认将HEAD请求转换成GET请求,但是对于S3协议来说,签名中包含请求方法,所以导致了验证不正确,最终返回403 。

设置完 proxy_cache_convert_head之后,再次验证,思源笔记查询快照一切正常。