使用 AWS ECS 在 Node/Express 网络中强制使用 ssl
Force ssl within a Node/Express web using AWS ECS
我有一个集群(在自动缩放中可能有 N 个实例)并且我有一个网站服务是在 Node/Express 完成的。
我有一个弹性负载均衡器,它有一个目标组,监听器指向这个目标组的特定路径。
一切都按预期工作,网站加载,我可以使用和不使用 https 进行访问,但是如何使 HTTPS 强制从 HTTP 重定向?我在ECS中没有任何代理(不知道nginx-proxy是否支持我的集群中的多个实例)
谢谢
我认为 ALB/ELB 无法自行进行重定向。
This AWS article描述了如何为nginx设置重定向:
server {
listen 80;
server_name www.example.org;
if ($http_x_forwarded_proto != "https") {
rewrite ^(.*)$ https://$server_name$REQUEST_URI permanent;
}
}
this SO answer中的另一个选项:
if ($http_x_forwarded_proto = 'http') {
return 301 https://yourdomain.com$request_uri;
}
关于应用程序的多个实例,我们所做的是将应用程序服务器置于内部 ALB 下,然后为 nginx 服务器创建另一个服务作为一种 "application gateway",这次使用安装了 SSL 证书的外部 ALB。 Nginx 将请求定向到内部应用程序 ALB。这类似于 Remind 的 Empire 中显示的架构。
2018 年 7 月 25 日更新: Elastic Load Balancing 宣布支持 Application Load Balancer 的重定向和固定响应。
您可以在 AWS listener rules.
中找到更多信息
您无法在 ELB/ALB 上执行 HTTP 到 HTTPS 的重定向。
在 AWS 中有多种方法可以做到这一点。
- 在您的应用程序前面使用 AWS CloudFront 并在那里进行 SSL 重定向。您可以在 CDN 上享受边缘缓存的好处,但会花费更多。
- 在你的 NodeJS/Express 容器前面有一个像 Jwilder Nginx Proxy 这样的 Nginx 代理容器,并在代理处强制重定向。如果您对所有 NodeJS/Express 容器都有通用规则(例如 HTTP 到 HTTPS 重定向),那么这是一种方法。
- 为 NodeJS/Express 个内部装有 Nginx 的容器使用 docker 图像。
注意:由于您使用的是 Node/Express,因此最好在它前面安装一个像 Nginx 这样的 Web 服务器。查看以下 Whosebug Q/A 了解更多详情。
由于您使用的是 Express,因此您可以监听所有传入的请求并检查 x-forwared-proto header 是否为 "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());
我们的博客 post 中有更多关于此的信息:
https://snowball.digital/blog/force-https-behind-elastic-load-balancer-on-a-nodejs-application
基本上,AWS 负载均衡器现在支持来自 http 侦听器规则的 https 重定向(前提是您的应用程序正在将其中的 URL 从 http 重写为 https)。
导航:负载均衡器 > 侦听器 > HTTP:80 > view/edit 规则 > 添加规则(高于默认值)。规则应如下所示:
IF:
Source IP is 0.0.0.0/32
THEN:
Redirect to HTTPS://#{host}:443/#{path}?#{query}
Status code: HTTP_301
注意:还应该有一个 https 侦听器(具有有效证书,也可以自签名)侦听端口 443 才能正常工作。
我有一个集群(在自动缩放中可能有 N 个实例)并且我有一个网站服务是在 Node/Express 完成的。
我有一个弹性负载均衡器,它有一个目标组,监听器指向这个目标组的特定路径。
一切都按预期工作,网站加载,我可以使用和不使用 https 进行访问,但是如何使 HTTPS 强制从 HTTP 重定向?我在ECS中没有任何代理(不知道nginx-proxy是否支持我的集群中的多个实例)
谢谢
我认为 ALB/ELB 无法自行进行重定向。
This AWS article描述了如何为nginx设置重定向:
server {
listen 80;
server_name www.example.org;
if ($http_x_forwarded_proto != "https") {
rewrite ^(.*)$ https://$server_name$REQUEST_URI permanent;
}
}
this SO answer中的另一个选项:
if ($http_x_forwarded_proto = 'http') {
return 301 https://yourdomain.com$request_uri;
}
关于应用程序的多个实例,我们所做的是将应用程序服务器置于内部 ALB 下,然后为 nginx 服务器创建另一个服务作为一种 "application gateway",这次使用安装了 SSL 证书的外部 ALB。 Nginx 将请求定向到内部应用程序 ALB。这类似于 Remind 的 Empire 中显示的架构。
2018 年 7 月 25 日更新: Elastic Load Balancing 宣布支持 Application Load Balancer 的重定向和固定响应。 您可以在 AWS listener rules.
中找到更多信息您无法在 ELB/ALB 上执行 HTTP 到 HTTPS 的重定向。
在 AWS 中有多种方法可以做到这一点。
- 在您的应用程序前面使用 AWS CloudFront 并在那里进行 SSL 重定向。您可以在 CDN 上享受边缘缓存的好处,但会花费更多。
- 在你的 NodeJS/Express 容器前面有一个像 Jwilder Nginx Proxy 这样的 Nginx 代理容器,并在代理处强制重定向。如果您对所有 NodeJS/Express 容器都有通用规则(例如 HTTP 到 HTTPS 重定向),那么这是一种方法。
- 为 NodeJS/Express 个内部装有 Nginx 的容器使用 docker 图像。
注意:由于您使用的是 Node/Express,因此最好在它前面安装一个像 Nginx 这样的 Web 服务器。查看以下 Whosebug Q/A 了解更多详情。
由于您使用的是 Express,因此您可以监听所有传入的请求并检查 x-forwared-proto header 是否为 "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());
我们的博客 post 中有更多关于此的信息: https://snowball.digital/blog/force-https-behind-elastic-load-balancer-on-a-nodejs-application
基本上,AWS 负载均衡器现在支持来自 http 侦听器规则的 https 重定向(前提是您的应用程序正在将其中的 URL 从 http 重写为 https)。
导航:负载均衡器 > 侦听器 > HTTP:80 > view/edit 规则 > 添加规则(高于默认值)。规则应如下所示:
IF:
Source IP is 0.0.0.0/32
THEN:
Redirect to HTTPS://#{host}:443/#{path}?#{query}
Status code: HTTP_301
注意:还应该有一个 https 侦听器(具有有效证书,也可以自签名)侦听端口 443 才能正常工作。