1

我对 Apache 代理 Web 服务器和 Django SSL 有疑问,以下是 SSL 的 Django settings.py 和 apache server.conf 文件后跟的错误,django 版本 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)
  ----------------------------------------

设置.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'
   ......

阿帕奇服务器.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>

我还在 django wsgi.py中启用了 HTTPS

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

2 回答 2

1

错误的请求语法('\x16\x03\x00\x00?

这是预期 HTTP 流量的 HTTPS 流量。我认为这是由 apache.conf 中的以下行引起的:

redirect permanent / https://5.5.0.38:8080

这指示浏览器访问给定的 URL(可能是您的 Django 服务器)。它不会将请求转发到 Django 服务器(您可能想要这样做),而是指示浏览器发出新请求并直接从 Django 服务器获取资源,即前面没有 apache。如果您想在另一台服务器前使用 apache,我认为您需要使用 ProxyPass 或 ProxyPassReverse 之类的东西。

如果端口 8080 实际用于 https 将是非常不寻常的,通常这仅用于 http。因此,我假设您的 Django 服务器本身只是在说普通的 http。

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

这不会使 Django 成为 HTTPS 服务器,而只是指示 Django 将所有链接创建为 https 链接。这支持了我的假设,即您的 Django 服务器本身只执行普通的 http。

于 2015-01-10T10:22:38.660 回答
1

我认为正确的答案如下:

  • 首先启用 apache 的 proxy_http 模块以将 url 从 https 重新映射到 http

    $ a2enmod proxy_http

  • 第二个去掉 https 请求到 django 的重定向

  • 添加 ProxyPass 和 ProxyPassReverse 以通过 http 协议将 https 请求从 apache 服务器传递到 Django

    以下是我为 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 编辑/etc/apache2/sites-enabled/000-default.conf apache 文件,如下所示

<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>
于 2015-01-10T16:07:50.750 回答