node.js - 终止大量 SSL 连接具有成本效益

标签 node.js ssl openssl haproxy stunnel

我最近设置了一个基于 Node.js 的 Web 套接字服务器,该服务器经过测试可以在一个小型 EC2 实例 (m1.small) 上每秒处理大约 2,000 个新连接请求。考虑到 m1.small 实例的成本,以及将多个实例置于支持 WebSocket 的代理服务器(如 HAProxy)之后的能力,我们对结果非常满意。

但是,我们意识到我们尚未使用 SSL 进行任何测试,因此研究了一些 SSL 选项。很明显,在代理服务器上终止 SSL 连接是理想的,因为这样代理服务器可以检查流量并插入诸如 X-Forward-For 之类的 header ,以便服务器知道请求来自哪个 IP。

所以我研究了许多解决方案,例如 Pound、stunnel 和 stud,所有这些都允许终止 443 上的传入连接,然后传递到端口 80 上的 HAProxy,然后将连接传递到 Web 服务器.然而不幸的是,我发现向 c1.medium(高 CPU)实例上的 SSL 终止代理服务器发送流量非常快地消耗了所有 CPU 资源,而且每秒只有 50 个左右的请求。我尝试使用上面列出的所有三个解决方案,它们的性能与我假设的大致相同,它们都依赖于 OpenSSL。我尝试使用 64 位超大 High CPU 实例 (c1.xlarge),发现性能仅随成本线性扩展。因此,根据 EC2 定价,我需要为每秒 200 个 SSL 请求支付大约 600 美元/平方米,而每秒 2,000 个非 SSL 请求需要 60 美元/平方米。当我们开始计划每秒接受 1,000 或 10,000 个请求时,前一个价格在经济上很快变得不可行。

我还尝试使用 Node.js 的 https 服务器终止 SSL,其性能与 Pound、stunnel 和 stud 非常相似,因此该方法没有明显优势。

因此,我希望有人能提供帮助,建议我如何规避我们为提供 SSL 连接而必须承担的荒谬成本。我听说 SSL 硬件加速器提供了更好的性能,因为硬件是为 SSL 加密和解密而设计的,但是由于我们目前对所有服务器都使用 Amazon EC2,除非我们有单独的数据,否则不能使用 SSL 硬件加速器以物理服务器为中心。当成本如此之高时,我只是想看看亚马逊、谷歌、Facebook 等公司如何通过 SSL 提供所有流量。肯定有更好的解决方案。

任何建议或想法将不胜感激。

谢谢 马特

最佳答案

我不太了解不同 EC2 实例上可用的 CPU 能力,但我认为您的问题不在于您选择的 TLS 终止代理软件,而在于它们的配置。 如果没有任何配置,我假设他们都将提供他们支持的所有密码套件,包括(非常)慢的。他们可能也会让客户选择最喜欢的那个。

并非所有 TLS 密码套件生来都是平等的,有些套件的 CPU 成本高于其他套件,无论是来自 key 交换还是密码本身。 根据所使用的软件,应该有一种方法可以指定服务器接受的一串密码(还有一种方法可以让服务器坚持这一点)。对于 OpenSSL,这些工作方式如下:http://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS

如果您追求速度,至少要确保您没有使用采用 Diffie-Hellman(非椭圆曲线类型) key 交换的密码。 要禁用使用 DH key 交换的密码套件,请确保字符串在某些时候包含 !DH。 您可以测试哪些字符串导致哪些密码可用,例如,openssl ciphers -v 'HIGH:!aNULL:!DH:!ECDH'

此字符串禁用正常的 Diffie-Hellman 以及椭圆曲线 Diffie-Hellman key 交换。这可能只剩下 RSA key 交换,具体取决于您的 OpenSSL 版本。

关于密码,您可能应该在预期的 EC2 硬件上进行测试。如果没有硬件加速,您可能应该更喜欢 RC4 而不是 AES128 而不是 AES256,at least according to this benchmark .

我还建议阅读 this wonderful post ,尤其是第一个启发性的图表,显示了 DH 对 TLS 握手性能的影响。

最后,确保您使用的是 TLS session 缓存。这也节省了一些 CPU。

关于node.js - 终止大量 SSL 连接具有成本效益,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9067404/

相关文章:

node.js - HTTPS 证书 - 如何在我的架构上设置

PHPMailer SMTP 本地主机,证书错误

c++ - OpenSSL RSA_private_decrypt() 失败,返回 "oaep decoding error"

openssl - PyOpenSSL - 所有的加密功能在哪里?

node.js - 语音转文本 bing 语音 API Azure

javascript - 注入(inject)器错误在 angular.js 中找不到模块?

java - 如何使用 Java web 服务器实现 "privilege separation"的一些度量?

android - 有什么方法可以从 .c 和 .h 文件生成 JNI 文件?

javascript - Windows上的 Node npm错误寻找工具版本

ios - Ionic - 无法生成资源 ios