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

Node.js通过node-ssh连接HP-UX服务器报read ECONNRESET认证失败

NodeSSH连接HP-UX服务器报ECONNRESET错误解决方案

问题现象

连接本地网络自托管HP-UX服务器时触发连接重置错误,报错信息如下:

Hello world
Connected to Nemesis
true
rejected: Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
  errno: -4077,
  code: 'ECONNRESET',
  syscall: 'read',
  level: 'client-socket'
}
node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error: read ECONNRESET
    at TCP.onStreamRead (node:internal/stream_base_commons:217:20) {
  errno: -4077,
  code: 'ECONNRESET',
  syscall: 'read',
  level: 'client-socket'
}

问题复现所用测试代码:

console.log('Hello world');

const { NodeSSH } = require('node-ssh');

const ssh = new NodeSSH();

ssh.connect({
    host: "server",
    username: "admin account",
    password: "password"
}).then(console.log("Connected to Nemesis"))

console.log(ssh.isConnected());

ssh.exec('hh_client', ['--json'], { cwd: '/', stream: 'stdout', options: { pty: true } }).then(fulfilled => {
    console.log("fulfilled:", fulfilled)
}).catch(rejected => {
    console.log("rejected:", rejected)
})

已确认的前置信息:

  • 修改服务器IP测试时会提示找不到服务器,基础网络连通性正常
  • 输入错误用户名/密码时触发完全相同的报错,账号密码参数未被正确用于认证
  • 代码中exec调用逻辑复制自node-ssh模块npm官方文档示例
  • 服务器为接手的存量HP-UX环境,.ssh目录下已有存量密钥配置,不能覆盖原有内容
  • 使用系统终端执行ssh user@server命令,输入相同用户名密码可以正常连接,账号拥有服务器完整操作权限

根因定位

  • 第一处问题是异步逻辑编写错误:ssh.connect()是异步返回Promise的方法,原代码中.then(console.log("Connected to Nemesis"))的写法会在调用connect时立刻执行日志打印,不会等待连接握手完成,后续的isConnected()检查、exec()命令调用都是在SSH连接还未建立完成时触发的。
  • 第二处问题是算法兼容问题:存量HP-UX环境搭载的OpenSSH版本普遍较低,默认仅支持较早版本的密钥交换、加密、主机密钥算法,node-ssh底层依赖的ssh2库默认启用的算法列表不包含这些老旧算法,连接会在算法协商阶段被服务端直接重置,根本不会走到用户名密码认证环节,这也是输入错误账号密码也报相同错误的核心原因。

修复方案

  1. 修正异步调用逻辑,必须等待connect方法的Promise状态变更为成功后,再执行后续的状态检查、命令执行操作。
  2. 在connect配置中显式添加兼容HP-UX老版本SSH的算法列表,该方案使用密码认证,完全不需要修改服务器.ssh目录下的任何存量文件,不会影响原有密钥认证配置。

修正后的可运行代码:

const { NodeSSH } = require('node-ssh');
const ssh = new NodeSSH();

async function runCommand() {
  try {
    // 建立SSH连接
    await ssh.connect({
      host: "替换为实际服务器地址",
      username: "替换为实际登录账号",
      password: "替换为实际登录密码",
      // 兼容HP-UX老版本SSH的算法配置
      algorithms: {
        kex: [
          'diffie-hellman-group1-sha1',
          'diffie-hellman-group14-sha1',
          'diffie-hellman-group-exchange-sha1'
        ],
        cipher: [
          'aes128-cbc',
          '3des-cbc',
          'aes192-cbc',
          'aes256-cbc'
        ],
        serverHostKey: [
          'ssh-rsa',
          'ssh-dss'
        ],
        hmac: [
          'hmac-sha1',
          'hmac-md5'
        ]
      }
    })
    console.log("连接成功,当前连接状态:", ssh.isConnected())
    // 执行目标命令
    const execResult = await ssh.exec('hh_client', ['--json'], {
      cwd: '/',
      stream: 'stdout',
      options: { pty: true }
    })
    console.log("命令执行结果:", execResult)
  } catch (err) {
    console.log("操作异常:", err)
  } finally {
    // 用完释放连接
    ssh.dispose()
  }
}

runCommand()
  1. 如果添加上述算法配置后仍连接失败,可以在本地终端执行ssh -vvv user@实际服务器地址,查看终端正常连接时协商成功的kex、cipher、serverHostKey、hmac算法值,将对应算法添加到上述algorithms配置数组的最前端即可。

注意:上述算法列表包含部分已被认定为不安全的老旧算法,仅适用于内网隔离的存量HP-UX环境,若后续服务器SSH服务完成升级,建议及时移除这些老旧算法配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:39:20