如何禁用Django的无效HTTP_HOST错误?

Nat*_*man 46 django logging http-host

自从我部署了一个运行Django 1.7 alpha的站点(从Git检出)后,我偶尔会收到错误消息,标题如下:

"HTTP_HOST标头无效:'xxx.xxx.com'"

我意识到这是由于Host:HTTP标头被设置为未列出的主机名ALLOWED_HOSTS.但是,我无法控制某人使用伪造主机名向服务器发送请求的时间和频率.因此,我不需要一堆错误电子邮件让我知道其他人正试图做一些可疑的事情.

有没有办法禁用此错误消息?项目的日志记录设置如下所示:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*vin 54

你不应该忽视这个错误.相反,你应该在它到达你的Django后端之前拒绝请求.要拒绝没有HOST设置的请求,您可以使用

SetEnvIfNoCase Host .+ VALID_HOST
Order Deny,Allow
Deny from All
Allow from env=VALID_HOST
Run Code Online (Sandbox Code Playgroud)

或强制匹配到特定域(example.com)

SetEnvIfNoCase Host example\.com VALID_HOST
Order Deny,Allow
Deny from All
Allow from env=VALID_HOST
Run Code Online (Sandbox Code Playgroud)

  • 也就是说,您只使用Apache.您使用nginx转发请求,请参阅以下答案:http://stackoverflow.com/a/17477436/188614 (31认同)
  • 将此代码添加到我的虚拟主机文件会导致错误,例如"此处不允许订购"或"此处不允许拒绝". (7认同)
  • 您还应该提供该配置的确切位置,对于 Apache 的新手来说,这会很有帮助。 (6认同)
  • @tufelkinder:你可以将你的`virtualhost`配置中的代码放在一个新的`<Directory /> </ Directory>`指令中. (4认同)

Vin*_*jip 31

您可以将其添加到loggers日志记录配置部分:

    'django.security.DisallowedHost': {
        'handlers': ['mail_admins'],
        'level': 'CRITICAL',
        'propagate': False,
    },
Run Code Online (Sandbox Code Playgroud)

这会将日志记录阈值设置为高于ERRORDjango在SuspiciousOperation检测到时使用的级别.

或者,您可以使用例如a FileHandler来记录这些事件,而无需通过电子邮件发送给您.例如,要仅为这些特定事件使用专用文件,可以将其添加到以下handlers部分:

    'spoof_logfile': {
        'level': 'ERROR',
        'class': 'logging.FileHandler',
        'filename': '/path/to/spoofed_requests.log',
    },
Run Code Online (Sandbox Code Playgroud)

然后在以下loggers部分中使用它:

    'django.security.DisallowedHost': {
        'handlers': ['spoof_logfile'],
        'level': 'ERROR',
        'propagate': False,
    },
Run Code Online (Sandbox Code Playgroud)

请注意,在Django文档中提出的建议,请使用

    'django.security.DisallowedHost': {
        'handlers': ['null'],
        'propagate': False,
    },
Run Code Online (Sandbox Code Playgroud)

取决于你运行Python 2.7或更高版本 - 在2.6,logging没有NullHandler.


Zag*_*ags 9

django 文档专门解决了这个问题。他们建议将其放入您的日志记录设置中

LOGGING = {
    # ...
    "handlers": {
        # ...
        "null": {
            "class": "logging.NullHandler",
        },
    },
    "loggers": {
        # ...
        "django.security.DisallowedHost": {
            "handlers": ["null"],
            "propagate": False,
        },
    },
}
Run Code Online (Sandbox Code Playgroud)

此外,如果您使用 Sentry,则需要添加以下内容以防止 Sentry 拾取它:

from sentry_sdk.integrations.logging import ignore_logger
ignore_logger("django.security.DisallowedHost")
Run Code Online (Sandbox Code Playgroud)


Jan*_*zny 8

这是NGINX示例,应该阻止您的django接收垃圾请求.

server {
    listen 80 default_server;
    server_name _;
    return 418;
}


server {
    listen 80;
    # This will keep Django from receiving request with invalid host
    server_name <SERVER_IP> your.domain.com;
    ...
Run Code Online (Sandbox Code Playgroud)

  • 如果使用 HTTPS,请不要忘记重复上述相同的服务器块,但端口 443 和指定的 ssl 证书除外。只是浪费了一个小时试图找出为什么我不断收到错误消息。 (2认同)

DRC*_*DRC 6

你可以用这样的东西来沉默那个特定的SuspiciousOperation

'loggers': {
    'django.security.DisallowedHost': {
        'handlers': ['null'],
        'propagate': False,
   },
Run Code Online (Sandbox Code Playgroud)

有关更多参考,参阅此参考https://docs.djangoproject.com/en/dev/topics/logging/#django-security

编辑

你还需要添加一个'null'处理程序:

'handlers': {
    'null': {
        'level': 'DEBUG',
        'class': 'logging.NullHandler',
    },
}
Run Code Online (Sandbox Code Playgroud)

可能你只需要添加它并修改错误级别(用'ERROR'替换DEBUG).

总是参考文档中的完整语法和语义.


Bob*_*lay 5

在请求到达 Django 之前阻止带有无效 Host 标头的请求的另一种方法是使用默认的Apache 配置<VirtualHost>,它除了返回 404 之外什么都不做。

<VirtualHost *:80>
</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

如果您将其定义为您的第一个虚拟主机(例如在 000-default.conf 中),然后在它后面加上您的 'real' <VirtualHost>,并使用 a<ServerName>ServerAlias>您想要匹配的任何 <条目,Apache 将为任何请求返回 404Host不匹配的标题<ServerName>或您的<ServerAlias>条目之一。确保默认值 404<VirtualHost>首先定义的关键是通过文件名('000')或配置文件中的第一个条目。

我比上面流行的解决方案更喜欢这个,因为它非常明确且易于扩展。


liq*_*dki 5

使用Apache 2.4,无需使用mod_setenvif。HTTP_HOST已经是一个变量,可以直接求值:

WSGIScriptAlias / /path/to/wsgi.py

<Directory /path/to>
    <Files wsgi.py>
        Require expr %{HTTP_HOST} == "example.com"
    </Files>
</Directory>
Run Code Online (Sandbox Code Playgroud)