web-dev-qa-db-ja.com

Djangoエラー:無効なHTTP_Hostヘッダー:u '/ run / myprojectname / gunicorn.sock:'

SOにはこのような質問がたくさんあることは承知していますが、私の特定の問題に答えているようには見えません。

DjangoのALLOWED_HOSTS値が、適切な80値が付いていない私のIPのポートHost:へのすべてのリクエストをブロックしていること、およびリクエストが入ったときに、正しい値、Djangoは私にメールをドロップしています。この問題を解消するために slick Nginx hack についても知っていますが、私は理解しようとしていますそのような要求の性質を調べ、これが私が心配する必要があるセキュリティ問題であるかどうかを判断します。

このようなリクエストは理にかなっています:

[Django] ERROR: Invalid HTTP_Host header: '203.0.113.1'.  You may need to add u'203.0.113.1' to ALLOWED_HOSTS.

しかし、これは私を驚かせます:

[Django] ERROR: Invalid HTTP_Host header: u'/run/my_project_name/gunicorn.sock:'.

これは、リクエスタがHost: /run/my_project_name/gunicorn.sockをサーバーに送信したことを意味しませんか?もしそうなら、彼らは私の.sockファイルのパス名をどのように持っていますか?私のサーバーはどういうわけかこの情報を漏らしていますか?

さらに、Django 1.6.5を実行しているため、なぜ このチケット が修正済みとマークされているので、これらの電子メールがまったく受信されないのか理解できません。しばらくの間。

誰かが私が行方不明のものに光を当てることができますか?

これは私のsettings.LOGGING変数です:

{
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {'()': 'Django.utils.log.RequireDebugFalse'}
    },
    'formatters': {
        'simple': {'format': '%(levelname)s %(message)s'},
        'verbose': {'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'}
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
            'level': 'DEBUG'
        },
        'mail_admins': {
            'class': 'Django.utils.log.AdminEmailHandler',
            'filters': ['require_debug_false'],
            'level': 'ERROR'
        }
    },
    'loggers': {
        'Django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True
        },
        'my_project_name': {
            'handlers': ['console'], 
            'level': 'DEBUG'
        }
    },
    'version': 1
}

そして、これが私のnginx設定です:

worker_processes 1;
pid /run/nginx.pid;
error_log /var/log/myprojectname/nginx.error.log debug;
events {
}
http {
  include mime.types;
  default_type application/octet-stream;
  access_log /var/log/myprojectname/nginx.access.log combined;
  sendfile on;
  gzip on;
  gzip_http_version 1.0;
  gzip_proxied any;
  gzip_min_length 500;
  gzip_disable "MSIE [1-6]\.";
  gzip_types text/plain text/html text/xml text/css
             text/comma-separated-values
             text/javascript application/x-javascript
             application/atom+xml;
  upstream app_server {
    server unix:/run/myprojectname/gunicorn.sock fail_timeout=0;
  }
  server {
    listen 80 default;
    listen [::]:80 default;
    client_max_body_size 4G;
    server_name myprojectname.mydomain.tld;
    keepalive_timeout 5;
    root /var/www/myprojectname;
    location / {
      try_files $uri @proxy_to_app;
    }
    location @proxy_to_app {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $Host;
      proxy_redirect off;
      proxy_pass http://app_server;
    }
    error_page 500 502 503 504 /500.html;
    location = /500.html {
      root /tmp;
    }
  }
}

最後に、これをnginxアクセスログで見つけました。これは、/ run/myprojectname/gunicorn.sockが無効なHTTP_Hostヘッダーであることについて不平を言う電子メールに対応しています。*

もちろん、これはすべて1行でした。

2014/09/05 20:38:56 [info] 12501#0: *513 epoll_wait() reported that client
prematurely closed connection, so upstream connection is closed too while sending
request to upstream, client: 54.84.192.68, server: myproject.mydomain.tld, request:
"HEAD / HTTP/1.0", upstream: "http://unix:/run/myprojectname/gunicorn.sock:/"

もちろん、これがどういう意味かはまだわかりません:-(

  • アップデート#1:追加されたsettings.LOGGING
  • アップデート#2:追加されたnginx設定
  • pdate#:nginxログから興味深い行を追加しました
  • pdate#4:nginx設定を更新しました
21
Daniel Quinn

のように思える

proxy_set_header Host $http_Host

変更する必要があります から

proxy_set_header Host $Host

server_name適切に設定する必要があります サーバーへのアクセスに使用するアドレス。すべてをキャッチしたい場合は、server_name www.domainname.com ""doc here )を使用する必要があります。

確かではありませんが、クライアントがHost:ヘッダーを送信しないと、何が起こっていると思いますか。 nginxはHost:ヘッダーを受信しないため、Host:ヘッダーはgunicornに渡されません。この時点で、gunicornはHost:をソケットパスとして入力し、Djangoこれが使用される接続であるため、これを通知します。$Hostを使用してserver_name nginxでHost:がgunicornに正しく渡されるようにし、この問題を修正する必要があります。

メールに関しては、リンクしたチケットの commit によると、許可されていないホストに対してメールがまだ送信されているようです。ドキュメントにも追加されました 送信されるメールを無効にする方法を提案しました

    'loggers': {
        'Django.security.DisallowedHost': {
        'handlers': ['null'],
        'propagate': False,
    },
23
user193130

メールを抑制することは問題に直接対処しないため、メールを抑制することは良い考えではないことを示唆するコメントを見つけました。私が見つけた最も効果的な解決策は、あなたのnginx設定に以下を追加することです:

server {

    ...

    ## Deny illegal Host headers
    if ($Host !~* ^(mydomain.com|www.mydomain.com)$ ) {
        return 444;
    }
}

詳細: https://snakeycode.wordpress.com/2015/05/31/Django-error-invalid-http_Host-header/

ブログ投稿はこの質問を参照しています。

12
Ernest Jumbe

私はこれが古い質問であることを知っていますが、問題はちょうど今日私に起こりました。 Django docs で推奨される解決策は、nginx構成に「catch all」nginxサーバーを追加することです。

server {
    listen 80 default_server;
    return 444;
}

official nginx docs 同じソリューションを推奨し、構文のニュアンスを与えるか、または取る。

このように、リクエストはDjangoに送信されず、nginxが不正なリクエストを受信するとすぐに接続がシャットダウンされます。

5
Laurent S