23

我已经使用 Nginx、Gunicorn、Django 堆栈创建了一个 Django (1.7) Web 应用程序,最近我开始遇到一些错误:

[Django] 错误(外部 IP):无效的 HTTP_HOST 标头:'*.domain.com'。根据 RFC 1034/1035,提供的域名无效。

搜索后,我发现了几个建议将通配符作为允许的主机的响应,即

ALLOWED_HOSTS = ['*']

但是我仍然收到此错误。

这是完整的错误消息:

Request repr(): 
<WSGIRequest
path:/,
GET:<QueryDict: {}>,
POST:<QueryDict: {}>,
COOKIES:{},
META:{'HTTP_ACCEPT_ENCODING': 'none',
'HTTP_CONNECTION': 'close',
'HTTP_HOST': '*.domain.com',
'HTTP_USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.2)',
'HTTP_X_FORWARDED_FOR': '11.111.111.11',
'HTTP_X_FORWARDED_HOST': 'subdomain.domain.com',
'HTTP_X_REAL_IP': '11.111.111.11',
'PATH_INFO': u'/',
'QUERY_STRING': '',
'RAW_URI': '/',
'REMOTE_ADDR': '127.0.0.1',
'REMOTE_PORT': '51349',
'REQUEST_METHOD': 'GET',
'SCRIPT_NAME': u'',
'SERVER_NAME': '127.0.0.1',
'SERVER_PORT': '9000',
'SERVER_PROTOCOL': 'HTTP/1.0',
'SERVER_SOFTWARE': 'gunicorn/19.1.1',
'gunicorn.socket': <socket._socketobject object at 0x3877fa0>,
'wsgi.errors': <gunicorn.http.wsgi.WSGIErrorsWraper object at 0x37e6050>,
'wsgi.file_wrapper': <class 'gunicorn.http.wsgi.FileWrapper'>,
'wsgi.input': <gunicorn.http.body.Body object at 0x396cc50>,
'wsgi.multiprocess': False,
'wsgi.multithread': False,
'wsgi.run_once': False,
'wsgi.url_scheme': 'http',
'wsgi.version': (1, 0)}>

这是我应该关心的事情吗?我在这里错过了什么吗?我认为通过将通配符放在允许的主机中,我会消除这个问题,但似乎并非如此。

任何帮助将非常感激。

4

3 回答 3

11

ISSUE:(gunicorn您的 Django 应用程序服务器)正在获取无效的主机名。

当向服务器(NginX)发出请求并且 HTTP 主机(或用户代理)为空时,nginx 将 HTTP 主机设置为 gunicorn sock。


解决方案:在您的 nginx conf(nginx.confsites-enabled/<your-site>.conf)中添加/更新指令:

proxy_set_header Host $http_host;

to(如果您没有设置,只需添加以下内容),

proxy_set_header Host $host;

可以把它放在指令location上方的 ,里面:proxy_pass

server {
    listen 8000;
    server_name 0.0.0.0;

    location / {
            proxy_set_header Host $host;
            include proxy_params;
            proxy_pass http://unix:/<your-path>/yourproject.sock;  

    }
}
于 2018-02-23T10:18:57.700 回答
4

向您的服务器发出请求的客户端已发送以下 HTTPHost标头:

Host: *.domain.com

根据 HTTP 规范,这是无效的 -*标头中不允许出现 - 因此 Django 以 HTTP 400 响应响应并记录错误。

这与您在ALLOWED_HOSTS设置中放置的内容无关,在哪里*被允许并告诉 Django 接受对任何(有效)主机名的请求(它仍然会拒绝无效的主机名,如*.domain.com)。

然而,正如其他人在评论中指出的那样,您应该真正将 nginx 配置为仅接受特定主机的连接(server_name),这样此类请求甚至不会到达 Django。

于 2016-04-17T04:43:15.980 回答
-2

而不是在settings.py中遵循, ALLOWED_HOSTS = ['*'] (在生产中不是一个好习惯)

遵循此 - 要响应“example.com”和任何子域,请以点开头的域 ALLOWED_HOSTS = ['.example.com', '203.0.113.5']

于 2020-06-24T07:40:24.510 回答