使用 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 才能正常工作。