Как отключить Django неверную ошибку 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,
},
}
}
Ответы
Ответ 1
Вы не должны игнорировать эту ошибку. Вместо этого вы должны отклонять запрос до того, как он достигнет вашего бэкэнда 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
Ответ 2
Вы можете добавить это в раздел loggers
своей конфигурации ведения журнала:
'django.security.DisallowedHost': {
'handlers': ['mail_admins'],
'level': 'CRITICAL',
'propagate': False,
},
Это устанавливает порог регистрации выше уровня ERROR
, который использует Django, когда обнаружен SuspiciousOperation
.
В качестве альтернативы вы можете использовать, например. a FileHandler
, чтобы регистрировать эти события, не отправляя их вам. Например, чтобы использовать выделенный файл только для этих конкретных событий, вы можете добавить это в раздел 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 docs, использовать
'django.security.DisallowedHost': {
'handlers': ['null'],
'propagate': False,
},
зависит от того, что вы используете Python 2.7 или новее - на 2.6, logging
не имеет NullHandler
.
Ответ 3
Здесь пример NGINX, который должен помешать вашему джанго получать запросы на мусор.
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;
...
Ответ 4
вы можете отключить эту особую SuspiciousOperation с чем-то вроде
'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',
},
}
возможно, вам нужно только добавить это и изменить уровень ошибки (заменив DEBUG на "ERROR" ).
как всегда, ссылаются на документацию для полного синтаксиса и семантики.
Ответ 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>
Ответ 6
Другой способ блокировать запросы с недопустимым заголовком Host до того, как он достигнет Django, - это использовать конфигурацию Apache по умолчанию с <VirtualHost>
, которая ничего не возвращает, а возвращает 404.
<VirtualHost *:80>
</VirtualHost>
Если вы определяете это как свой первый виртуальный хост (например, в 000-default.conf), а затем следуйте за ним с помощью своего "реального" <VirtualHost>
, в который входят записи <ServerName>
и any < ServerAlias>
, которые вы хотите совместить, Apache вернет 404 для любых запросов с заголовком Host
, который не соответствует <ServerName>
или одной из ваших записей <ServerAlias>
. Прежде всего, убедитесь, что значение по умолчанию - 404 <VirtualHost>
- либо имя файла ('000'), либо первая запись в вашем файле конфигурации.
Мне нравится это лучше, чем популярное решение выше, потому что оно очень явное и легко расширяемое.
Ответ 7
Другие ответы на этой странице верны, если вы просто хотите скрыть или отключить предупреждение. Если вы намеренно разрешаете каждому имени хоста, специальное значение *
может использоваться как параметр 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 (e.g. ``.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
Ответ 8
Я не могу комментировать, но поскольку Order Deny, Allow устарел, способ сделать это на виртуальном хосте с текущей директивой Require:
<Directory /var/www/html/>
SetEnvIfNoCase Host example\.com VALID_HOST
Require env VALID_HOST
Options
</Directory>
Ответ 9
В параметре setting.py:
ALLOWED_HOSTS = ['yourweb.com']
Ответ 10
для нескольких допустимых хостов вы можете:
SetEnvIfNoCase Host example\.com VALID_HOST
SetEnvIfNoCase Host example2\.com VALID_HOST
SetEnvIfNoCase Host example3\.com VALID_HOST
Require env VALID_HOST