2

现在我有一个启用 SSL 的网站。SSL 处于 ELB 级别,因此 apache http 服务器永远不会看到它。我正在努力做到这一点,以便 Apache 将强制所有请求都具有https,因此不会http发出请求。我正在阅读有关 SO 的其他几篇文章,包括:

Django 和 SSL 问题

https://serverfault.com/questions/410542/disable-https-for-certain-path-in-nginx-results-in-instance-behind-elb-going-int

http://www.acmedata.in/2012/08/31/how-to-host-a-django-app-behind-elb-with-ssl/

我可以为此使用 ELB 配置吗?还是我必须从 ELB 中删除私钥等并将其全部放在 Web 服务器级别?我无法找到有关此的任何进一步信息...

4

2 回答 2

5

您可以通过在 Apache 配置中添加这样的重写规则来强制使用 https:

<VirtualHost *:80>
    ...
    RewriteEngine On
    RewriteCond %{HTTP:X-Forwarded-Proto} !https
    RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=permanent]
    ...
</VirtualHost>

这里的关键是X-Forwarded-Proto标题。ELB 处理 https 并将请求作为 http 转发给 Apache,它还在该过程中添加了此标头。重写规则检查此标头以仅重定向并非源自 ELB 的 http 请求。

于 2013-08-30T09:21:26.153 回答
2

您可以在 django 级别处理此问题,这就是我使用的:

from django.http import HttpResponsePermanentRedirect
from django.conf import settings


class SecureRequiredMiddleware(object):
    def __init__(self):
        self.paths = getattr(settings, 'SECURE_REQUIRED_PATHS')
        self.enabled = self.paths and getattr(settings, 'HTTPS_SUPPORT')

    def process_request(self, request):
        if self.enabled and not request.is_secure():
            full_path = request.get_full_path()

            for path in self.paths:
                if full_path.startswith(path):
                    secure_url = request.build_absolute_uri(full_path).replace(
                        'http://', 'https://')
                    return HttpResponsePermanentRedirect(secure_url)

将其添加到文件并使用中间件设置指向它。然后您将需要添加两个设置项。第一个被调用SECURE_REQUIRED_PATHS,它应该是一个 URL 列表,如下所示:

SECURE_REQUIRED_PATHS = [
    '/login',   #  require HTTPS for any URL starting with `/login`
    '/account', # require HTTPS for any URL starting with `/account`
    '/',        # require HTTPS for all URLs
]

第二个应该是一个名为HTTPS_SUPPORT

HTTPS_SUPPORT = True

然后,只要用户使用 HTTP 访问您的 URL SECURE_REQUIRED_PATHS,他们就会被重定向到 HTTPS 等效项。

于 2013-08-30T03:21:59.593 回答