无效的HTTP_HOST标头:' localhost:90,localhost:90'。根据RFC 1034/1035,提供的域名无效

时间:2017-05-03 13:32:57

标签: django nginx gunicorn

我正在尝试将nginx与Gunicorn一起配置为Django项目。 nginx给了我以下错误:

DisallowedHost at /
Invalid HTTP_HOST header: 'localhost:90,localhost:90'. The domain name provided is not valid according to RFC 1034/1035.

这是我的nginx配置

    server {

        listen 90;
        listen [::]:90;

        server_name xxxx;

        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
            root /home/user/djangopro/djangoapp;
        }

        location / {
            include proxy_params;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_buffering off;
            proxy_redirect off;

            proxy_pass http://localhost:8200/;
        }
    }

Gunicorn正在localhost:8200正确地为该网站提供服务。谁能告诉我导致错误的原因是什么?

3 个答案:

答案 0 :(得分:1)

我得到了同样的错误。我猜你可能会来自Flask转换为Djano?如果从配置中删除proxy_set_header Host $http_host;行,它应该可以工作(它修复了我的错误)。我认为它的作用是将请求IP地址和代理IP地址堆叠在一起,而django只需要一个ip地址,而不是列表。看到这张Djano门票:https://code.djangoproject.com/ticket/28028

我猜你已经弄明白了(因为已经过了几个月),但是我仍然在回答拯救某人我花了两个小时谷歌搜索:)

编辑:我想澄清一下,问题来自同时设置include proxy_params;proxy_set_header Host $http_host;。默认proxy_params已包含proxy_set_header Host $http_host;,因此它会将主机设置两次,因此列出两个主机。如果您在Ubuntu上(在其他计算机上将是类似的路径),请查看proxy_params中的/etc/nginx/proxy_params文件。

答案 1 :(得分:0)

我在使用 docker 时遇到了类似的问题,因为我试图从另一个容器调用 django 服务。

最终在 settings.py 中做了一个猴子补丁,因为这个方法实际上只是检查/匹配域。可能是安全问题,风险自负。

# monkey patch to get rid of message below in docker
from django.http.request import HttpRequest
HttpRequest.get_host = HttpRequest._get_raw_host

答案 2 :(得分:0)

我也遇到了这个问题,发现 Django 实际上有一个对它的引用,buried obscurely in its docs

解决方案是实现自定义中间件,但在我的情况下,我必须修改文档中建议的中间件。这是我修改后的中间件,以及 settings.py 中我添加它的行:

custom.middleware.py:

class MultipleProxyMiddleware:
   FORWARDED_FOR_FIELDS = [
    'HTTP_X_FORWARDED_FOR',
    'HTTP_X_FORWARDED_HOST',
    'HTTP_X_FORWARDED_SERVER',
    'HTTP_HOST' <=== I ADDED THIS LINE
]

def __init__(self, get_response):
    self.get_response = get_response

def __call__(self, request):
    """
    Rewrites the proxy headers so that only the most
    recent proxy is used.
    """
    for field in self.FORWARDED_FOR_FIELDS:
        if field in request.META:
            if ',' in request.META[field]:
                parts = request.META[field].split(',')
                request.META[field] = parts[-1].strip()
    return self.get_response(request)

settings.py:

MIDDLEWARE = [
'my.apps.custom.middleware.MultipleProxyMiddleware', <=== I added this line
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'axes.middleware.AxesMiddleware',
]