【问题标题】:How to SSH into a server from a node.js application?如何从 node.js 应用程序通过 SSH 连接到服务器?
【发布时间】:2021-09-29 05:34:51
【问题描述】:
var exec = require('child_process').exec;

exec('ssh my_ip',function(err,stdout,stderr){
    console.log(err,stdout,stderr);
});

这只是冻结 - 我猜,因为 ssh my_ip 要求输入密码,是交互式的,等等。如何正确执行?

【问题讨论】:

  • 您可以配置和设置您的ssh 使用公钥以避免需要任何密码。读好ssh tutorial

标签: linux node.js ssh child-process


【解决方案1】:

有一个 node.js 模块被编写用于在 SSH 中使用由 mscdex 称为 ssh2 的节点执行任务。可以在 here. 找到您想要的示例(来自自述文件):

var Connection = require('ssh2');

var c = new Connection();
c.on('connect', function() {
  console.log('Connection :: connect');
});
c.on('ready', function() {
  console.log('Connection :: ready');
  c.exec('uptime', function(err, stream) {
    if (err) throw err;
    stream.on('data', function(data, extended) {
      console.log((extended === 'stderr' ? 'STDERR: ' : 'STDOUT: ')
                  + data);
    });
    stream.on('end', function() {
      console.log('Stream :: EOF');
    });
    stream.on('close', function() {
      console.log('Stream :: close');
    });
    stream.on('exit', function(code, signal) {
      console.log('Stream :: exit :: code: ' + code + ', signal: ' + signal);
      c.end();
    });
  });
});
c.on('error', function(err) {
  console.log('Connection :: error :: ' + err);
});
c.on('end', function() {
  console.log('Connection :: end');
});
c.on('close', function(had_error) {
  console.log('Connection :: close');
});
c.connect({
  host: '192.168.100.100',
  port: 22,
  username: 'frylock',
  privateKey: require('fs').readFileSync('/here/is/my/key')
});

【讨论】:

  • 很好,但是 telnet 呢? (和其他交互式命令)
  • 我找到了this telnet 客户端node.js 模块。如果您不熟悉,npmjs.org 是一个非常大的 node.js 包注册表。
  • 它需要 python,它不能使它成为真正的节点模块,它只是使用 exec 执行一些 python 命令
【解决方案2】:

此页面上的其他库具有较低级别的 API。

所以我为它写了一个轻量级的包装器。 node-ssh 在 MIT 许可下也可以在 GitHub 上使用。

这是一个如何使用它的示例。

var driver, ssh;

driver = require('node-ssh');

ssh = new driver();

ssh.connect({
  host: 'localhost',
  username: 'steel',
  privateKey: '/home/steel/.ssh/id_rsa'
})
.then(function() {
  // Source, Target
  ssh.putFile('/home/steel/.ssh/id_rsa', '/home/steel/.ssh/id_rsa_bkp').then(function() {
    console.log("File Uploaded to the Remote Server");
  }, function(error) {
    console.log("Error here");
    console.log(error);
  });
  // Command
  ssh.exec('hh_client', ['--check'], { cwd: '/var/www/html' }).then(function(result) {
    console.log('STDOUT: ' + result.stdout);
    console.log('STDERR: ' + result.stderr);
  });
});

【讨论】:

  • 这并不可怕,它只是一个更完整的示例,无需阅读更多文档即可启动和运行。我可以很容易地省略许多事件处理程序以减小大小...
  • @mscdex,我知道你可以留下一些事件处理程序,但是这个库让它太简单了,我的意思是没有它你必须做 .on('data').on('close').on('error'),但有了它,它只是一个简单的函数,你得到了结果
  • @SteelBrain 你的 rsa 密钥不能正常工作!
  • @johnshumon 确实如此!它只是真正的ssh2 模块的代理,它不会尝试自己做任何新的或更少的事情
  • 我喜欢这个界面。当您只需要运行一些简单的命令来返回承诺而不是使用事件发射器时,这在我的书中是很棒的。也就是说,@mscdex 首先为我们编写了一个 SSH 库!
【解决方案3】:

检查我的代码:

// redirect to https:
app.use((req, res, next) => {
    if(req.connection.encrypted === true) // or (req.protocol === 'https') for express
        return next();

    console.log('redirect to https => ' + req.url);
    res.redirect("https://" + req.headers.host + req.url);
});

【讨论】:

    【解决方案4】:

    最好的方法是使用promisifyasync/await。示例:

    const { promisify } = require('util');
    const exec = promisify(require('child_process').exec);
    
    export default async function (req, res) {
      const { username, host, password } = req.query;
      const { command } = req.body;
    
      let output = {
        stdout: '',
        stderr: '',
      };
    
      try {
        output = await exec(`sshpass -p ${password} ssh -o StrictHostKeyChecking=no ${username}@${host} ${command}`);
      } catch (error) {
        output.stderr = error.stderr;
      }
    
      return res.status(200).send({ data: output, message: 'Output from the command' });
    }
    

    【讨论】:

      【解决方案5】:

      通过 ssh 进入主机的纯 js/node 方式。特别感谢 弗里曼。假设 ssh 密钥在主机上。不需要请求对象。

      
      const { promisify } = require('util');
      const exec = promisify(require('child_process').exec);
      require('dotenv').config()
      
      //SSH into host and run CMD 
      const ssh = async (command, host) => {
      let output ={};
        try {
          output['stdin'] = await exec(`ssh -o -v ${host} ${command}`)
        } catch (error) {
          output['stderr'] = error.stderr
        }
      
        return output
      }
      
      
      exports.ssh = ssh
      
      
      
      

      【讨论】:

        猜你喜欢
        • 2016-12-05
        • 1970-01-01
        • 2011-04-16
        • 2023-03-08
        • 2013-03-10
        • 1970-01-01
        • 2021-01-09
        • 2021-05-22
        • 1970-01-01
        相关资源
        最近更新 更多