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

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

“无效的HTTP_HOST标题:'xxx.xxx.com'”

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

有什么办法可以禁用这个错误信息吗? 该项目的日志logging设置如下所示:

 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, }, } } 

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

 SetEnvIfNoCase Host .+ VALID_HOST Order Deny,Allow Deny from All Allow from env=VALID_HOST 

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

 SetEnvIfNoCase Host example\.com VALID_HOST Order Deny,Allow Deny from All Allow from env=VALID_HOST 

您可以将其添加到日志loggingconfiguration的loggers部分:

  'django.security.DisallowedHost': { 'handlers': ['mail_admins'], 'level': 'CRITICAL', 'propagate': False, }, 

这将日志logging阈值设置为高于Django在检测到SuspiciousOperation时使用的ERROR级别。

或者,您可以使用例如FileHandler来logging这些事件,而不用通过电子邮件发送给您。 例如,要为这些特定事件使用专用文件,可以将其添加到handlers部分:

  'spoof_logfile': { 'level': 'ERROR', 'class': 'logging.FileHandler', 'filename': '/path/to/spoofed_requests.log', }, 

然后在loggers部分使用它:

  'django.security.DisallowedHost': { 'handlers': ['spoof_logfile'], 'level': 'ERROR', 'propagate': False, }, 

请注意, Django文档中的build议使用

  'django.security.DisallowedHost': { 'handlers': ['null'], 'propagate': False, }, 

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

这是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; ... 

你可以用类似的东西来保持这个特定的可疑操作

 'loggers': { 'django.security.DisallowedHost': { 'handlers': ['null'], 'propagate': False, }, 

看到这个更多的参考https://docs.djangoproject.com/en/dev/topics/logging/#django-security

编辑

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

 'handlers': { 'null': { 'level': 'DEBUG', 'class': 'logging.NullHandler', }, } 

可能你只需要添加这个并修改错误的级别(用'ERROR'replaceDEBUG)。

一如既往地参考文档的完整语法和语义。

使用Apache 2.4,不需要使用mod_setenvif。 HTTP_HOST已经是一个variables,可以直接进行评估:

 WSGIScriptAlias / /path/to/wsgi.py <Directory /path/to> <Files wsgi.py> Require expr %{HTTP_HOST} == "example.com" </Files> </Directory> 

如果您只想隐藏或禁用警告,则此页面上的其他答案是正确的。 如果您有意允许每个主机名都可以使用*的特殊值作为ALLOWED_HOSTS设置。

要完全防止主机名检查,请将以下行添加到settings.py

 ALLOWED_HOSTS = ['*'] 

来源: https : //github.com/django/django/blob/master/django/http/request.py#L544-L563

 def validate_host(host, allowed_hosts): """ Validate the given host for this site. Check that the host looks valid and matches a host or host pattern in the given list of ``allowed_hosts``. Any pattern beginning with a period matches a domain and all its subdomains (eg ``.example.com`` matches ``example.com`` and any subdomain), ``*`` matches anything, and anything else must match exactly. Note: This function assumes that the given host is lower-cased and has already had the port, if any, stripped off. Return ``True`` for a valid host, ``False`` otherwise. """ for pattern in allowed_hosts: if pattern == '*' or is_same_domain(host, pattern): return True return False 

在到达Django之前,用一个无效的Host头来阻止请求的另一种方法是使用默认的 Apacheconfiguration和一个<VirtualHost> ,这个configuration什么也不做,只是返回一个404。

 <VirtualHost *:80> </VirtualHost> 

如果你把它定义为你的第一个虚拟主机(例如在000-default.conf中),然后跟着你的“真正的” <VirtualHost> ,用一个<ServerName>和任何你想匹配的< ServerAlias>将返回一个404的任何请求与Host头不匹配<ServerName>或您的一个<ServerAlias>条目。 确保首先定义默认值404 <VirtualHost>是通过filename('000')或configuration文件中的第一项来定义。

我喜欢这个比上面stream行的解决scheme更好,因为它非常明确,易于扩展。

我现在还不能评论,但是由于Order Deny,Allow是不推荐使用的,所以在虚拟主机中使用当前的Require指令来做到这一点是:

 <Directory /var/www/html/> SetEnvIfNoCase Host example\.com VALID_HOST Require env VALID_HOST Options </Directory> 

在setting.py中设置:

 ALLOWED_HOSTS = ['yourweb.com'] 

对于多个有效的主机,您可以:

 SetEnvIfNoCase Host example\.com VALID_HOST SetEnvIfNoCase Host example2\.com VALID_HOST SetEnvIfNoCase Host example3\.com VALID_HOST Require env VALID_HOST