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,
},
}
}
このエラーを無視するべきではありません。代わりに、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
これをロギング設定のloggers
セクションに追加できます:
'Django.security.DisallowedHost': {
'handlers': ['mail_admins'],
'level': 'CRITICAL',
'propagate': False,
},
これは、ERROR
が検出されたときにDjango=が使用するSuspiciousOperation
レベルを超えるロギングしきい値を設定します。
代わりに、例えば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
がありません。
Django=がゴミ要求を受信しないようにする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;
...
そのようなSuspiciousOperationを次のようなもので黙らせることができます
'loggers': {
'Django.security.DisallowedHost': {
'handlers': ['null'],
'propagate': False,
},
詳細はこちらをご覧ください https://docs.djangoproject.com/en/dev/topics/logging/#Django-security
[〜#〜] edit [〜#〜]
また、「null」ハンドラーを追加する必要があります。
'handlers': {
'null': {
'level': 'DEBUG',
'class': 'logging.NullHandler',
},
}
おそらく、これを追加して、エラーのレベルを変更するだけです(DEBUGを 'ERROR'に置き換えます)。
完全な構文と意味については、常に documentation を参照してください。
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>
Djangoに到達する前に無効なHostヘッダーを持つリクエストをブロックするもう1つの方法は、404を返すだけの<VirtualHost>
でdefault Apache構成を使用することです。
<VirtualHost *:80>
</VirtualHost>
これを最初の仮想ホスト(たとえば、000-default.conf)として定義し、その後に「実際の」<VirtualHost>
を付けて、<ServerName>
および一致する<ServerAlias>
エントリを完了すると、Apacheは404を返します<ServerName>
または<ServerAlias>
エントリのいずれかと一致しないHost
ヘッダーを持つ要求。キーは、デフォルトの404 <VirtualHost>
が、ファイル名( '000')または構成ファイルの最初のエントリのいずれかによって最初に定義されるようにするためです。
これは非常に明示的で拡張が容易なので、上記の一般的なソリューションよりもこれが好きです。
まだコメントすることはできませんが、Order Deny、Allowは廃止されているため、現在のRequireディレクティブを使用して仮想ホストでこれを行う方法は次のとおりです。
<Directory /var/www/html/>
SetEnvIfNoCase Host example\.com VALID_Host
Require env VALID_Host
Options
</Directory>
警告を非表示または無効にするだけの場合は、このページの他の回答は正しいです。すべてのホスト名を意図的に許可する場合は、*
の特別な値をALLOWED_HOSTS
設定として使用できます。
ホスト名のチェックを完全に防ぐには、settings.py
に次の行を追加します。
ALLOWED_HOSTS = ['*']
ソース: https://github.com/Django/django/blob/master/Django/http/request.py#L544-L56
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
複数の有効なホストの場合:
SetEnvIfNoCase Host example\.com VALID_Host
SetEnvIfNoCase Host example2\.com VALID_Host
SetEnvIfNoCase Host example3\.com VALID_Host
Require env VALID_Host
Setting.pyセットで:
ALLOWED_HOSTS = ['yourweb.com']