How to disable Django's invalid HTTP_HOST erro

2020-02-02 04:14发布

Ever since I deployed a site running Django 1.7 alpha (checked out from Git), I've been occasionally receiving error messages with titles like:

"Invalid HTTP_HOST header: 'xxx.xxx.com'"

I realize that this is due to the Host: HTTP header being set to a hostname not listed in ALLOWED_HOSTS. However, I have no control over when and how often someone sends a request to the server with a forged hostname. Therefore I do not need a bunch of error emails letting me know that someone else is attempting to do something fishy.

Is there any way to disable this error message? The logging settings for the project look like this:

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

10条回答
Fickle 薄情
2楼-- · 2020-02-02 04:51

Another way to block requests with an invalid Host header before it reaches Django is to use a default Apache config with a <VirtualHost> that does nothing but return a 404.

<VirtualHost *:80>
</VirtualHost>

If you define this as your first virtual host (e.g. in 000-default.conf) and then follow it with your 'real' <VirtualHost>, complete with a <ServerName> and any <ServerAlias> entries that you want to match, Apache will return a 404 for any requests with a Host header that does not match <ServerName> or one of your <ServerAlias> entries. The key it to make sure that the default, 404 <VirtualHost> is defined first, either by filename ('000') or the first entry in your config file.

I like this better than the popular solution above because it is very explicit and easy to extend.

查看更多
趁早两清
3楼-- · 2020-02-02 04:51

I can't comment yet, but since Order Deny, Allow is deprecated, the way to do this in a virtual host with the current Require directive is:

<Directory /var/www/html/>
    SetEnvIfNoCase Host example\.com VALID_HOST
    Require env VALID_HOST
    Options
</Directory>
查看更多
老娘就宠你
4楼-- · 2020-02-02 04:58

You shouldn't be ignoring this error. Instead you should be denying the request before it reaches your Django backend. To deny requests with no HOST set you can use

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

or force the match to a particular domain (example.com)

SetEnvIfNoCase Host example\.com VALID_HOST
Order Deny,Allow
Deny from All
Allow from env=VALID_HOST
查看更多
不美不萌又怎样
5楼-- · 2020-02-02 04:58

Using Apache 2.4, there's no need to use mod_setenvif. The HTTP_HOST is already a variable and can be evaluated directly:

WSGIScriptAlias / /path/to/wsgi.py

<Directory /path/to>
    <Files wsgi.py>
        Require expr %{HTTP_HOST} == "example.com"
    </Files>
</Directory>
查看更多
登录 后发表回答