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

Node.js连接EC2实例遇ECONNREFUSED错误,Shell可正常连接

解决方案:EC2 SSH连接ECONNREFUSED问题及简化远程命令执行方法

一、解决ECONNREFUSED错误

1. 等待实例完全就绪,而非仅Running状态

实例状态变为running不代表系统已初始化完成、sshd服务已启动。需等待实例的系统状态检查和实例状态检查均通过,可通过AWS SDK的waitFor方法实现:

const { EC2Client, waitUntilInstanceStatusOk } = require("@aws-sdk/client-ec2");

const ec2Client = new EC2Client({ region: 'your-region' });
const params = { InstanceIds: ["i-xxxxxx"] };

// 等待实例状态检查通过,最长等待5分钟,每10秒检查一次
await waitUntilInstanceStatusOk({
  client: ec2Client,
  maxWaitTime: 300,
  minDelay: 10,
}, params);

2. 验证ssh2连接配置细节

  • 密钥格式:确保加载的私钥是完整的PEM格式,读取时保留原始内容:
    const privateKey = fs.readFileSync('./your-key.pem', 'utf8');
    
  • 实例用户名:根据AMI镜像选择正确用户名(Amazon Linux 2用ec2-user,Ubuntu用ubuntu,CentOS用centos),用户名错误可能间接导致连接失败。
  • 端口与IP:确认公网IP无误,本地防火墙或代理未拦截22端口。

3. 增加连接重试机制

即使实例状态检查通过,sshd可能仍有短暂启动延迟,可添加重试逻辑:

const connectWithRetry = (conn, config, retries = 3) => {
  return new Promise((resolve, reject) => {
    const attempt = () => {
      conn.connect(config);
      conn.once('ready', resolve);
      conn.once('error', (err) => {
        if (retries > 0) {
          retries--;
          setTimeout(attempt, 5000); // 5秒后重试
        } else {
          reject(err);
        }
      });
    };
    attempt();
  });
};

二、更简便的Node.js远程执行EC2命令方法

1. 使用AWS Systems Manager (SSM) Run Command

无需开放SSH端口、无需管理密钥对,直接通过AWS API执行命令,安全且便捷:

const { SSMClient, SendCommandCommand, GetCommandInvocationCommand } = require("@aws-sdk/client-ssm");

const ssmClient = new SSMClient({ region: 'your-region' });

// 发送命令
const sendCommand = async (instanceId, commands) => {
  const commandParams = {
    DocumentName: "AWS-RunShellScript",
    InstanceIds: [instanceId],
    Parameters: { commands }
  };
  const command = new SendCommandCommand(commandParams);
  const response = await ssmClient.send(command);
  return response.Command.CommandId;
};

// 查询命令执行结果
const getCommandResult = async (commandId, instanceId) => {
  const resultParams = {
    CommandId: commandId,
    InstanceId: instanceId
  };
  const resultCommand = new GetCommandInvocationCommand(resultParams);
  return await ssmClient.send(resultCommand);
};

// 调用示例
(async () => {
  const commandId = await sendCommand('i-xxxxxx', ['echo "Hello from SSM"', 'ls -l']);
  console.log('命令ID:', commandId);
  // 等待命令执行完成后查询结果
  setTimeout(async () => {
    const result = await getCommandResult(commandId, 'i-xxxxxx');
    console.log('执行结果:', result.StandardOutputContent);
  }, 10000);
})();

注意:需确保实例已安装SSM Agent(Amazon Linux 2默认预装),且实例关联的IAM角色拥有AmazonSSMManagedInstanceCore权限。

2. 使用node-ssh简化SSH操作

基于ssh2封装的上层库,API更简洁:

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

(async () => {
  try {
    await ssh.connect({
      host: '54.241.142.163',
      username: 'ec2-user',
      privateKey: './your-key.pem'
    });
    const result = await ssh.execCommand('echo "Hello from node-ssh"');
    console.log('输出:', result.stdout);
    await ssh.dispose();
  } catch (err) {
    console.error('错误:', err);
  }
})();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:33:27