如何从一个node.js应用程序中SSH到服务器?

4
var exec = require('child_process').exec;

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

这只是冻结了 - 我猜是因为ssh my_ip需要密码,是交互式的等等。如何正确地处理?


1
您可以配置和设置您的 ssh 使用公钥来避免需要任何密码。阅读一篇好的 ssh 教程 - Basile Starynkevitch
5个回答

5

有一个用于在Node.js中使用SSH执行任务的模块,名为ssh2,由mscdex编写。可以在这里找到它:https://github.com/mscdex/ssh2。一个你想要的示例(来自readme)如下:

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呢?(还有其他交互式命令) - MaiaVictor
我找到了这个 telnet 客户端 node.js 模块 this。如果你不熟悉,http://npmjs.org 是一个非常大的 node.js 包注册表。 - Andrew Ty.
它需要Python,这并不意味着它是真正的Node模块,它只是使用exec执行一些Python命令。 - Vikas Kandari

4
这个页面上的另一个库有一个较低级别的API。
因此,我为它编写了一个轻量级的包装器。node-ssh,也可在GitHub上以MIT许可证提供。
以下是如何使用它的示例。
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);
  });
});

1
这并不可怕,只是一个更完整的示例,可以让您在不必阅读更多文档的情况下开始运行。我本可以轻松省略许多事件处理程序以减小大小... - mscdex
@mscdex,我知道你可能会留下一些事件处理程序,但是这个库使它变得非常简单,我的意思是没有它,你必须使用.on('data').on('close').on('error'),但是有了它,只需要一个简单的函数就可以得到结果。 - Steel Brain
@SteelBrain,你的代码在处理RSA密钥时存在问题! - Abu Shumon
@johnshumon 它确实如此!它只是真正的 ssh2 模块的代理,它本身不会尝试做任何新的或更少的事情。 - Steel Brain
我喜欢这个界面。当你只需要运行一些简单的命令并返回承诺时,使用事件发射器比起其他方式更好。话虽如此,@mscdex在第一时间为我们编写了一个SSH库,做得非常出色! - marnusw

0

最好的方法是使用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' });
}

-1

使用纯JS/Node的方式连接主机。特别感谢ttfreeman。假设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




-1

请检查我的代码:

// 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);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接