8

I am getting Invalid HTTP_HOST header error on my server. I don't understand why it's happening and how to fix it. Everytime it happens backend stops working and I have to restart the server.

Any help will be appreciated.

Thanks in advance!

FYI : Server is aws ec2; frontend is angular and backend is django/drf with gunicorn. Angular and DRF are both deployed on the same server.

Error 0. If I don't set the Host variable in nginx.conf, I get below error many times. Invalid HTTP_HOST header: '/run/gunicorn.sock:'. The domain name provided is not valid according to RFC 1034/1035.

If I set the Host variable in nginx.conf, I get below errors.

Error 1. proxy_set_header Host $http_host;

Invalid HTTP_HOST header: '127.0.0.1:8000,127.0.0.1:8000'. The domain name provided is not valid according to RFC 1034/1035.

Error 2. proxy_set_header Host $host;

Invalid HTTP_HOST header: '127.0.0.1:8000,127.0.0.1'. The domain name provided is not valid according to RFC 1034/1035.

Error 3. proxy_set_header Host $server_name;

Invalid HTTP_HOST header: '13.234.187.18,13.234.187.18:8000'. The domain name provided is not valid according to RFC 1034/1035.

nginx.conf is as below.

server {
    listen 8000;
    server_name 13.234.187.18;

    location / {
        proxy_set_header Host $host;
        include proxy_params;

        proxy_pass http://unix:/run/gunicorn.sock;
    }
}

I found below code on the nginx website. Will it solve this problem? http://nginx.org/en/docs/http/request_processing.html

server {
    listen      80;
    server_name "";
    return      444;
}
Chetan Ganji
  • 83
  • 1
  • 1
  • 3
  • The UNIX socket name must be enclosed in colons. Try `http://unix:/run.gunicorn.sock:`. – berndbausch Jan 16 '21 at 09:58
  • 1
    Regarding $host and $http_host, I speculate that the error might come from a malformed host header in the HTTP request. – berndbausch Jan 16 '21 at 10:08
  • Please share the output of `nginx -T`. – Tero Kilkanen Jan 16 '21 at 13:26
  • 1
    `server_name ` form of directive is wrong. If you need this virtualhost to listen only on single IP, add corresponding `listen` directive. If it needs to be catch-all which responds to any Host value, make it default_server and use `server_name _`. – Nikita Kipriyanov Jan 16 '21 at 15:40

2 Answers2

6

The problem is that you have caused the Host header to be included twice.

        proxy_set_header Host $host;
        include proxy_params;

Looking at the proxy_params file will show you that it was already set there. Setting it again causes the two values to be joined with a comma.

Inside that file you will find preset headers that will be used when you include that file. You do not need to repeat any of those lines in your own configuration.

ubuntu@vmtest-ubuntu2004:~$ cat /etc/nginx/proxy_params
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

You can remove your own additional proxy_set_header Host $host; from the configuration.

Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
2

I had a similar issue, however, I didn't have proxy_set_header in my Nginx config file and it was simply include proxy_params;.

What happens here is according to Django documentation when your site is behind a proxy server, Django will reject the requests coming from the proxy thinking they are not secure even though the connection between the client and the proxy might be secure. So the solution is to update your Django settings.py file and add the following:

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

You can read further here about this issue here: https://docs.djangoproject.com/en/3.1/ref/settings/#secure-proxy-ssl-header