Node FTPS 报 session reuse required:比较直接 TLS 与 socket 升级路径
FTPS 控制连接成功而数据连接报 522 时,检查 tls.connect 是否通过已有 net.Socket 传递 session。区分会话复用、证书验证和服务端安全要求。
FTPS 可以登录,开始传文件却报 522 SSL connection failed: session reuse required。如果客户端把已连接的 net.Socket 交给 tls.connect({ socket, session }),检查 TLS 会话是否真的被复用,而不是先去改账户或被动端口。
Node.js 22.23.1 中有一个具体回归:直接用 host、port 建立 TLS 并传入 session 可以复用;用已经连接到 IP 的 socket 升级 TLS 时,同样的 session 却没有恢复。故障范围是这组连接方式和版本,不能扩展成所有 FTPS 522 都由 Node 引起。
先区分 TCP 复用与 TLS 会话复用
FTPS 的控制连接和数据连接通常是不同的 TCP 连接。服务端要求的是数据连接恢复相关 TLS 会话,不是要求在同一条 TCP socket 上传所有内容。修改 HTTP Agent 的 keep-alive 设置与这里无关。
在数据连接的 secureConnect 后,通过现有诊断入口查看:
const reused = dataSocket.isSessionReused();
其中 dataSocket 是真正用于传输的 TLSSocket。结合控制连接获取会话的时机、目标地址、SNI 和 TLS 版本判断;没有取得有效 session、会话过期或服务端本来拒绝恢复,也会使结果为 false。不要把会话字节或认证信息写进日志。
控制连接方式可调整时,评估直接建立 TLS
如果客户端设计允许自行创建数据 TLS 连接,可在保留原连接参数的前提下,评估让 tls.connect 建立连接,而不是先创建 net.Socket 再升级。核心参数关系如下,值由应用原连接流程提供:
import tls from 'node:tls';
const dataSocket = tls.connect({
host: dataHost,
port: dataPort,
servername: certificateHost,
session: controlSession,
ca: trustedCA,
});
这不是可直接粘贴的完整 FTP 客户端;还需原来的握手时序、错误处理、超时、数据流和关闭逻辑。certificateHost 应为证书验证所需的真实 DNS 名,trustedCA 来自原有信任配置。不能通过关闭证书验证或把 IP 硬写进 servername 绕过问题。
如果数据通道必须经过代理隧道或第三方库内部创建的 socket,直接建连接会改变网络路径,就不适用。应等待或选择经核对包含对应修正的正式运行时/客户端组合,不要给 socket 的私有 _host 字段随意补值。
版本升级需要看真正改到哪条路径
相关修正方向是在 IP 连接的快速路径前保留主机身份,供 TLS 会话绑定使用。已核对的 Node 22.23.2 正式 net.js 仍在 IP 快速分支之后写 _host,该正式版本尚保留这条路径;后续选型须核对目标发行版的对应源码变化。
验收应在相同服务端要求下覆盖登录、数据 TLS 的 isSessionReused() 和真实读写结果,同时确认认证、SNI、证书信任与代理路径保持正确。撤回连接构造调整时恢复原客户端入口;不要通过关闭服务端的会话复用要求来证明客户端恢复。


