sanketbajoria / ssh2-promise

ssh with promise/async await and typescript support
https://www.npmjs.com/package/ssh2-promise
MIT License
148 stars 24 forks source link
forward-tunnel promise reverse-tunnels sftp socks ssh ssh-promise ssh2 tunnel

SSH2-Promise

ssh2-promise is a powerful promise wrapper around ssh2 client. It supports all the ssh2 client operation such as connection hopping, exec, spawn, shell, sftp, open tunnel, open socks connection etc... in promisify and async-await way. It helps in caching the sshconnection, to reduce time, during connection hopping. It have reconnect logic, so that, once disconnected, it can retry the sshconnection, automatically.
It has promise wrapper around sftp operations too. This module is written in Typescript. It can be used in Javascript or in Typescript with full type support.

We have upgraded to ssh2 v1.1.0. It means minimum Node requirement v10.16.0, if you need support for older version please use ssh2-promise v0.2.0

Change in sftp api, now ssh.sftp() provide wrapped SFTP session instead of raw sftp session.

Installation

//(Require Node v10.16.0 or newer)
npm install ssh2-promise;

//for older version (Supports for any version of Node)
npm install ssh2-promise@0.2.0

Local Testing

Prerequisite to be installed

cd pretest
docker-compose up -d
cd ..
yarn test

Usage

All examples are shown in promisify and async-await manner.

Require

//in javascript manner
var SSH2Promise = require('ssh2-promise');

//or in typescript manner
import SSH2Promise = require('ssh2-promise');

//or in typescript manner (with esModuleInterop enabled)
import SSH2Promise from 'ssh2-promise';

//To import SFTP, SSHConfig, TunnelConfig Type definition, SSHConstants in typescript

//without esModuleInterop
import SFTP = require('ssh2-promise/lib/sftp')
import SSHConfig = require('ssh2-promise/lib/sshConfig');
import TunnelConfig = require('ssh2-promise/lib/tunnelConfig');
import SSHConstants = require('ssh2-promise/lib/sshConstants');

//with esModuleInterop
import SFTP from 'ssh2-promise/lib/sftp'
import SSHConfig from 'ssh2-promise/lib/sshConfig';
import TunnelConfig from 'ssh2-promise/lib/tunnelConfig';
import SSHConstants from 'ssh2-promise/lib/sshConstants';

Connect to SSH Server

Configuration passed to SSH2Promise is aligned to ssh2 library. For debugging, pass a debug function in configuration, similary how we do for SSH2

// The config passed to the Client constructor should match the config required by ssh2.
// Extra identity option is provided to directly pass the path of private key file
var sshconfig = {
  host: '192.168.1.2',
  username: 'ubuntu',
  identity: '/here/is/my/key'
}

var ssh = new SSH2Promise(sshconfig);

//Promise
ssh.connect().then(() => {
  console.log("Connection established") 
});

//Async Await
(async function(){
    await ssh.connect();
    console.log("Connection established");
})();

//Close the ssh connection 
//very important otherwise event leaks can happen
ssh.close(); 

Connect to SSH Server via hopping

//SSH server detail used for hopping
var sshconfig1 = {
  host: '192.168.1.2',
  username: 'ubuntu',
  identity: '/here/is/my/key1'
}

//SSH server detail to be connected
var sshconfig2 = {
  host: '192.168.1.3',
  username: 'ubuntu',
  password: 'mysecret2'
}

//It will establish connection to sshconfig2 via sshconfig1
//by default it will cache connection, 
//to disable caching, pass second parameter as true
//new SSH2Promise([sshconfig1, sshconfig2], true)
var ssh = new SSH2Promise([sshconfig1, sshconfig2]);

//Promise
ssh.connect().then(() => {
  console.log("Connection established") 
});

//Async Await
(async function(){
    await ssh.connect();
    console.log("Connection established");
})();

exec, spawn cmd

var ssh = new SSH2Promise(sshconfig);

//Promise
//use exec, if output of command is limited
ssh.exec("whoami").then((data) => {
  console.log(data); //ubuntu
});
//use spawn, if you want to stream on output of command
ssh.spawn("tail -f /var/log.txt").then((socket) => {
  socket.on('data', () => {
    //file content will be available here
  })
});

//Async Await
//use exec, if output of command is limited
(async function(){
    var data = await ssh.exec("whoami");
    console.log(data); //ubuntu
})();

//use spawn, if you want to stream on output of command
(async function(){
    var socket = await ssh.spawn("tail -f /var/log.txt");
    socket.on('data', () => {
      //file content will be available here
    })
})();

sftp, shell cmd

var ssh = new SSH2Promise(sshconfig);

//Promise
//Get a sftp session
//see: https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md

//in typescript import sftp type definition
//import SFTP = require('ssh2-promise/lib/sftp')

var sftp/*:SFTP*/ = ssh.sftp()
sftp.readdir("/").then((data) => {
  console.log(data); //file listing
}).catch((err) => {
  console.log(err);
})

//Get a shell session
ssh.shell().then((socket) => {
  socket.on('data', () => {
    //shell content will be available here
  })
  //Can write to socket 
  socket.write("")
});

//Async Await
//Get a sftp session
//see: https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md
(async function(){
    var sftp = ssh.sftp();
    var data = await sftp.readdir("/")
    console.log(data); //file listing
})();

//Get a shell session
(async function(){
    var socket = await ssh.shell();
    socket.on('data', () => {
      //shell content will be available here
    })
    //Can write to socket 
    socket.write("")
})();

sftp operation in promise & async await manner

//in typescript import sftp type definition
//import SFTP = require('ssh2-promise/lib/sftp')
var ssh = new SSH2Promise(sshconfig);
var sftp/*:SFTP*/ = ssh.sftp(); //or new SSH2Promise.SFTP(ssh);

//We can do all sftp client operation listed in "https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md" in promisify or async await manner.

//Promise
//Read dir
sftp.readdir("/").then((list) => {
  console.log(list); //list of files in directory '/'
});
//Create ReadStream
sftp.createReadStream("/test.sh").then((stream) => {
  console.log(stream); //Readable stream, which support data, close events etc.. 
});
//Get stat
sftp.getStat("/test.sh").then((stat) => {
  console.log(stat); //Stat object 
});

//Async Await
//Read dir
(async function(){
    var list = await sftp.readdir("/");
    console.log(list); //list of files in directory '/'
})();
//Create ReadStream
(async function(){
    var stream = await sftp.createReadStream("/test.sh");
    console.log(stream); //Readable stream, which support data, close events etc.. 
})();
//Get stat
(async function(){
    var st = await sftp.getStat("/test.sh");
    console.log(stat); //Stat object 
})();

tunnel and socks server

var ssh = new SSH2Promise(sshconfig);

//Promise
//It will establish the socks connection, one per ssh connection, and return the port
//It is mainly used for reverse tunneling
ssh.getSocksPort().then((port) => {
  console.log(port); //Socks port
});

//Establish a forward tunneling to any resource over above server
ssh.addTunnel({remoteAddr: "www.google.com", remotePort: "80"}).then((tunnel) => {
  console.log(tunnel.localPort); //Local port 
});

//Async Await
//It will establish the socks connection, one per ssh connection, and return the port
//It is mainly used for reverse tunneling
(async function(){
    var port = await ssh.getSocksPort();
    console.log(port); //Socks port
})();

//Establish a forward tunneling to any resource over above server
(async function(){
    var tunnel = await ssh.addTunnel({remoteAddr: "www.google.com", remotePort: "80"});
    console.log(tunnel.localPort); //Local port
})();

x11

sshconfig.x11 = {srcIP: 'localhost', srcPort: 6000}
//sshconfig.x11 = '/tmp/.X11-unix/X0' //connect to unix socket
var ssh = new SSH2Promise(sshconfig);

//It will establish the x11 forwarding, if
//x server running locally, 
//x forwarding enabled on remote server 
//xeyes command is installed on remote server

//Promise
ssh.x11('xeyes').then(() => {
  console.log("success"); //if x server running locally, (x forwarding enabled & xeyes command is installed) on remote server
}, () => {
  console.log("error"); //if any success condition is not met
});

//Async Await
(async function(){
  try{
    await ssh.x11('xeyes');
    console.log("success"); //if x server running locally, (x forwarding enabled & xeyes command is installed) on remote server
  }catch(err){
    console.log("error"); //if any success condition is not met
  }
})();

subsys

var ssh = new SSH2Promise(sshconfig);

//It will start subsystem

//Promise
ssh.subsys('sftp').then((stream) => {
  console.log("success"); //sftp system started successfully
});

//Async Await
(async function(){
  var stream = await ssh.subsys('sftp');
  console.log("success"); //sftp system started successfully
})();

API

require('ssh2-promise') require('ssh2-promise\lib\sftp')

SSH2

Events

Methods

SFTP

It supports all the sftp client operations, in promisify way. For detailed explanation of all the operation, please visit sftp. It has few extra methods getStat, setStat, changeTimestamp, readFileData, writeFileData, changeMode, changeOwner.

Methods

ATTRS

An object with the following valid properties:

When supplying an ATTRS object to one of the SFTP methods:

Stats

An object with the same attributes as an ATTRS object with the addition of the following methods:

LICENSE

MIT