服务器IP地址是否应该在ALLOWED_HOSTS django设置中?

Nat*_*eri 35 django

自升级到django 1.5以来,我的日志显示了几个SuspiciousOperation例外情况:

Invalid HTTP_HOST header (you may need to set ALLOWED_HOSTS): <my server's ip>
Run Code Online (Sandbox Code Playgroud)

这真的是一个"可疑"的请求,还是我应该总是ALLOWED_HOSTS在我的域名之外的设置中包含我服务器的IP地址?知道什么会提出请求HTTP_HOST = "ip address"而不是HTTP_HOST = "domain name"

这是请求环境:

{'HTTP_ACCEPT_ENCODING': "'identity'",
 'HTTP_CONNECTION': "'close'",
 'HTTP_HOST': "'168.62.208.14'",
 'HTTP_X_FORWARDED_PROTOCOL': "'https'",
 'HTTP_X_REAL_IP': "'176.10.35.241'",
 'HTTP_X_SCHEME': "'https'",
 'PATH_INFO': "u'/'",
 'QUERY_STRING': "''",
 'RAW_URI': "'/'",
 'REMOTE_ADDR': "'127.0.0.1'",
 'REMOTE_PORT': "'45068'",
 'REQUEST_METHOD': "'GET'",
 'SCRIPT_NAME': "u''",
 'SERVER_NAME': "'168.62.208.14'",
 'SERVER_PORT': "'80'",
 'SERVER_PROTOCOL': "'HTTP/1.0'",
 'SERVER_SOFTWARE': "'gunicorn/0.14.6'",
 'gunicorn.socket': "'<socket._socketobject object at 0x7ab3b40>'",
 'wsgi.errors': '"<open file \'<stderr>\', mode \'w\' at 0x7f0c94810270>"',
 'wsgi.file_wrapper': "'<class gunicorn.http.wsgi.FileWrapper at 0x34eec80>'",
 'wsgi.input': "'<gunicorn.http.body.Body object at 0x2a0bf10>'",
 'wsgi.multiprocess': 'False',
 'wsgi.multithread': 'False',
 'wsgi.run_once': 'False',
 'wsgi.url_scheme': "'http'",
 'wsgi.version': '[1, 0]'}
Run Code Online (Sandbox Code Playgroud)

fol*_*lex 19

简短回答是YES(根据提供的标题).

答案很长:根据文件:

如果Host标头(或X-Forwarded-Host,如果启用了USE_X_FORWARDED_HOST)与此列表中的任何值都不匹配,则django.http.HttpRequest.get_host()方法将引发SuspiciousOperation.

换句话说:如果您的请求将您的服务器IP地址作为主机标头传递(显然它们确实如此),并且您认为没关系,那么您应该将服务器IP添加到ALLOWED_HOSTS.

此外,由于许多 原因,IP地址可能在HTTP_HOST中,也有人可以直接询问IP地址.

  • 感谢您的回复 - 听起来我实际上并不想在ALLOWED_HOSTS中使用我的服务器IP.我不认为在其他地方推荐它,我并不特别关心直接支持IP请求(这些请求很少,我的服务器的IP可以改变).我自己似乎能够触发这种类型的请求的唯一方法是访问https:// <server ip>,这不是我想要支持的. (6认同)
  • 好吧,通常你应该将这些请求重定向到你的域名,但是如果你确定所有这些"直接"请求都是无效的 - 忽略它们. (3认同)

Max*_*ysh 13

不,它不应该

默认情况下,没有理由认为IP地址应被接受为有效的HOST头.此消息表明生产环境配置错误:此类请求不应到达后端.

这是关于主机头中毒和ALLOWED_HOSTS的 security.stackexchange.com上的帖子.

该怎么办

在到达django后端之前,使用无效的HOST标头过滤掉所有请求.

如何

很有可能你在nginxdjango面前使用反向代理.如果您根本不使用任何反向代理(或者您正在使用runserver),则必须(否则您将面临安全风险).

添加444在配置顶部返回的默认服务器块.它应该是配置中的第一个服务器块:

# File: /etc/nginx/sites-available/domain.com

upstream django_server {
    server 127.0.0.1:8000;
}

# Catch all requests with an invalid HOST header
server {
    server_name "";
    listen      80;
    return      444;
}

# Your config goes there
server {
    server_name  domain.com;
    listen       80;

    location / {
        proxy_pass http://django_server;
    }
}
Run Code Online (Sandbox Code Playgroud)


And*_*ade 10

实际上,只需编辑文件MyProjectName/settings.py并将主机IP(IP地址添加到运行Django的计算机)添加到列表中ALLOWED_HOSTS,默认情况下该列表为空.

所以,在你的情况下,我们会在变化之前得到:

...
ALLOWED_HOSTS = []
...
Run Code Online (Sandbox Code Playgroud)

改变后:

...
ALLOWED_HOSTS = ['168.62.208.14'] #Make sure your host IP is a string
...
Run Code Online (Sandbox Code Playgroud)

再次运行服务器,你应该很好.以下是使用端口8000的示例:

python manage.py runserver 168.62.208.14:8000

.现在,如果您访问浏览器并输入地址http://168.62.208.14:8000,您应该会在"祝贺您第一个支持Django的页面"页面中找到自己的位置.

  • 感谢您非常明确的答案,没有对我的用例做出任何假设。 (2认同)