如何在 AWS 弹性负载均衡器上实施 HTTP 严格传输安全 (HSTS)?

How to implement HTTP Strict Transport Security (HSTS) on AWS Elastic Load Balancer?

我想在我的应用程序中实施 HSTS。

我有一个 ELB 终止 SSL 并将流量转发到我的应用程序,这是一个用作反向代理的 apache 服务器。

我知道为了实施 HSTS,我需要在我的请求中添加 header Strict-Transport-Security。

不幸的是,我似乎无法在我的 Apache 服务器上实现它,因为它必须添加到 HTTPS 虚拟主机,而我的 Apache 只配置了 http 虚拟主机,因为 SSL 在 ELB 上终止。

这意味着 ELB 在转发请求时必须将 header Strict-Transport-Security 添加到请求中。

我该怎么做?我可以添加某种安全策略来为我做到这一点吗?

Maybe? - 解决了我过去遇到的类似情况。

我问了 AWS Support,得到的答复是目前 ELB 无法在客户端请求中添加 HSTS headers。因此,我决定使用我的 Apache 服务器寻找解决方法。这是我找到的解决方案:

HSTS RFC 表示

An HSTS Host MUST NOT include the STS header field in HTTP responses conveyed over non-secure transport.

然后我所做的是在 Apache 中设置 header AFTER http=>https 重定向。由于此重定向具有标志 [L],这意味着 301 重定向将不包含 header,但任何 https 请求都包含。我的 Apache 配置如下所示:

<VirtualHost *:80>
...
    #http=>https
    RewriteCond %{HTTP:X-Forwarded-Proto} =http
    RewriteRule . https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]

    #hsts
    Header set Strict-Transport-Security "max-age=31536000"

如果您使用的是 Apache 2.4+,您可能熟悉 expressions 和指令 <If><ElseIf><Else>.

我在开发环境、暂存环境和生产环境之间有一个复杂的配置,所以依赖 [L] 标志和 RewriteRule 对我来说是行不通的。

这使我想到了以下解决方案,我将其放在 .htaccess 中:

<IfModule mod_headers.c>
    <If "%{REQUEST_SCHEME} == 'https' || %{HTTP:X-Forwarded-Proto} == 'https'">
        Header set Strict-Transport-Security "max-age=31536000"
    </If>
</IfModule>

它在我的环境中工作得更好,我觉得它更符合 RFC。

如果您从不直接访问您的实例,您可以删除 "%{REQUEST_SCHEME} == 'https' 部分,但这是我在开发环境中调试过程的一部分。

非常感谢 Pedreiro 为我指明了 HSTS RFC 上实际规范的正确方向。

请注意,由于 Apache < 2.4 不支持此功能,因此最好将其封装在 <IfVersion >= 2.4> 中,如下所示:

    <IfVersion >= 2.4> 
        <IfModule mod_headers.c>
            <If "%{REQUEST_SCHEME} == 'https' || %{HTTP:X-Forwarded-Proto} == 'https'">
                Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
            </If>
        </IfModule>
    </IfVersion>