indexzero
1/11/2013 - 7:38 AM

Thoughts about SSH tunnellng using `ssh2`

Thoughts about SSH tunnellng using ssh2

var fs = require('fs'),
    path = require('path');
    Connection = require('ssh2');


var tunnelHost = process.argv[2],
    dest = process.argv[3],
    keyfile = process.argv[4];

var conn = new Connection();

function logSsh(obj, name) {
  obj.on('connect', function ()    { console.log(name + ' :: connect'); });
  obj.on('error',   function (err) { console.log(name + ' :: error :: ' + err); });
  obj.on('end',     function ()    { console.log(name + ' :: end');   });
  obj.on('close',   function ()    { console.log(name + ' :: close'); });
}

function logStream(stream, conn, name) {
  stream.on('data', function(data, extended) {
    console.log(name + (extended === 'stderr' ? ' STDERR: ' : ' STDOUT: ')
                + data);
  });
  stream.on('end', function() {
    console.log(name + ' Stream :: EOF');
  });
  stream.on('close', function() {
    console.log(name + ' Stream :: close');
  });
  stream.on('exit', function(code, signal) {
    console.log(name + ' Stream :: exit :: code: ' + code + ', signal: ' + signal);
    conn.end();
  });
}

logSsh(conn, 'Connection')

conn.on('ready', function () {
  console.log('Connection :: ready');
  
  //
  // Remark: Currently doesn't work with either...
  //
  // Use an interactive shell to nc
  //
  // conn.exec('nc ' + dest + ' 22', function (err, tunnelStream) {
  //
  // OR!
  // Use an outbound TCP connection to dest.host
  //
  conn.forwardOut(tunnelHost, 22, dest, 22, function (err, tunnelStream) {
    if (err) throw err;
    logStream(tunnelStream, conn, 'Connection');
    
    var tunnel = new Connection();
    
    logSsh(tunnel, 'Tunnel')
    
    tunnel.connect({
      host: dest,
      port: 22,
      username: 'root',
      debug: function (msg) {
        console.log('Tunnel: ' + msg);
      },
      privateKey: require('fs').readFileSync(keyfile),
      stream: tunnelStream
    });
    
    tunnel.on('ready', function () {
      console.log('Tunnel :: ready');
      tunnel.exec('ls -la /root', function (err, stream) {
        if (err) throw err;
        logStream(stream, tunnel, 'Tunnel');
      })
    });
  });
});

conn.connect({
  host: tunnelHost,
  port: 22,
  username: 'root',
  debug: function (msg) {
    console.log('Connection: ' + msg);
  },
  privateKey: require('fs').readFileSync(keyfile),
});