允许node.js HTTPS请求的所有SSL协议。

4
有没有可能让node.js的https.request(客户端)与远程服务器协商任何可能的协议(即使不安全)? 我了解安全风险,但对于我的项目,有些网站只能使用较旧/不安全的SSL协议和密码才能正常工作。
例如:https://www.dot.ny.gov在Ubuntu Server 16.04上使用curl或最新的node.js 7.10.1默认配置时无法使用(超时)。 只有使用curl选项--tlsv1.0或--sslv3才能正常工作。
那么有没有一种方法可以使node.js重新协商使用一系列协议的SSL连接(从最安全到最不安全),或者使用最广泛的配置(通过node.js或底层OpenSSL)以启用所有SSL协议和密码?

不允许任何匿名密码套件。 - user207421
2个回答

3
仅允许这些协议并不能解决你所描述的网站问题。TLS 的设计大多是向后兼容的,即如果一个正确实现的服务器只能使用 SSL 3.0 或 TLS 1.0,则当其遇到支持 TLS 1.2 的客户端的 ClientHello 时,它将只回复最佳支持的协议。这是因为客户端只会宣布它所支持的最佳版本,然后服务器选择等于或小于客户端提供的版本中最佳的版本。只有在这种情况下,“允许”才会起作用,即如果客户端接受服务器以较低版本回复。但这不是你展示的网站的问题。在这种情况下,服务器或前面的某个中间框架具有错误的 SSL/TLS 堆栈,它会在出现意外的 ClientHello 时失败。这些可能是一些意外的 TLS 版本、意外的扩展、过小或过大的意外密码等奇怪情况。
在这种情况下,TLS协议版本似乎根本不是问题,但更像是ClientHello的大小是一个问题,可能是因为有一个旧的F5负载均衡器在其前面发生了this bug。由于浏览器往往只提供几个密码,他们的ClientHello大多数时候足够小而不会受到这个问题的影响。例如,如果您尝试减少密码套件的数量,如openssl s_client -connect www.dot.ny.gov:443 -cipher 'AES128-SHA',即使使用TLS 1.2 ClientHello,也会成功,但如果您尝试更大的密码套件(如-cipher 'AES'),它将仅挂起而没有得到响应,可能是因为破损的负载均衡器无法处理大的ClientHello。并且通过在命令行中强制执行TLS 1.0,您只需确保它不会提供新的TLS 1.2密码套件,从而减小了ClientHello的大小。
没有通用的方法来处理这样的破损服务器,因为“允许”的部分仅在服务器回复后出现(在这种情况下不存在),有些实际上可能会导致更多的问题(例如提供过多的密码,这会增加ClientHello的大小)。相反,我们必须调试问题,找出破损服务器喜欢和不喜欢的内容,然后设计一个特定的TLS握手(版本、密码、扩展、大小等),以使服务器喜欢它。了解特定服务器接受什么的好方法是查看SSLLabs的分析

感谢您的解释,Steffen。我想知道在这种情况下,Web浏览器如何重新协商,但是node.js或curl不能做到这一点?尽管SSLLabs测试报告该网站存在许多问题,但它在Chrome和Firefox中加载正常。我希望node.js的https.request可以成功地与这些仅支持旧协议和密码的网站握手。 - Nick
1
@Nick:有时浏览器也会崩溃。有时,如果第一次请求失败,它们会尝试使用较低的协议版本,尽管它们似乎不再采用这种行为,而倾向于期望服务器进行修复。在这种特定情况下,它们可能只是运气好,并没有受到影响,因为它们提供的加密套件较少,这导致ClientHello更小-请查看编辑后的答案获取详细信息。 - Steffen Ullrich

0

用于进行HTTP(S)请求的最受欢迎的NPM包之一是request。根据其文档,您可以指定要接受哪些SSL协议。

如果您事先知道要访问哪些站点以及它们使用的协议,您可以针对每个请求设置它。否则,我想您可以编写一些条件语句,尽管进行多个请求的开销会很繁琐。


请求库现已弃用。 - raphaklaus
我今天在Nodejs中考虑使用进行HTTP(S)请求的包将是"Axios"和"Got"。 - Niels de Bruin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接