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 после запуска службы.