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

时间:2017-01-27 03:00:44

标签: django unix nginx proxy gunicorn

我有一个以这种方式设置的站点: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在接收请求时,会将Host标头与服务器块的server_name参数进行匹配,如果匹配,则为其提供服务。但是,nginx似乎试图使用与api.mysite.com不同的Host标头服务(将请求传递给我的Django服务器)请求。 Django有一个名为ALLOWED_HOSTS的设置(在我的情况下设置为['api.mysite.com']),它执行进一步检查Host标头,如果请求Host标头没有,则会引发错误匹配,这不应该发生,因为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 / nignx UNIX套接字的本地文件系统上的路径的请求。

有任何线索吗?

1 个答案:

答案 0 :(得分:1)

事实证明,如果nginx没有遇到匹配的服务器块,它会将请求发送到第一个服务器块。所以解决方案是设置一个默认的服务器块,它会丢弃这样的每个请求:

server {
    listen 80 default_server;
    return 444;
}