Nginx 代理 Minio 出现 Access not allowed! 403 Forbidden、Minio新增加桶并添加访问权限控制、浏览器向minio上传文件报错

    对于一般的公司,使用开源对象存储系统搭建自己的文件对象服务器是一个非常优选的方案,MinIO 是一个高性能、S3 兼容的对象存储。且可以免费使用,它是专门为大规模 AI/ML、数据湖和数据库工作负载而构建的,是由软件定义的存储。客户根本不需要购买任何专有的硬件服务器,只需要在一般的服务器上进行部署,就可以在云上和普通硬件上拥有分布式对象存储系统服务。非常推荐。

    不过在使用Minio 的时候也经常会遇到 一些问题,比如其自身的WEB服务器脆弱问题;权限配置麻烦的问题(这个在最新版的MINIO上进行了优化);还有接口调用中也免不了碰到一些问题,我这里列出了三个我遇到的问题,并展示了解决方法。如下:

一、Nginx 代理 Minio 出现 Access not allowed! 403 Forbidden 问题处理

        因为业务安全需要,直接使用minio的WEB端进行漏洞扫描的时候发现有很多的要修复漏洞,因为缺少nginx里面的很多头信息。所以计划在 Minio 的前面 使用了 Nginx 进行代理,但这样操作之后发现问题,业务在进行文件上传至 Minio 前是需要先调用 presigned_put_object 接口生成签名的 URL 地址的,但通过代理后生成的URL地址进行文件上传。接口请求时发现服务器端返回:403 Forbidden, 完整内容如下:

HTTP/1.1 403 Forbidden

Access not allowed!

    调试发现,minio client 在执行 presigned_put_object 方法的时候,会向 minio 发送一个 GET /bucket_name?location= 的方法,此时nginx 响应了403。如下:

"GET /bucket_name?location= HTTP/1.1" 403 369 "-" "MinIO (Linux; x86_64) minio-py/7.0.2" "-" 

在 MinIO 的python 模块中 api.py 里也可以看到执行了这个方法:

# Execute GetBucketLocation REST API to get region of the bucket.
response = self._url_open(
            "GET",
            "us-east-1",
            bucket_name=bucket_name,
 query_params={"location": ""},
        )

        于是将 nginx 代理进行了开启关闭尝试,发现不使用 nginx 代理,能正常调用,使用了nginx 代理就会返回这个错误。所以问题点也就明确了,出在nginx 代理的 proxy_set_header 配置上。最后排查发现问题出在下面这行上,正确应该使用 proxy_set_header Host $http_host; 而不能使用 proxy_set_header Host $host; 原因是 $host 参数不包含端口号数据,会导致请求头部 Host 中的端口丢失从而使后端程序不能正确处理。而 $http_host 则包含 IP地址和端口号。

        host变量表示客户端请求的主机名,不包括端口号。如果客户端请求的URL中没有指定主机名,则 host 变量的值为 Nginx 服务器的 IP 地址或主机名。

        http_host变量表示客户端请求的主机名,包括口号。如果客户端请求的URL中没有指定主机名,则 http_host 变量的值为 Nginx 服务器的 IP 地址或主机名。

location / {
 # 最后发现问题出在下面这行上,正确应该使用上面这行,而不能使用下面这行。
 proxy_set_header Host $http_host;
 proxy_set_header Host $host;
 
 proxy_pass http://192.168.12.23:9000;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 }

        虽然当下问题已解决,不过也让我产生一个疑问,在 nginx 使用$host代理时,我在浏览器访问 minio 的时候也没有报过错,各项请求也正常的。看来 minio 的 python 扩展模块中的请求方法会有所特殊。

二、Minio新增加桶并添加访问权限控制的方法

     之前也有相关的文章进行过记录,最近有过几次增加新桶然后对桶添加访问权限控制的操作,进行了一些整理,在此做个记录。

1. 列出所有的桶并添加对应的bucket桶

mc ls local  #列出所有桶
mc mb local/test-bucket  #添加对应桶
mc ls local  #查看添加后的桶是否在列表中

2. 修改已有的策略文件,将新加的桶名加入

cd /root/.mc
vim test.json
#修改Resource中添加对应的bucket
#"arn:aws:s3:::test-bucket/*",

3.更新原已有的策略

mc admin policy add local test test.json

4.对新加的桶设置永久下载权限

mc policy set download local/test-bucket

5.如果需要删除桶

mc rm --recursive --force  local/test-bucket
#删除一个存储桶并递归删除里面所有的内容。由于这个操作太危险了,你必须传--force参数指定强制删除,并添加--recursive进行递归。
Copymc rm --recursive --force play/myobject

6.查看当前已有的策略列表

mc admin policy list local/

7.查看具体策略详情,以知道策略应用的是哪个.json文件

mc admin policy info local 策略名

三、浏览器向minio上传文件报错PUT net::ERR_CONNECTION_RESET 

      通过浏览器进入 minio 的管理后台,可以直接upload文件至对象存储中,但有时会遇到PUT ..filename... net::ERR_CONNECTION_RESET 报错。错误的原因可能有多样,比如有可能是服务器限制了文件上传的权限,或者上传大小受到了限制。

    网上能找到各种各样的原因,不过我遇到的情况例外,是因为公司对互联网入口作了限制,限制了 put 协议请求以及websocket协议等,导致Minio文件PUT协议上传报错

net::ERR_CONNECTION_RESET

    以及EMQ中使用websocket协议报错连续失败。我这里和本身服务器本身无关(不需要在业务服务器上进行配置),是通过公司IT中心对互联网网络进出口进行了放开处理,在这里作个记录。