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'),
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);
const forwardInfo2 = await client.forwardOut({
id: 'my-id',
proxy: '3001:192.168.1.1:3000'
});
console.log(forwardInfo2);
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);
console.log(forwardInfo2);
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);
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);
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);
const echo = await client.exec('echo 1');
console.log(echo);
const batchEcho = await sshTunnel.exec([
'echo 1',
'echo 2',
'echo 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);
const echo = await client.exec('echo 1');
const forwardInfo = client.forwardOut(['3000:192.168.1.1:3000', '3001:192.168.1.1:3001']);
client.close(forwardInfo[0].id);
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 myUsername@192.168.1.1
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');
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 myUsername@192.168.1.1
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');
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');
coming soon
- forward in
- ssh server hopping