web-dev-qa-db-ja.com

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,
        },
    }
}
45
Nathan Osman

このエラーを無視するべきではありません。代わりに、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
52
Mark Lavin

これをロギング設定の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では、loggingNullHandlerがありません。

30
Vinay Sajip

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;
    ...
8

そのような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 を参照してください。

6
DRC

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>
5
liquidki

Djangoに到達する前に無効なHostヘッダーを持つリクエストをブロックするもう1つの方法は、404を返すだけの<VirtualHost>default Apache構成を使用することです。

<VirtualHost *:80>
</VirtualHost>

これを最初の仮想ホスト(たとえば、000-default.conf)として定義し、その後に「実際の」<VirtualHost>を付けて、<ServerName>および一致する<ServerAlias>エントリを完了すると、Apacheは404を返します<ServerName>または<ServerAlias>エントリのいずれかと一致しないHostヘッダーを持つ要求。キーは、デフォルトの404 <VirtualHost>が、ファイル名( '000')または構成ファイルの最初のエントリのいずれかによって最初に定義されるようにするためです。

これは非常に明示的で拡張が容易なので、上記の一般的なソリューションよりもこれが好きです。

4
Bob Barcklay

まだコメントすることはできませんが、Order Deny、Allowは廃止されているため、現在のRequireディレクティブを使用して仮想ホストでこれを行う方法は次のとおりです。

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

警告を非表示または無効にするだけの場合は、このページの他の回答は正しいです。すべてのホスト名を意図的に許可する場合は、*の特別な値を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
2
Wolph

複数の有効なホストの場合:

SetEnvIfNoCase Host example\.com VALID_Host
SetEnvIfNoCase Host example2\.com VALID_Host
SetEnvIfNoCase Host example3\.com VALID_Host
Require env VALID_Host
1
ashier

Setting.pyセットで:

ALLOWED_HOSTS = ['yourweb.com']
0
Mu Sian Gong