Подтвердить что ты не робот

Django ERROR: недопустимый заголовок 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. *

Все это было на одной линии, конечно:

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
  • Обновление # 3: добавлена ​​интересная строка из моего журнала nginx
  • Обновление # 4: обновлена ​​моя конфигурация nginx
4b9b3361

Ответ 1

Похоже,

proxy_set_header Host $http_host

следует изменить на

proxy_set_header Host $host

и server_name должны быть установлены соответствующим образом на адрес, используемый для доступа к серверу. Если вы хотите, чтобы он поймал все, вы должны использовать server_name www.domainname.com "" (doc здесь).

Я не уверен, но я думаю, что вы видите, если клиент не отправляет заголовок Host:. Поскольку nginx не получает заголовок Host:, заголовок Host: не передается до пушки. На данный момент я думаю, что gunicorn заполняет Host: как путь к сокету и сообщает Django, что это соединение используется. Используя $host и установив server_name в nginx, убедитесь, что Host: правильно передан в gunicorn и устранит эту проблему.

Что касается электронной почты, в соответствии с commit в связанном вами билете, похоже, что электронные письма по-прежнему отправляются за запрещенные хосты. Добавленный к документу также был предложил способ отключения отправленных сообщений:

    'loggers': {
        'django.security.DisallowedHost': {
        'handlers': ['null'],
        'propagate': False,
    },

Ответ 2

Я знаю, что это старый вопрос, но проблема была со мной только сегодня. Рекомендуемое решение для Django docs заключается в том, чтобы добавить в ваш конфигуратор nginx "catch all" nginx:

server {
    listen 80 default_server;
    return 444;
}

официальные документы nginx рекомендуют одно и то же решение, дают или принимают некоторые синтаксические нюансы.

Таким образом, запрос не отправляется на django, соединение немедленно отключается, когда nginx получает неверный запрос.

Ответ 3

Я столкнулся с некоторыми замечаниями, которые предполагают, что подавление электронных писем не является хорошей идеей, потому что это не касается непосредственно проблемы. Наиболее эффективным решением, которое я нашел, является добавление следующего к вашим настройкам 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/

Сообщение в блоге ссылается на этот вопрос.