如何让 Amazon 的 ELB 与 HTTPS/SSL 与 Web Sockets 一起工作?
Posted
技术标签:
【中文标题】如何让 Amazon 的 ELB 与 HTTPS/SSL 与 Web Sockets 一起工作?【英文标题】:How do you get Amazon's ELB with HTTPS/SSL to work with Web Sockets? 【发布时间】:2012-02-29 09:22:52 【问题描述】:这似乎现在不起作用。我在 Amazon ELB 后面使用 Faye 和 NodeJS。当我打开 HTTPS 时,无法再代理连接。我在这里发现了一个未回答的问题:https://forums.aws.amazon.com/message.jspa?messageID=283293。任何人都能得到这个工作?除了运行我自己的 HAProxy 实例之外,还有其他解决方法吗?
【问题讨论】:
【参考方案1】:您可以使用 Application LB 来很好地支持 websocket。在 ALB 上实现了一些技巧后,我刚刚在我们最新的项目中实现了这个想法:
-
在所有相关 SG 上打开 80 端口
让 NodeJS 在 80 上运行
启用NodeJS响应http-80请求(NodeJS会在后端升级http请求到websocket)
让 ALB 目标组检查 http-80 和正确的 ping 路径
在 ALB 上创建侦听器:
http80->http80, https443->http80
在 ALB 上创建侦听器规则:http80->target group, https443->target group
在中启用http粘性
【讨论】:
您如何配置运行状况检查/ping 路径以使其正常工作? 我最终创建了一个单独的 HTTP 端点,仅用于健康检查。根据docs,“...健康检查不支持 WebSockets”。 @dskrvk 您在哪里以及如何为您的健康检查设置端点?你在为你的 ALB 运行 nginx 吗?我在同样的情况下没有运行 nginx,现在确定我应该为健康检查提供什么文件以及它应该响应什么? 我只是在我的应用程序(Node.js HTTP 服务器)中创建了另一个侦听器,它以状态 200 和字符串“OK”响应(尽管主体可以为空)。它可以是任何东西——可以是您在应用程序中定义的端点,也可以是 Apache 或 nginx 网络服务器的配置块。【参考方案2】:我确认,根据我们自己的测试,在 TCP/SSL 上配置 ELB,而不是 HTTP/HTTPS,使用 WebSockets 是成功的。缺点有两个:
1) 正如 arturnt 已经指出的,你不能得到粘性。
2) 您将失去检索客户身份的能力。您的 WebSocket 服务器看到的原始 IP 将始终是 ELB 之一,并且与 HTTP/HTTPS 配置不同,不会将 X-Forwarded-For 标头添加到请求中。
2013 年 7 月更新:亚马逊刚刚增加了对 代理协议 的支持,它解决了上面的第 2 个缺点。使用代理协议,即使 ELB 在 TCP 级别而不是 HTTP 上工作,也会添加包含客户端原始 IP 的标头。完整详情:http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html
2016 年 8 月更新:亚马逊刚刚宣布了新的 AWS Application Load Balancer,它支持第 7 层的 WebSocket(以及 HTTP/ 2.0 和基于内容的路由)。见https://aws.amazon.com/it/blogs/aws/new-aws-application-load-balancer/
【讨论】:
第二个选项可以使用WSS吗? ...还有a module to deal with the PROXY protocol。 ...或上述模块的当前活动fork。 无法使用粘性会话使得无法有效地将 ELB 与 websockets 一起使用,因为它每次都需要连接到同一个实例,这是无法保证的。 @loourr 正确,我希望看到这确实有效,因为我们已经尝试了一段时间......【参考方案3】:在 James 的回答之后,我做了更多的研究并最终选择了 TCP 路由,但不确定使用 ELB 的 HTTP 隧道有什么缺点(考虑到我不需要粘性)。好消息是你不需要做螺柱/隧道,因为 ELB 为你提供了。因此,NodeJS/Faye 在端口 8000 上侦听的最终 ELB 设置:
Secure TCP Forward (443) -> Local (8000)
TCP Forward 80 -> Local(8000)
【讨论】:
缺点是粘性,如果当前选择的服务器返回错误,ELB 能够将请求转发到不同的服务器。【参考方案4】:它不起作用,ELB 的 HTTP(S) 代理至少目前不理解 websocket 请求,我不知道何时/是否计划。
我不确定 HAProxy 是否完全必要。应该可以放置 SSL 终止符,例如stud/stunnel,在与你的 nodejs 服务器相同的实例上并通过这种方式。然后,您可以保留 ELB,但将其置于 TCP 模式。
显然每个实例都存在 SSL 开销,但从长远来看,这可能比将 SSL 卸载到 ELB(特别是基于用户对 ELB 的 SSL 性能的 cmets )更好。
【讨论】:
通常更希望在 AWS ELB 处终止 SSL,只要这样可以在一个地方轻松地更新证书。这也意味着潜在易受攻击的应用程序代码无权访问证书。当然,缺点是 ELB 和应用程序之间的通信是未加密的,但这可以通过 VPC 和强化网络安全来缓解。以上是关于如何让 Amazon 的 ELB 与 HTTPS/SSL 与 Web Sockets 一起工作?的主要内容,如果未能解决你的问题,请参考以下文章