Nginx 反向代理 MinIO:解决 400 Bad Request

前言

当我们在构建个人博客或网站时,为了提高资源访问的速度和稳定性,经常会使用对象存储服务,如 MinIO,来存储静态资源,例如图片。而为了让网站看起来更加专业和美观,我们通常不希望用户直接看到后端存储的地址和端口,这时就可以利用 Nginx 进行反向代理,隐藏真实的后端服务地址。

问题描述

在尝试使用 Nginx 反向代理 MinIO 时,遇到了一个问题:虽然代理配置能成功访问 MinIO,但尝试访问存储在其中的图片时会收到一个 400 Bad Request: malformed Host header 的错误。

初步的配置如下:

server {
	listen 80;
	server_name image.laodengtou.com;
	location / {
		proxy_pass http://localhost:9001;
		proxy_set_header Host \$host;
		proxy_set_header X-Real-IP \$remote_addr;
	}
}

解决方案

经过一系列的测试和尝试,以下是一个工作正常的配置:

server {
    listen 80;
    server_name your_domain.com;

    location / {
        proxy_pass http://localhost:9001/;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        rewrite ^/(.*)$ /$1 break;
    }
}

对比这两个配置,可以看到以下几点差异:

  1. proxy_set_header Host:在原始配置中,使用了 \$host,这可能导致了“Host”头部的错误解析。而在工作的配置中,使用 $http_host 可以确保 HTTP 请求头中的 Host 信息被正确传递给 MinIO。
  2. proxy_set_header X-Forwarded-For:此头用于传递原始请求的 IP 地址,有时对于某些应用来说这是必要的。
  3. rewrite:通过使用重写规则,可以确保请求的 URL 路径不会被错误地解释或修改。

效果展示

修改前

修改后

总结

Nginx 的反向代理功能强大,但在配置时需要注意一些细节,特别是当后端服务对请求头有特定要求时。对于 MinIO 这样的对象存储服务,确保传递正确的 Host 信息是关键。如果你有其他相关的经验或知识,欢迎在评论区分享!