我有一个集群(在自动缩放中可能有 N 个实例),并且我有一个在 Node/Express 中完成的网站服务。
我有一个弹性负载均衡器,它有一个目标组,监听器指向这个目标组的特定路径。
一切都按预期工作,网站加载,我可以在有和没有 https 的情况下访问,但我怎样才能使 HTTPS 强制从 HTTP 重定向?我在 ECS 中没有任何代理(不知道 nginx-proxy 是否支持我的集群中的多个实例)
谢谢
我有一个集群(在自动缩放中可能有 N 个实例),并且我有一个在 Node/Express 中完成的网站服务。
我有一个弹性负载均衡器,它有一个目标组,监听器指向这个目标组的特定路径。
一切都按预期工作,网站加载,我可以在有和没有 https 的情况下访问,但我怎样才能使 HTTPS 强制从 HTTP 重定向?我在 ECS 中没有任何代理(不知道 nginx-proxy 是否支持我的集群中的多个实例)
谢谢
2018 年 7 月 25 日更新: Elastic Load Balancing 宣布支持应用程序负载均衡器的重定向和固定响应。您可以在AWS 侦听器规则中找到更多信息。
您不能在 ELB/ALB 上执行 HTTP 到 HTTPS 重定向。
在 AWS 中有多种方法可以做到这一点。
注意:由于您使用的是 Node/Express,因此最好在其前面放置一个像 Nginx 这样的 Web 服务器。查看以下Stackoverflow Q/A以了解更多详细信息。
我不认为 ALB/ELB 可以自己进行重定向。
这篇 AWS 文章描述了如何为 nginx 设置重定向:
server {
listen 80;
server_name www.example.org;
if ($http_x_forwarded_proto != "https") {
rewrite ^(.*)$ https://$server_name$REQUEST_URI permanent;
}
}
此 SO 答案中的另一个选项:
if ($http_x_forwarded_proto = 'http') {
return 301 https://yourdomain.com$request_uri;
}
关于应用程序的多个实例,我们所做的是将应用程序服务器置于内部 ALB 下,然后为 nginx 服务器创建另一个服务以充当一种“应用程序网关”,这次使用具有 SSL 证书的外部 ALB安装。Nginx 将请求定向到内部应用程序 ALB。这类似于 Remind's Empire中显示的架构。
基本上,AWS 负载均衡器现在支持来自 http 侦听器规则的 https 重定向(前提是您的应用程序正在将其中的 URL 从 http 重写为 https)。
导航:负载均衡器 > 侦听器 > HTTP:80 > 查看/编辑规则 > 添加规则(高于默认值)。规则应如下所示:
IF:
Source IP is 0.0.0.0/32
THEN:
Redirect to HTTPS://#{host}:443/#{path}?#{query}
Status code: HTTP_301
注意:还应该有一个 https 侦听器(具有有效证书,也可以是自签名的)侦听端口 443 以使其正常工作。
由于您使用的是 Express,因此您可以侦听所有传入请求并检查 x-forwared-proto 标头是否为“http”。如果是,请重定向到 https。Express 中间件函数如下所示:
function forceHttps(req, res, next) {
const xfp =
req.headers["X-Forwarded-Proto"] || req.headers["x-forwarded-proto"];
if (xfp === "http") {
const secureUrl = `https://${req.headers.hostname}${req.url}`;
res.redirect(301, secureUrl);
} else {
next();
}
}
...或者您可以只使用为这个特定用例设计的 NPM 包: https ://www.npmjs.com/package/@crystallize/elasticloadbalancer-express-force-https
安装
npm i --save @crystallize/elasticloadbalancer-express-force-https
用法
const express = require('express');
const forceHttps = require('@crystallize/elasticloadbalancer-express-force-https');
const server = express();
server.use(forceHttps());
我们的博客文章中有关此的更多信息: https ://snowball.digital/blog/force-https-behind-elastic-load-balancer-on-a-nodejs-application