【问题标题】:Should server IP address be in ALLOWED_HOSTS django setting?服务器 IP 地址应该在 ALLOWED_HOSTS django 设置中吗?
【发布时间】:2013-05-16 14:13:29
【问题描述】:

自从升级到 django 1.5 后,我的日志显示了几个带有文本的 SuspiciousOperation 异常:

Invalid HTTP_HOST header (you may need to set ALLOWED_HOSTS): <my server's ip>

这是否真的是一个“可疑”请求,或者我是否应该始终在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]'}

【问题讨论】:

  • @yuwang 不同之处在于链接的问题是在这种情况下 HTTP_HOST 是 google.com - 所以它肯定是可疑的。就我而言,HTTP_HOST 是我服务器的实际 IP 地址,所以我不确定它是否是有效请求。
  • 那些是正常有效的请求吗?
  • @KrisKumler 我不太确定这些请求是否有效,这就是我想要弄清楚的。我已包含来自这些请求之一的请求数据。我们所有的有效请求通常都有 HTTP_HOST: 域,但也许有一些原因让客户端通过我不知道的 IP 地址发出请求?
  • 我也看到了同样的情况——我猜是网络爬虫、机器人——它们只是爬取公共 IP 来寻找网站——所以我认为允许他们获取你的网站是可以的——我想应该他们成功了,然后他们将进行反向查找以确定您的域名。

标签: django


【解决方案1】:

不,不应该。

通常这不是配置 Django 服务器的安全方式。有时,例如,在测试您的应用程序时,您可以通过直接 IP 地址访问它,但没有理由禁用日志警告。

我的旧答案是错误的,感谢 Max Malysh 指出这一点。

旧答案(不安全):

简短的回答是:是(根据提供的标题)。

长答案: 根据documentation

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

换句话说:如果您的请求将您的服务器 ip 地址作为 Host 标头传递(显然他们确实这样做了),并且您认为没问题,那么是的,您应该将服务器 ip 添加到 ALLOWED_HOSTS。

另外manyreasons的IP地址可以在HTTP_HOST中,也可以直接要求IP地址。

【讨论】:

  • 感谢您的回复 - 听起来我实际上并不希望我的服务器 IP 在 ALLOWED_HOSTS 中。我没有看到它在其他任何地方被推荐,而且我并不特别关心直接支持对 IP 的请求(这些请求不常见,而且我的服务器的 IP 可以更改)。我自己似乎可以触发此类请求的唯一方法是转到 https://,这不是我想要支持的。
  • 好吧,通常你应该将这些请求重定向到你的域名,但如果你真的确定所有这些“直接”请求都是无效的——忽略它们。
  • 我不确定我是否同意。在具有 ELB 对特定 docker 实例的健康检查的 ECS 中,请求将直接到达该容器的 IP 地址。 AFAICT,没有其他方法可以检查特定实例的运行状况。
【解决方案2】:

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

因此,在您的情况下,我们将在更改之前:

...
ALLOWED_HOSTS = []
...

改动后:

...
ALLOWED_HOSTS = ['168.62.208.14'] #Make sure your host IP is a string
...

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

python manage.py runserver 168.62.208.14:8000

。现在,如果您转到浏览器并输入地址 http://168.62.208.14:8000,您应该会发现自己在“恭喜您的第一个 Django 驱动的页面”页面。

【讨论】:

  • 感谢您提供的非常明确的答案,没有对我的用例做出任何假设。
  • 在生产服务器上最好关注 Max Malysh 的answer
【解决方案3】:

不,不应该

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

这是Host header poisoning & ALLOWED_HOSTS@security.stackexchange.com 上的帖子。

做什么

在到达 django 后端之前过滤掉所有带有无效 HOST 标头的请求。

如何

您很可能在 django 前面使用 nginx 作为反向代理。如果您根本不使用任何反向代理(或者您使用的是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;
    }
}

【讨论】:

    猜你喜欢
    • 2021-02-17
    • 2013-11-05
    • 2014-08-23
    • 2012-12-21
    • 2011-08-17
    • 1970-01-01
    • 2018-04-26
    • 2015-03-27
    • 1970-01-01
    相关资源
    最近更新 更多