我正在尝试理解 AWS 的应用程序负载均衡器。我的情况有点复杂,我正在运行一个带有 nodejs 服务器的 ec2 实例,最终我只希望它仅通过 https 访问。因此,我最初在 443 上设置了一个侦听器,该侦听器在端口 443 上进行健康检查,并转发到以我的 ec2 实例为目标的组。
我有一本 Chef Cookbook,可以自动设置盒子、设置我的 nodejs 服务器,最后获取/设置 SSL 证书(使用 acmetool)。为了使它正常工作,盒子需要打开端口 402、4402 和 80。
因此,为了使其正常工作,我似乎需要 402、4402 和 80 的侦听器,然后——这需要为每一个端口创建单独的组?(这是我开始感到困惑的地方)..然后每个组都有自己的健康检查---所以我意识到,如果我最初没有 SSL 证书,我就无法在端口 443 上进行健康检查...所以这导致我在端口 12345 上创建另一个侦听器和组,然后让我的 nodejs 服务器响应 12345 上的健康检查......这看起来很奇怪,因为我基本上运行了两个 nodejs 服务器,一个在 12345 上仅用于健康检查,另一个在 443 上用于我的真实应用程序。
我必须使用 12345,因为 acmetool 有一个“重定向”守护进程,它监听端口 80 并将所有请求重定向到 443,除了它为颁发/更新证书而收到的 SSL 挑战请求。
所以……我的问题是,我似乎拥有所有这些组,它们现在在端口 12345 上都有相同的健康检查端点……这感觉非常低效,因为我只能假设这意味着负载均衡器将对同一端点执行 n 次 ping,每个组一次。这让我认为我一定是做错了。
答案1
我同意你的观点,你做错了。我的做法如下:
- ALB 监听端口 443,终止 SSL 流量。
- 使用 Amazon ACM 生成您的证书并将其附加到您的 HTTPS 侦听器。
- ALB 目标组将未加密的流量发送到实例上的端口 80。
- 实例的安全组仅允许从您的 ALB 访问端口 80。
因此实际上,您的客户端的请求路径是:
客户端 -> [HTTPS] -> ALB -> [HTTP] -> 实例
这实现了以下几点:
- 避免您必须在单个实例上管理 SSL 证书。您的应用程序仍然能够通过
X-Forwarded-Proto
ALB 在其请求中发送给您的标头确定客户端是否已加密(并且由于您只有一个 HTTPS 侦听器,因此此标头的值将始终为https
。 - 由于安全组限制仅来自 ALB 的端口 80 流量,因此您可以确保没有人可以访问您实例的端口 80。如果您的实例甚至没有公共 IP,那么这将提供进一步的保护。
- Amazon ACM 证书是免费的,并且还有一个额外的好处,那就是 Amazon 将为您处理和更新私钥(如果您使用 DNS 进行身份验证)。这消除了另一个麻烦。
唯一的警告是,您的流量一旦离开负载均衡器并发往您的实例,就不再加密。这通常是可以接受的,除非您出于合规原因要求所有流量都保持端到端加密状态。
在这种情况下,可以在您的实例上使用自签名证书(显然,我自己从未这样做过)。在这种情况下,您可以创建一个有效期较长的证书(可能 3 年),并使用 Opsworks App 的 SSL 证书部分上传它的各个部分。然后,它将在实例上的应用程序数据包中可用,您可以在启动服务之前从中提取 SSL 证书部分并将其安装到您的应用程序中。然后设置您的目标组以将流量路由到实例上的 HTTPS/443,并相应地修改健康检查和安全组。