npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ssh-tunneling

v1.1.23

Published

a ssh-tunneling client for nodejs

Downloads

2,648

Readme

Ssh tunneling for nodejs

A ssh tunneling client based on ssh2, which can do command executing and port forwarding.

Installation

npm i ssh-tunneling

Features

  • connection keep-alive: Keeping the ssh connection alive whenever you use it.
  • port forwarding: Ssh tunneling port forward even behind a hopping server,such as a socks server.
  • port checking and finding: The client will automatically find a available local port to forward when the port is using.
  • command executing: Execute linux commands.

API

new SshTunnel(config)

options

  • host: <required> ssh ip
  • port: <required> ssh port
  • username: <required> ssh user name
  • privateKey: [optional] ssh private key
  • password: [optional] ssh password
  • hoppingServer: [optional] Currently it just supports the socks4 or socks5 server,such as 'socks5://180.80.80.80:1080' or 'socks4://180.80.80.80:1080'
import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
};
const client = new SshTunnel(sshConfig);

or establish a connection behind a socks5 server

import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
  // or password
  // password: 'myPassword',
  hoppingServer: 'socks://180.80.80.80:1080'
};
const client = new SshTunnel(sshConfig);

forwardOut

Forward local port to remote port.

import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
};
const client = new SshTunnel(sshConfig);
const forwardInfo1 = client.forwardOut('3000:192.168.1.1:3000');
console.log(forwardInfo1);
// { localPort: 3000, destPort: 3000, destHost: '192.168.1.1', id: '3000:192.168.1.1:3000', type: 'out' }
// or passing an id, it'll use that id.
const forwardInfo2 = await client.forwardOut({
  id: 'my-id',
  proxy: '3001:192.168.1.1:3000'
});
console.log(forwardInfo2);
// { localPort: 3000, destPort: 3000, destHost: '192.168.1.1', id: 'my-id', type: 'out' }

If the local port is occupied, it will choose a idle local port to listen and return the info in result.

import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
};
const client = new SshTunnel(sshConfig);
const forwardInfo1 = client.forwardOut('3000:192.168.1.1:3000');
const forwardInfo2 = client.forwardOut('3000:192.168.1.1:3000');
console.log(forwardInfo1);
// port 3000 is idle
// { localPort: 3000, destPort: 3000, destHost: '192.168.1.1', id: '3000:192.168.1.1:3000', type: 'out' }
console.log(forwardInfo2);
// port 3000 is using, so it use another idle port 3001
// { localPort: 3001, destPort: 3000, destHost: '192.168.1.1', id: '3000:192.168.1.1:3000', type: 'out' }

Also, you can pass an array to forward multiple ports and it will return the result array too.

import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
};
const client = new SshTunnel(sshConfig);
const forwardInfo1 = client.forwardOut(['3000:192.168.1.1:3000', '3001:192.168.1.1:3001']);
console.log(forwardInfo1);
// [
//   { localPort: 3000, destPort: 3000, destHost: '192.168.1.1', id: '3000:192.168.1.1:3000', type: 'out' },
//   { localPort: 3001, destPort: 3001, destHost: '192.168.1.1', id: '3001:192.168.1.1:3001', type: 'out' },
// ]

// or passing an id and it'll use that id
const forwardInfo2 = client.forwardOut([
  {
    id: 'my-id-1',
    proxy: '3000:192.168.1.1:3000'
  },
  {
    id: 'my-id-2',
    proxy: '3001:192.168.1.1:3000'
  }
]);
console.log(forwardInfo2);
// [
//   { localPort: 3000, destPort: 3000, destHost: '192.168.1.1', id: 'my-id-1', type: 'out' },
//   { localPort: 3001, destPort: 3001, destHost: '192.168.1.1', id: 'my-id-2', type: 'out' },
// ]

exec

import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
};
const client = new SshTunnel(sshConfig);
// execute echo command
const echo = await client.exec('echo 1');
console.log(echo); 
// 1
// Also, if passing a command array, it will execute every commands one time and return by order
const batchEcho = await sshTunnel.exec([
  'echo 1',
  'echo 2',
  'echo 3'
]);
// batchEcho: [{ command: 'echo 1', result: '1' }, { command: 'echo 2', result: '2' }, { command: 'echo 3', result: '3' }]

close

Since the ssh connection is established, it can be closed manualy.

  • close one server close(serverKey)
  • close all server close()
import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
};
const client = new SshTunnel(sshConfig);
// execute echo command
const echo = await client.exec('echo 1');
const forwardInfo = client.forwardOut(['3000:192.168.1.1:3000', '3001:192.168.1.1:3001']);
// close one proxy server
client.close(forwardInfo[0].id);
// close all proxy server
client.close();

Examples

Simple ssh port forwarding out

An example that fowarding port 3000 to 192.168.1.1:3000 through a ssh tunnel.
The original ssh command is ssh -L 3000:192.168.1.1:3000 -i ~/.ssh/myPrivateKey [email protected]

import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
};
const client = new SshTunnel(sshConfig);
const forwardInfo = await client.forwardOut('3000:192.168.1.1:3000');
// { localPort: 3000, destHost: '192.168.1.1', destPort: 3000, id: '3000:192.168.1.1:3000', type: 'out' }

Ssh port forwarding through a socks5 server

An example that fowarding port 3000 to 192.168.1.1:3000 through a ssh tunnel which only can be connect through a sock5 server.
The original ssh command is ssh -o ProxyCommand="nc -X 5 -x 180.80.80.80:1080 %h %p" -L 3000:192.168.1.1:3000 -i ~/.ssh/myPrivateKey [email protected]

import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
  hoppingServer: 'socks5://180.80.80.80:1080',
};
const client = new SshTunnel(sshConfig);
const forwardInfo = await client.forwardOut('3000:192.168.1.1:3000');
// { localPort: 3000, destHost: '192.168.1.1', destPort: 3000, id: '3000:192.168.1.1:3000', type: 'out' }

Commands executing

import { SshTunnel } from 'ssh-tunneling';
import type { SshConfig } from 'ssh-tunneling';

const sshConfig: SshConfig = {
  host: '192.168.1.1',
  port: 22,
  username: 'myUsername',
  privateKey: fs.readFileSync('~/.ssh/myPrivateKey'),
};
const client = new SshTunnel(sshConfig);
const result = await client.exec('echo 1');
// 1

coming soon

  • forward in
  • ssh server hopping