使用AWS ECS在Node / Express Web中强制ssl

问题描述 投票:1回答:3

我有一个集群(可以在自动扩展中有N个实例),我有一个服务,在Node / Express中完成了一个网站。

我有一个Elastic Load Balancer,它有一个Target Group,Listener指向这个目标组的特定路径。

一切都按预期工作,网站加载,我可以使用和不使用https访问,但我怎么能强制HTTPS从HTTP重定向?我在ECS中没有任何代理(不知道nginx-proxy是否支持我的集群中的多个实例)

谢谢

amazon-web-services amazon-ecs elastic-load-balancer jwilder-nginx-proxy
3个回答
3
投票

更新于2018年7月25日:Elastic Load Balancing宣布支持应用程序负载均衡器的重定向和固定响应。您可以在AWS listener rules找到更多信息。


您无法在ELB / ALB上执行HTTP到HTTPS重定向。

在AWS中有多种方法可以做到这一点。

  • 在应用程序前使用AWS CloudFront并在那里进行SSL重定向。您可以在CDN获得边缘缓存,但会花费更多。
  • 在NodeJS / Express容器前面有一个像Jwilder Nginx Proxy这样的Nginx代理容器,并在代理处强制重定向。如果您对所有NodeJS / Express容器(例如HTTP到HTTPS重定向)都有通用规则,则这是一种方法。
  • 对于内部具有Nginx的NodeJS / Express容器,请使用docker镜像。

注意:由于您使用Node / Express,因此最佳做法是在其前面安装Nginx等Web服务器。请查看以下Stackoverflow Q/A了解更多详情。


1
投票

我不认为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服务器创建另一个服务以充当一种“应用程序网关”,这次使用带有SSL证书的外部ALB安装。 Nginx将请求定向到内部应用ALB。这类似于Remind的Empire中显示的架构。


0
投票

由于您使用的是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

© www.soinside.com 2019 - 2024. All rights reserved.