为什么 nginx 接受 Host 标头与 server_name 不匹配的请求?

2024-05-01

我有一个这样设置的站点:nginx 作为代理服务器,通过 UNIX 套接字代理为 Django 站点提供服务的 Gunicorn 实例的请求。

这是我的 nginx 配置:

server {
    listen 80;
    server_name api.mysite.com;

    location /static/ {
        alias /webapps/mysite/static/;
        autoindex off;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/webapps/mysite/mysite.sock;
    }

}

我的理解是nginx在收到请求时会匹配Hostheader 与服务器块的 server_name 参数相匹配,如果匹配,则为其提供服务。然而,nginx 似乎正在尝试使用以下命令来服务(将请求传递到我的 Django 服务器)请求:Host标头与 api.mysite.com 不同。 Django 有一个名为ALLOWED_HOSTS(在我的例子中设置为['api.mysite.com'])执行进一步检查Host标头并在请求时引发错误Hostheader 不匹配,这不应该发生,因为 nginx 应该已经过滤了这个。问题是我看到 Django 引发的错误如下所示:

  • 无效的 HTTP_HOST 标头:'/webapps/mysite/mysite.sock:'。根据 RFC 1034/1035,提供的域名无效。
  • 无效的 HTTP_HOST 标头:'testp1.piwo.pila.pl'。您可能需要将“testp1.piwo.pila.pl”添加到 ALLOWED_HOSTS。
  • 无效的 HTTP_HOST 标头:'xxx.xxx.xxx.xxx' (我服务器的真实IP)。您可能需要将“xxx.xxx.xxx.xxx”添加到 ALLOWED_HOSTS。

有几件事:

  • 我知道请求是通过 nginx 发出的,因为它们显示在 nginx 日志中,并且无论如何都不可能直接访问 Gunicorn 服务器,因为我是通过 UNIX 套接字而不是通过 HTTP 进行代理。
  • 我知道这些请求来自寻找免费代理使用的机器人,但我不太关心这一点。我真正感兴趣的是Host标头设置为我的gunicorn/nginx UNIX套接字的本地文件系统上的路径。

有什么线索吗?


事实证明,如果 nginx 没有遇到匹配的服务器块,它会将请求发送到第一个服务器块。因此,解决方案是设置一个默认服务器块来删除每个请求,如下所示:

server {
    listen 80 default_server;
    return 444;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 nginx 接受 Host 标头与 server_name 不匹配的请求? 的相关文章

随机推荐