I am trying to configure nginx along with Gunicorn for a Django project. nginx is giving me the following error:
DisallowedHost at /
Invalid HTTP_HOST header: 'localhost:90,localhost:90'. The domain name provided is not valid according to RFC 1034/1035.
This is my nginx configuration
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 is serving the site properly at localhost:8200. Can anyone tell me what is causing the error?
I was getting the same error. I'm guessing you might be coming from Flask converting to Django? If you remove the proxy_set_header Host $http_host; line from your configuration, it should work (it fixed my error). I think what that does is stack together both the requesting ip address, and the proxy ip address, while Django only wants a single ip address, not a list. See this Django ticket: https://code.djangoproject.com/ticket/28028
I'm guessing you already got this figured out (since its been a few months), but I'm still answering to save someone the 2 hours I just spent googling :)
edit: I'd like to clarify, the problem comes from having both include proxy_params; and proxy_set_header Host $http_host; set. The default proxy_params already have the proxy_set_header Host $http_host; included, so it'll set the host twice, hence the list of two hosts. Look at the proxy_params file in /etc/nginx/proxy_params if you're on Ubuntu (will be a similar path on other machines).
I came across a similar issue with docker because I'm trying to call a django service from another container.
Ended up doing a monkey patch in settings.py since all this method does is actually check / match the domain. Could be a security issue, do at your own risk.
# monkey patch to get rid of message below in docker
from django.http.request import HttpRequest
HttpRequest.get_host = HttpRequest._get_raw_host
I had this problem, too, and discovered that Django actually has a reference to it, buried obscurely in its docs.
The solution is to implement a custom middleware, though in my case I had to modify the middleware suggested in the docs. Here is my modified middleware, and the line in settings.py where I added it:
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',
]