You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ssh2-sftp-client连接SFTP报ERR_GENERIC_CLIENT握手超时问题

问题定位

从调试日志看,错误根因是SSH握手阶段超时,命令行可以正常连接但代码连接失败,按出现概率排序,触发原因如下:

  • ssh2-sftp-client底层依赖ssh2库,默认握手超时时间仅10秒,跨网段、企业内网SFTP设备做了流量审计、密钥交换计算耗时较长时,10秒不足以完成握手流程,而命令行sftp客户端默认超时时间远大于该值,因此可以正常连接。
  • 现有代码存在两个隐性bug:一是Promise.all的回调中没有给sftp.put加await,上传任务未执行完就会进入后续流程;二是没有在finally块主动关闭SFTP连接,长期运行会出现句柄泄漏。
  • 部分老旧内网SFTP服务器仅支持旧版密钥交换、加密算法,ssh2库出于安全考虑默认禁用了这些旧算法,会导致算法协商阶段卡住直到超时。
  • 若代码运行在容器/云主机环境,需确认Node进程的出网规则,部分环境会限制非系统命令进程的22端口访问,出现命令行可连但代码连不上的情况。
修复方案

按以下顺序调整即可:

  1. 调整连接配置,延长握手超时时间,添加兼容算法配置
    给connect参数增加readyTimeout字段(单位毫秒,建议先设为30000,网络差可调整为60000),同时添加兼容新旧SFTP服务端的算法列表,避免协商卡住,注意端口要强制转数字类型,避免配置读成字符串导致连接异常:
await sftp.connect({
  host: SFTP.HOST,
  port: Number(SFTP.PORT),
  username: SFTP.USERNAME,
  password: SFTP.PASSWORD,
  readyTimeout: 30000,
  algorithms: {
    kex: [
      'ecdh-sha2-nistp256', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp521',
      'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group14-sha256',
      'diffie-hellman-group15-sha512', 'diffie-hellman-group16-sha512',
      'diffie-hellman-group14-sha1'
    ],
    cipher: [
      'aes128-ctr', 'aes192-ctr', 'aes256-ctr',
      'aes128-gcm', 'aes128-gcm@openssh.com',
      'aes256-gcm', 'aes256-gcm@openssh.com',
      'aes128-cbc', 'aes192-cbc', 'aes256-cbc'
    ]
  }
})
  1. 修复代码逻辑问题,移除冗余的.then链,统一用async/await,给上传操作加await,最后主动关闭连接
    修正后的完整代码参考:
import Client from 'ssh2-sftp-client';
import config from 'config';
import logger from './logger';

const upload = async csvFiles => {
  const sftp = new Client();
  try {
    const SFTP = config.get('SFTP');
    const remotePath = SFTP.REMOTE;

    await sftp.connect({
      host: SFTP.HOST,
      port: Number(SFTP.PORT),
      username: SFTP.USERNAME,
      password: SFTP.PASSWORD,
      readyTimeout: 30000,
      algorithms: {
        kex: [
          'ecdh-sha2-nistp256', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp521',
          'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group14-sha256',
          'diffie-hellman-group15-sha512', 'diffie-hellman-group16-sha512',
          'diffie-hellman-group14-sha1'
        ],
        cipher: [
          'aes128-ctr', 'aes192-ctr', 'aes256-ctr',
          'aes128-gcm', 'aes128-gcm@openssh.com',
          'aes256-gcm', 'aes256-gcm@openssh.com',
          'aes128-cbc', 'aes192-cbc', 'aes256-cbc'
        ]
      }
    });

    await Promise.all(
      csvFiles.map(file => {
        const fileName = file.split(/[\\/]/).pop();
        return sftp.put(file, `${remotePath.replace(/\/$/, '')}/${fileName}`);
      })
    );

    logger.log({ level: 'info', message: 'sftp-success' });
  } catch (err) {
    logger.log({ level: 'error', message: 'sftp-error', err });
  } finally {
    await sftp.end();
  }
};

module.exports = upload;
  1. 若调整后仍超时,在代码运行的环境下,用和启动Node服务相同的系统用户执行sftp <用户名>@<SFTP地址> -p <端口>验证连通性,同时执行nc -zv <SFTP地址> <端口>确认端口可达,排除系统级网络策略、权限限制问题。

内容的提问来源于stack exchange,提问作者William Mandang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:06:31