您没有提供足够的设置信息,但我可以猜测发生了什么。
我猜你是在 ELB 上卸载 SSL 并向 Nginx 发送明文 HTTP 消息,并将 HTTP_X_FORWARDED_PROTO 标头设置为原始方案。
因此,如果用户转到 https://www.example.com,那么它会卸载 SSL/TLS 并将流量定向到 http://www.example.com,并将 HTTP_X_FORWARDED_PROTO 设置为“https”。在这种情况下,没有重定向(因为用户已经在使用 HTTPS),但也没有 HSTS 标头(因为用户没有使用 HTTPS 到 nginx 并且您只在 443 服务器配置中设置了该标头)。您应该将其添加到您的端口 80 服务器,以便同时为这种情况提供 HSTS 标头:
if ($http_x_forwarded_proto = "https") {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
从技术上讲,您不应该通过 HTTP 仅通过 HTTPS 提供 HSTS 标头,因此最好在负载平衡级别设置,但我认为使用 $http_x_forwarded_proto 标头就可以了。
但是,如果我的猜测是正确的,那么这证明你没有正确使用 HSTS,所以我不在这里添加一些警告是失职的。
HSTS 并非没有风险。
HSTS 是一个很好的解决方案,即目前 Web 默认不是 HTTPS,这会导致各种安全风险。但是,如果您仍然需要使用 HTTP,则并非没有风险。例如,如果您有一些尚未转换为 HTTPS 的子域(例如 blog.example.com),或者如果您将相同的域用于尚未转换的内部站点(例如 intranet.example.com)或开发站点( dev.example.com)。最后一个也可能是一个问题,因为 HSTS 不允许您跳过过去的 HTTPS 错误(例如,如果为您的开发域使用自签名证书)。这并不是说您不应该使用 HSTS - 但您应该充分理解它并在给自己(和您的组织)带来很多痛苦之前对其进行测试。
因此,建议从较小的 max-age 开始,而不是一整年 (max-age= 31536000) 并建立起来。而不是全力以赴并破坏事物。这样一来,如果您找到需要转换的网站,您就不会将其锁定一年或直到您转换为 HTTPS。
对于预加载尤其如此,您将标头烘焙到浏览器代码库中,因此它甚至在您访问该站点之前就从头开始。您基本上无法撤消此操作(Chrome 至少需要 3 个月才能将其删除,其他浏览器没有给出时间表)。所以,由于它基本上是不可逆的,在你完全测试之前,你永远不应该去预加载,看起来你还没有。 Chrome has an issue tracking all the screw ups that sites have done where they have requested preload and then broken things。我有blog about this danger,就像have others。此外,预加载还有一些其他要求(您必须将 preload 属性添加到您的标头,并且您还必须在您的基本域 (https://example.com) 上提供此标头),您似乎没有满足这些要求。
基域问题尤其会导致问题,例如,如果您从未正常访问过,因此https://www.example.com 的测试看起来很好,http://intranet.example.com 仍然有效(因为您从未在基域设置 HSTS 标头,所以它可以继续通过 HTTP 发送)然后你预加载并繁荣 - http://intranet.example.com 停止工作。对此进行测试的最简单方法是将此基域中的资源添加到您的 www 站点(例如 https://example.com/pixel.png),这将强制访问您站点的任何人使用基域的 HSTS 标头。
HSTS 很棒。每个站点都应该使用它,每个站点都应该只使用 HTTPS——但在他们这样做之前,它并非没有风险。确保在部署时理解它。慢慢来,建立一个大的最大年龄。然后才进行预加载。