解决 Node.js 中 "SSL routines:final_renegotiate:unsafe legacy renegotiation disabled" 错误
问题背景
当你使用 Node.js 与一些较旧的服务器(特别是 IIS)建立 HTTPS 连接时,可能会遇到以下错误:
SSL routines:final_renegotiate:unsafe legacy renegotiation disabled
这个错误源于一个已知的安全漏洞 CVE-2009-3555,Node.js 从版本 17/18 开始移除了对不安全旧版 SSL 重新协商的支持,以增强安全性。
问题根源
CVE-2009-3555 安全漏洞
该漏洞允许攻击者在 SSL/TLS 会话中注入任意明文,可能导致会话劫持和其他安全问题。因此,现代 Node.js 版本默认禁用了这种不安全的旧版重新协商方式。
IIS 服务器的兼容性问题
许多旧版 IIS 服务器仍然使用这种不安全的重新协商方式,而 Node.js 的默认配置不再允许这种连接。这就是为什么你会遇到这个错误,即使尝试使用 Node.js 标志也无法忽略它。
解决方案
使用自定义 HTTPS Agent 允许旧版连接
对于必须与这些旧服务器通信的情况,可以通过创建自定义 HTTPS Agent 来允许旧版 SSL 连接:
import crypto from 'crypto';
import https from 'https';
import axios from 'axios';
const allowLegacyRenegotiationforNodeJsOptions = {
httpsAgent: new https.Agent({
secureOptions: crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT,
}),
};
export const request = axios.create({
...allowLegacyRenegotiationforNodeJsOptions,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
// ...
});
方案说明
-
crypto.constants.SSL_OP_LEGACY_SERVER_CONNECT
这个选项明确告诉 Node.js 允许与使用旧版 SSL 重新协商的服务器建立连接。 -
自定义 HTTPS Agent
通过创建自定义的https.Agent,我们可以覆盖默认的安全设置,同时保持其他安全功能不变。
安全注意事项
虽然这个解决方案可以解决问题,但需要注意:
-
安全风险
启用旧版重新协商会降低连接的安全性,可能使你的应用面临中间人攻击等风险。 -
临时解决方案
这应该被视为临时解决方案,长期来看应该升级服务器端以支持现代 SSL/TLS 协议。 -
范围限制
尽量只对特定的、必要的连接启用此选项,而不是全局设置。
替代方案
如果可能,考虑以下更安全的替代方案:
-
升级服务器
将 IIS 服务器升级到支持现代 TLS 协议的版本。 -
使用代理
在中间层设置一个代理服务器,处理与旧服务器的安全连接,而你的 Node.js 应用则与代理使用现代协议通信。 -
联系服务提供商
如果是第三方服务,联系他们升级其 SSL/TLS 配置。
总结
当遇到 "SSL routines:final_renegotiation:unsafe legacy renegotiation disabled" 错误时,可以通过创建自定义 HTTPS Agent 并设置 SSL_OP_LEGACY_SERVER_CONNECT 选项来解决与旧版服务器的兼容性问题。但请记住,这只是一个临时解决方案,从安全角度考虑,应该尽快升级服务器端以支持现代安全协议。
在实施此解决方案时,务必评估潜在的安全风险,并尽可能限制其使用范围,只在绝对必要的情况下启用旧版 SSL 重新协商支持。

浙公网安备 33010602011771号