StackExchange 网站的一名用户 Matt Goforth 对于 SSL 在负载均衡设备上的处理提出了他的疑惑:
对于集群式的 web 应用来说,一种常见的做法是在集群与公网之间添加一道反向代理(例如 HAProxy、Nginx 和 F5 等等),以实现应用服务器的流量负载均衡。为了对数据包进行深入探测,必须在负载均衡这一层(或者是更靠前的阶段)将 SSL 进行卸载。但这样一来,负载均衡与应用服务器之间的流量就处于未加密的状态。这种在入口处对 SSL 进行卸载的做法是否会为应用服务器带来数据包嗅探或 ARP 欺骗的风险呢?
SSL 是否应该被卸载呢?如果答案是肯定的,要怎样做才不会降低数据传递的完整性呢?我主要担心的地方在于 web 应用,它本身是无法实现消息层的加密的。
在这个问题的最高票回答中,用户 CHI Coder 007 表示:
在我看来,你的问题主要在于 “你是否信任你的数据中心”。换句话说,看起来你正试图找到一条分界线,一边是无法信任的网络,另一边则是可信赖的起点。
按我的观点来看,SSL/TLS 信任应当在 SSL 卸载设备这一层就结束了,原因在于管理这些设备的部门通常也负责网络与基础设施的管理。这里面有很大一部分信任是受到契约的约束的。而对于下游服务器的传输数据加密是没有意义的,因为通常来说,负责网络的人员往往也能够访问到这些服务器(这里面可能会有一些例外,比如多租户环境,或是某些业务需求强制要求更深入的分离性)。
在负载均衡上卸载 SSL 的第二个原因在于,它是处理 SSL 攻击,例如 CRIME 或 BEAST 等行为的中央核心。如果你选择在运行着不同操作系统的各个 web 服务器上卸载 SSL,很可能会因为额外的复杂度而遇到各种问题。将问题尽量简单化,从长期来看将减少你的麻烦。
简而言之,
- 是的,应当在负载均衡设备上完成 SSL 卸载,让问题简单化。
2.(举例来说)Citrix Netscaler 能够阻止对某个 URL 的不安全访问,将这种策略逻辑与 TLS 的相关特性相结合,就能够确保你的数据可靠,不被篡改(假设我对于你的数据完整性需求的理解是正确的)。不过,你有可能遇到以下情形(也是比较常见的):
a. 使用外部提供的负载均衡服务(例如亚马逊和微软的服务)
b. 使用第三方的 CDN (例如 Akamai、亚马逊和微软等等)
c. 或是使用第三方代理以避免 Dos 攻击在这些情况下,来自第三方的流量将通过你所无法控制的网络链接发送至你的服务器,这些未加密的链接有可能是不可信的。在这种情况下,你应当重新对数据进行加密,或者至少通过点对点的
VPN 进行数据传输。微软就提供了这样一种 VPN 产品,这就让你能够将网络边界的安全交由它负责。
用户 JZeolla 也赞成这样的做法:
是的,我也赞同将 TLS 进行卸载的做法。以下的方法我都是在 Citrix Netscaler 上尝试的,但我相信 F5 也能够实现同样的功能。
首先,你需要确保在负载均衡设备的另一头对数据重新加密,但对 TLS
进行解密的设备应当能够从安全角度发现问题。这种方式不应当成为数据完整性降低的借口。许多人告诉我,在后端进行重新加密将带来巨大的计算负担,但事实并非如此。TLS 的资源消耗来自于连接的建立与关闭操作,而这将由 TLS 卸载设备完成。在后端,你将与服务器建立起更持久的连接,这将大大减少所消耗的资源。
此外,如果你不对 TLS 进行卸载,那么哪怕是一次通过 TLS 发起的小型 DDos 攻击也将使你的服务器完全瘫痪。我对这种情形非常熟悉,而 TLS 卸载从计算方面能够起到非常大的作用,并且让你能够在入口阶段就封死攻击。对于特大型的 DDoS 攻击来说,你还可以在 TLS 卸载设备与服务器之间分担缓解的对策。
用户 Tom Leek 对于 SSL 连接中的数据嗅探做了较深入的讲解:
为了嗅探通过 SSL 连接进行传输的数据,必须满足以下两个条件之一:
1. 传输通道中止于负责进行嗅探的机器上,亦即你所说的"负载均衡设备"。
2. 嗅探系统已获取服务器私钥的一份拷贝,并且 SSL 连接没有使用短期的 Diffie-Hellman 密钥交换算法(也就意味着服务器不允许名字中包含 “DHE” 的密码集。)如果你选择第一种方式,那么数据在嗅探系统(即负载均衡器)与集群之间的传输是不加密的,除非你选择其他的 SSL 通道对数据重新加密。在这种方式下,主要的 SSL 连接是在客户端与负载均衡设备之间,而后者会在其自身与每个集群的节点间维护一个 SSL link(或是选择其他某些加密技术,例如某种实现了 IPsec 的 VPN)。
第二种方式更轻量级一些,因为数据包嗅探器只需要对数据进行解密,而无需进行重新加密。不过,这也意味着服务器上的所有节点都能够与客户端进行完整的 SSL 通信,也就必须获取服务器的私钥信息。此外,由于不支持 DHE,也就代表你无法享受到 Perfect Forward Secrecy 特性所带来的好处(虽然问题不算特别严重,但是 PFS 对于安全审计来说非常实用,最好能够保留它)。
无论哪种方式,负责进行尝试数据包嗅探的节点必须获取 SSL 通道的某些访问特权,因此对于安全方面来说是个风险。
Ralph Bolton 则给出了一些具体做法的建议:
我也支持在负载均衡器(例如你自己的网络设备,或是第三方 CDN 提供商等技术)上卸载 SSL,这样可以使负载均衡器对流量进行嗅探,并更好地发挥负载均衡的功效。同时,这也意味着你的负载均衡器需要负责处理慢客户端、错误的 SSL 实现以及一般性的互联网的缺陷。为此,你可能要为负载均衡器投入更好的资源,而不是后端服务器。然后,这同样也表示在全世界通行的 SSL 证书都在负载均衡器上设置(希望这能够让维护这些证书的工作变得简单一些)。
有一种可选的方案是简单地将客户端的 TCP 连接均衡地在后端服务器上进行负载,由于负载均衡器在这种情况下无法了解具体细节,因此也无法在后端服务器上做到负载的平衡,而后端服务器也需要直接处理各种互联网的问题。对我来说,只有在对于负载均衡器、CDN 提供商等技术无法信任的情况下才会做出这种选择。
至于是否要在负载均衡器与后端服务器之间进行重新加密,则由你个人偏好与实际情况而定。如果你需要处理信用卡或金融交易,很可能受到政府的管控,那么就必须选择重新加密。另外,如果负载均衡器是通过不可信的网络与后端服务器之间进行流量交换,也应当选择重新加密。反之,如果你只是运行一个公司的网站,并且对于它的安全关心并不太在意,那么也可以选择免除重新加密带来的麻烦。
重新加密所带来的开销或许没有你想象中那么高,通常来说,负载均衡器能够与后端服务器之间维持一个长连接,SSL 的开销在这种网络中是非常小的。
最后需要考虑的一件事是后端服务器上运行的应用。如果所有到来的流量都是 HTTP 形式,则应用就无法根据客户端所使用的协议来进行相应的决策。举例来说,它无法做到"你正在尝试通过 HTTP 方式访问登录页面,我会将你重定向到该页面的 HTTPS 版本上"等操作。你或许可以让负载均衡器添加一个 HTTP header,以表示该请求原本来自于 HTTPS,但必须在应用中对于这个 header 进行特殊处理。在某些情况下,选择进行重新加密,并让应用以默认的方式运行,或许比起针对站点的情况而进行特殊的改造来得更合适。
我的结论是:在负载均衡器上进行卸载,并在发送至后端服务器时进行重新加密。如果按这种方式操作时遇到某些问题,而按需要进行一些调整。
最后的一个回答来自于用户 Davis:
你可以选择通过某种较简单的密钥证书对内部流量进行加密。另外,建议你尽量缩短负载均衡器与服务器之间的路径,以避免内部传输中的嗅探或攻击。SSL 可以在负载均衡器上进行卸载,以减轻 web 服务器处理这种 CPU 密集型任务的压力。而如果你选择的负载均衡设备品牌能够支持更丰富的功能,例如检测恶意协议连接、检测 DDoS 行为,那就更棒了。
查看英文原文: https://security.stackexchange.com/questions/30403/should-ssl-be-terminated-at-a-load-balancer
感谢张婵对本文的策划和审校。
评论