Django Apache SSL [код 400, неверный запрос сообщения]

У меня проблема с прокси-сервером Apache и Django SSL. Ниже приведена ошибка, за которой следуют файлы Django settings.py и apache server.conf для SSL, django version 1.6.8

  ----------------------------------------
  [10/Jan/2015 09:11:33] code 400, message Bad request syntax ('\x16\x03\x00\x00?
  Exception happened during processing of request from ('5.5.0.46', 38141)
  Traceback (most recent call last):
  File "/usr/lib/python2.7/SocketServer.py", line 593, in process_request_thread
   self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 334, in finish_request
   self.RequestHandlerClass(request, client_address, self)
  File "/usr/local/lib/python2.7/dist-packages/django/core/servers/basehttp.py", line 126, in __init__
   super(WSGIRequestHandler, self).__init__(*args, **kwargs)
  File "/usr/lib/python2.7/SocketServer.py", line 649, in __init__
   self.handle()
  File "/usr/lib/python2.7/wsgiref/simple_server.py", line 117, in handle
   if not self.parse_request(): # An error code has been sent, just exit
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 286, in parse_request
    self.send_error(400, "Bad request syntax (%r)" % requestline)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 368, in send_error
    self.send_response(code, message)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 385, in send_response
    self.log_request(code)
  File "/usr/lib/python2.7/BaseHTTPServer.py", line 422, in log_request
    self.requestline, str(code), str(size))
  File "/usr/local/lib/python2.7/dist-packages/django/core/servers/basehttp.py", line 138, in log_message
   msg = "[%s] %s\n" % (self.log_date_time_string(), format % args)
  UnicodeDecodeError: 'ascii' codec can't decode byte 0xf9 in position 12: ordinal not in    range(128)
  ----------------------------------------

settings.py

   ...... 

   # secure proxy SSL header and secure cookies
   SECURE_SSL_REDIRECT = True
   SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
   SESSION_COOKIE_SECURE = True
   CSRF_COOKIE_SECURE = True

   # session expire at browser close
   SESSION_EXPIRE_AT_BROWSER_CLOSE = True

   # wsgi scheme
   os.environ['wsgi.url_scheme'] = 'https'
   ......

сервер apache.conf

 <IfModule mod_ssl.c>
    <VirtualHost *:80>
            ServerName mywebsite.com
            WSGIScriptAlias / /var/www/manage/manage/wsgi.py
    </VirtualHost>
    <VirtualHost _default_:443>
            ServerName mywebsite.com
            WSGIScriptAlias / /var/www/manage/manage/wsgi.py
            SSLEngine on
            SSLCertificateFile      /etc/apache2/ssl/apache.crt
            SSLCertificateKeyFile /etc/apache2/ssl/apache.key
            redirect permanent / https://5.5.0.38:8080
    </VirtualHost>
  </IfModule>

Также я включил HTTPS в django wsgi.py

  ......
  os.environ['HTTPS'] = "on"
  ..............

person 0x3bfc    schedule 10.01.2015    source источник


Ответы (2)


Неверный синтаксис запроса ('\x16\x03\x00\x00?

Это HTTPS-трафик, в котором ожидается HTTP-трафик. Я предполагаю, что это вызвано следующей строкой в ​​вашем apache.conf:

redirect permanent / https://5.5.0.38:8080

Это указывает браузеру вместо этого получить доступ к данному URL-адресу (возможно, к вашему серверу Django). Он не перенаправляет запрос на сервер Django (что вы, вероятно, намеревались), а вместо этого указывает браузеру сделать новый запрос и получить ресурс непосредственно с сервера Django, то есть без apache впереди. Я думаю, вам нужно использовать вместо этого что-то вроде ProxyPass или ProxyPassReverse, если вы хотите использовать apache перед другим сервером.

Было бы очень необычно, если бы порт 8080 фактически использовался для https, обычно он используется только для http. Поэтому я предполагаю, что сам ваш сервер Django говорит только на простом http.

os.environ['HTTPS'] = "включено"

Это не делает сервер HTTPS из Django, а только указывает Django создавать все ссылки как ссылки https. Это подтверждает мое предположение, что сам ваш сервер Django работает только с обычным http.

person Steffen Ullrich    schedule 10.01.2015
comment
мне нужно перенаправить запросы HTTPS с сервера apache на сервер Django и вернуть их обратно на тот же порт 443 - person 0x3bfc; 10.01.2015
comment
хорошо, после включения модуля proxy_http и добавления Proxypassreverse в файл proxy.conf он работает, но у меня есть проблема с получением ресурсов, таких как файлы js/css/и изображения. Не удалось загрузить ресурс: сервер ответил со статусом 502 ( Ошибка прокси), так как я могу поддерживать выполнение всех запросов и получать все ресурсы, не получая это сообщение об ошибке - person 0x3bfc; 10.01.2015
comment
спасибо, после просмотра файла proxy.conf я изменил ProxyPassReverse / 5.5.0.38:8080 вместо ProxyPassReverse / 5.5.0.38:8080 косая черта '/' вызывает эту ошибку - person 0x3bfc; 10.01.2015
comment
@AhmedAbdullah Сервер django использует внутри себя сервер Apache? или где я могу найти этот файл .conf? - person cafebabe1991; 16.06.2015

Я думаю, что правильный ответ выглядит следующим образом:

  • сначала включите модуль proxy_http для apache, чтобы переназначить URL-адрес с https на http

    $ a2enmod proxy_http

  • во-вторых, убрать перенаправление https-запросов на django

  • добавьте ProxyPass и ProxyPassReverse для передачи https-запросов с сервера apache на Django по протоколу http

    вот что я сделал для apache.conf

        <VirtualHost *:80>
                ServerName mywebsite.com
                WSGIScriptAlias / /var/www/manage/manage/wsgi.py
        </VirtualHost>
        <VirtualHost _default_:443>
                ServerName mywebsite.com
                WSGIScriptAlias / /var/www/manage/manage/wsgi.py
                SSLEngine on
                SSLCertificateFile      /etc/apache2/ssl/apache.crt
                SSLCertificateKeyFile /etc/apache2/ssl/apache-wp.key
                ProxyPass / http://myip:8080/
                ProxyPassReverse / http://myip:8080/
                #redirect permanent / https://myip:8080
        </VirtualHost>
    

также убедитесь, что все http переписаны на https, отредактируйте файл apache /etc/apache2/sites-enabled/000-default.conf, как показано ниже.

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html
        RewriteEngine On
        RewriteCond %{HTTPS} !on
        RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
person 0x3bfc    schedule 10.01.2015