Django 错误(外部 IP):无效的 HTTP_HOST 标头:'*.domain.com'

Posted

技术标签:

【中文标题】Django 错误(外部 IP):无效的 HTTP_HOST 标头:\'*.domain.com\'【英文标题】:Django ERROR (EXTERNAL IP): Invalid HTTP_HOST header: '*.domain.com'Django 错误(外部 IP):无效的 HTTP_HOST 标头:'*.domain.com' 【发布时间】:2016-01-10 21:51:18 【问题描述】:

我使用 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)>

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

任何帮助将不胜感激。

【问题讨论】:

我不会使用通配符允许的主机,而是使用真正允许的主机列表,例如 [www.domain.com, domain.com]。还要配置你的 Nginx 以通过 server_name 接受这些请求。 @Jingo 感谢您的帮助和快速响应。我之前添加了域,但遇到了同样的错误,这就是我在其位置添加通配符的原因。奇怪的。我会按照你提到的那样把它放回去,看看我是否仍然遇到这些问题。 我现在删除了通配符允许的主机,但仍然收到此错误?! 你解决了这个问题吗?怎么样? 不,不幸的是我没能修复,但我相信这可能是由我们服务器上运行的内部进程引起的,因为它似乎每天都在同一时间发生:s 【参考方案1】:

而不是在 settings.py 中包含以下内容, ALLOWED_HOSTS = ['*'] (在生产中不是一个好的做法)

关注这个 - 要响应“example.com”和任何子域,请以点开头的域 ALLOWED_HOSTS = ['.example.com', '203.0.113.5']

【讨论】:

【参考方案2】:

ISSUEgunicorn(您的 Django 应用服务器)正在获取无效的主机名。

当向服务器 (NginX) 和 HTTP 主机(或 user agent) 为空,nginx 将 HTTP 主机设置为 gunicorn sock。


解决方案:在您的 nginx conf(nginx.confsites-enabled/&lt;your-site&gt;.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;  

    

【讨论】:

在我的文件中添加这个 proxy_set_header 后,现在我在加载我的主页时收到“400 bad request”, 也收到 400 错误消息。不得不这么快就删除它。 400 是否与在 NGINX 中没有 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 而在 Django 设置中没有 SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') 相关? 哦,亲爱的,这最后一条评论解决了我 10 多个小时的痛苦……【参考方案3】:

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

Host: *.domain.com

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

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

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

【讨论】:

以上是关于Django 错误(外部 IP):无效的 HTTP_HOST 标头:'*.domain.com'的主要内容,如果未能解决你的问题,请参考以下文章

如何禁用 Django 的无效 HTTP_HOST 错误?

Django 错误:无效的 HTTP_HOST 标头:u'/run/myprojectname/gunicorn.sock:'

Django 无效的 http_host

将 django 站点从 http 升级到 https 后,我不断收到“无效的 HTTP_HOST 标头”错误电子邮件

无效的http_host标头

Django 的 SuspiciousOperation 无效的 HTTP_HOST 标头