Bad Request и Invalid HTTP_HOST header при развертывании NGINX + Gunicorn + Django?

Не могли бы вы, пожалуйста, подсказать, где или как найти решение моего DisallowedHost исключения?

Я развернул свой Django проект на DigitalOcean Ubuntu сервере с помощью Nginx + Gunicorn в соответствии с инструкциями DjangoProject и DigitalOcean, а также ответами на смежные вопросы DjangoForum, StackOverflow и других. Полагаю, я испробовал все советы, которые смог найти, но все еще имею 400 BadRequest ответов и Invalid HTTP_HOST header ошибок.

likarnet - это название моего проекта, а likarnet.com - это мой домен. Я подключил домен likarnet.com к своему публичному IP и SSL-сертификат к своему домену. Версии python 3.12, django 5.0.6

Пожалуйста, извините меня, если я спрашиваю какие-то очевидные вещи. Это мой первый проект.

Файл /etc/nginx/sites-available/likarnet

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name likarnet www.likarnet;

        access_log  /var/log/nginx/access.log;
        error_log  /var/log/nginx/error.log;

        location = /favicon.ico { access_log off; log_not_found off; }
        location /static/ {
            root /home/likarnet/website/likarnet;
        }

        location /media/ {
            root /home/likarnet/website/likarnet;
        }

        location / {
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Host $server_name;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_redirect off;
            proxy_pass http://unix:/run/gunicorn.sock;
        }
}

Я только что попробовал использовать по умолчанию include proxy_params;

Файл /etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=likarnet
Group=sudo
WorkingDirectory=/home/likarnet/website/likarnet
ExecStart=/home/likarnet/venv/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          --chdir=/home/likarnet/website/likarnet \
          likarnet.wsgi:application

[Install]
WantedBy=multi-user.target

Итак, когда я запускаю проект с python3 manage.py runserver 127.0.0.1:8000 или 0.0.0.0:8000 и пробую с другого терминала curl -v localhost:8000, я получаю

* Host localhost:8000 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:8000...
* connect to ::1 port 8000 from ::1 port 59232 failed: Connection refused
*   Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Date: Fri, 21 Jun 2024 21:43:57 GMT
< Server: WSGIServer/0.2 CPython/3.12.3
< Content-Type: text/html; charset=utf-8
< Location: https://localhost:8000/
< X-Content-Type-Options: nosniff
< Referrer-Policy: same-origin
< Cross-Origin-Opener-Policy: same-origin
< Connection: close
< 
* Closing connection

В терминале с проектом у меня появились дополнительные строки Host, ALLOWED_HOSTS, Domain и Port, так как я добавил их печать в функцию get_host() в /venv/lib/python3.12/site-packages/django/http/request.py

Host:  localhost:8000
ALLOWED_HOSTS:  ['likarnet.com', '.likarnet.com', '64.225.77.248', '127.0.0.1', 'localhost']
Domain:  localhost
Port:  8000
[21/Jun/2024 21:51:17] "GET / HTTP/1.1" 301 0

Когда я пытаюсь curl --unix-socket /run/gunicorn.sock localhost, я получаю

<!doctype html>
<html lang="en">
<head>
  <title>Bad Request (400)</title>
</head>
<body>
  <h1>Bad Request (400)</h1><p></p>
</body>
</html>

И я получаю из браузера при вводе likarnet.com

This site can’t be reached
likarnet.com refused to connect.
ERR_CONNECTION_REFUSED

И трассировка ERROR из моего лог-файла. То же самое происходит, когда я использую браузер или команду curl, но с различными именами хостов - localhost, мой публичный IP, likarnet.com или www.likarnet.com

ERROR 2024-06-21 21:51:06,961 /home/likarnet/venv/lib/python3.12/site-packages/django/core/handlers/exception.py  11561  131208492179584 Invalid HTTP_HOST header: 'localhost'. You may need to add 'localhost' to ALLOWED_HOSTS.
Traceback (most recent call last):
  File "/home/likarnet/venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/home/likarnet/venv/lib/python3.12/site-packages/django/utils/deprecation.py", line 133, in __call__
    response = self.process_request(request)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/likarnet/venv/lib/python3.12/site-packages/django/middleware/security.py", line 28, in process_request
    host = self.redirect_host or request.get_host()
                                 ^^^^^^^^^^^^^^^^^^
  File "/home/likarnet/venv/lib/python3.12/site-packages/django/http/request.py", line 151, in get_host
django.core.exceptions.DisallowedHost: Invalid HTTP_HOST header: 'localhost'. You may need to add 'localhost' to ALLOWED_HOSTS.

Я не уверен, какие данные также важны. И я собираюсь добавить все необходимое. Спасибо за помощь и совет.

Ваша ошибка связана с ALLOWED_HOSTS в настройках, потому что в вашем выводе на печать ALLOWED_HOSTS - это [....., ...., 'localhost'], но сообщение об ошибке гласит:

django.core.exceptions.DisallowedHost: Invalid HTTP_HOST header:
localhost'. You may need to add 'localhost' to ALLOWED_HOSTS.

Метод validate_host вызывается в методе get_host, и мы уверены, что 'localhost' существует в ALLOWED_HOSTS, но ошибка все равно возникает!!!

перезапустите службу gunicorn и протестируйте ее. Возможно, вы обновили ALLOWED_HOSTS после запуска службы.

Вернуться на верх