ssh_tunnel_proxy 1.2.10 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +144 -67
  2. package/dist/cjs/index.d.ts +65 -0
  3. package/dist/cjs/index.js +496 -0
  4. package/dist/cjs/index.js.map +1 -0
  5. package/dist/cjs/keypair_storage.d.ts +12 -0
  6. package/dist/cjs/keypair_storage.js +60 -0
  7. package/dist/cjs/keypair_storage.js.map +1 -0
  8. package/dist/cjs/ngrok_service.d.ts +11 -0
  9. package/dist/cjs/ngrok_service.js +40 -0
  10. package/dist/cjs/ngrok_service.js.map +1 -0
  11. package/dist/cjs/ssh2-node.d.ts +1 -0
  12. package/dist/cjs/ssh2-node.js +188 -0
  13. package/dist/cjs/ssh2-node.js.map +1 -0
  14. package/dist/esm/index.d.ts +65 -0
  15. package/dist/esm/index.js +491 -0
  16. package/dist/esm/index.js.map +1 -0
  17. package/dist/esm/keypair_storage.d.ts +12 -0
  18. package/dist/esm/keypair_storage.js +57 -0
  19. package/dist/esm/keypair_storage.js.map +1 -0
  20. package/dist/esm/ngrok_service.d.ts +11 -0
  21. package/dist/esm/ngrok_service.js +37 -0
  22. package/dist/esm/ngrok_service.js.map +1 -0
  23. package/dist/esm/ssh2-node.d.ts +1 -0
  24. package/dist/esm/ssh2-node.js +184 -0
  25. package/dist/esm/ssh2-node.js.map +1 -0
  26. package/dist/types/index.d.ts +65 -0
  27. package/dist/types/keypair_storage.d.ts +12 -0
  28. package/dist/types/ngrok_service.d.ts +11 -0
  29. package/dist/types/ssh2-node.d.ts +1 -0
  30. package/package.json +38 -8
  31. package/ssh2-node +2 -0
  32. package/.eslintrc.json +0 -15
  33. package/.vscode/launch.json +0 -34
  34. package/lib/index.js +0 -472
  35. package/lib/keypair_storage.js +0 -76
  36. package/lib/ngrok_service.js +0 -47
  37. package/main.js +0 -176
  38. package/test/test.js +0 -214
  39. package/test/test_remote_exec.js +0 -219
package/README.md CHANGED
@@ -1,111 +1,188 @@
1
1
  # ssh_tunnel_proxy
2
2
  Initiate a ssh reverse tunnel proxy with forwarding ports
3
3
 
4
- ssh_tunnel_proxy can function as a stand-alone api, nodejs command line script or as part of an electron_js app. To setup a ssh tunnel, parameters are suppled for host, port, authentication and a list of proxy ports. If a ngrok api key is provided the host and port of the ngrok tunnel are obtained. A list of port forwards is provided and is validated to restrict connections to system ports on the remote host to a list of pre-defined ports such as http or https. After establishing a ssh connection on the remote server, local proxy port forwards are opened. If the connection is interrupted or connection errors occur, attempts are made re-establish the tunnel.
4
+ ssh_tunnel_proxy is a wrapper to ssh2 that provides async functionality as well as an extension to the api to include methods to setup a list of proxy forwards, exec a list of commands or startup a terminal shell. To setup a ssh tunnel, parameters are suppled for host, port, authentication and a list of proxy ports or commands to invoke. If a ngrok api key is provided the host and port of the ngrok tunnel are obtained. If the connection is interrupted or connection errors occur, attempts are made re-establish the tunnel.
5
5
 
6
- Example command line to establish a list of local forwards:
6
+ In addition to the node api, a command line function called ssh-node2 is included to start ssh sessions in a manner similar to the ssh command line utility.
7
+
8
+ ### Command line examples
9
+
10
+ Initialize ssh2 command:
11
+ ```
12
+ npm i ssh_tunnel_proxy -g
13
+ ```
14
+ Connect to remote host and establish local forwards:
7
15
 
8
16
  ```
9
- node main.js -c
17
+ ssh2-node -i=~/.ssh/<private_key> -L=8180:192.168.1.1:80 <username>@<hostname>
18
+ ```
19
+
20
+ Connect to host with parameters stored in ~/.config/ssh_tunnel_proxy/config.json:
21
+
22
+ ```
23
+ ssh2-node rh2
10
24
  ```
11
25
 
12
26
  default config file, located at:
13
27
  ~/.config/ssh_tunnel_proxy/config.json
14
28
  ```json
15
29
  [{
16
- "enabled": true,
30
+ "hostname":"rh2",
17
31
  "username": "<username>",
18
- "password": "",
19
- "host": "",
20
- "port": "",
21
32
  "proxy_ports": [
22
33
  "8280:127.0.0.1:80",
23
34
  "9000:127.0.0.1:9000",
24
35
  "8122:192.168.2.1:22"
25
36
  ],
26
- "whitelist": {
27
- "80": true,
28
- "443": true,
29
- "22": true
30
- },
31
- "service_name": "ssh_proxy_client",
32
- "server_name": "test",
37
+ "private_key_filename":"~/.ssh/<private key>",
33
38
  "ngrok_api": "<ngrok api key>"
34
39
  }]
35
40
  ```
36
41
 
37
- Command line to execute a series of commands on remote host:
42
+ Execute command on remote host
38
43
  ```
39
- node main.js -c -e='uptime' -e='ls -all'
44
+ ssh2-node rh2 "ls -all"
40
45
  ```
41
46
 
42
- Or execute commands defined in default config:
47
+ ### List of command-line options (compatible with original ssh2 command):
43
48
  ```
44
- node main.js -c
45
- ```
46
- ```json
47
- [{
48
- "enabled": true,
49
- "username": "<username>",
50
- "service_name": "ssh_proxy_client",
51
- "server_name": "test",
52
- "exec" : [
53
- "uptime",
54
- "ls -all"
55
- ],
56
- "ngrok_api": "<ngrok api key>"
57
- }]
49
+ Usage: ssh2-node [options] [userhost] [exec...]
50
+
51
+ Nodejs ssh2 command line client
52
+
53
+ Arguments:
54
+ userhost Connect to hostname in config.
55
+ exec Command to exec on remote host (must be in quotes)
56
+
57
+ Options:
58
+ -V, --version output the version number
59
+ -2 --protocolv2 [protocolv2] Forces ssh to try protocol version 2 only.
60
+ -4 --ipv4only [ipv4only] Forces ssh to use IPv4 addresses only.
61
+ -6 --ipv6only [ipv6only] Forces ssh to use IPv6 addresses only.
62
+ -A --forward_enable [forward_enable] Enables forwarding of the authentication agent
63
+ connection.
64
+ -a --forward_disable [forward_disable] Disables forwarding of the authentication agent
65
+ connection.
66
+ -b --bind [bind] bind_address
67
+ -C --compress [compress] Requests compression of all data
68
+ -c --cipher [cipher] cipher_spec
69
+ -D --dynamic_forward [dynamic_forward] Specifies a local 'dynamic' application-level
70
+ port forwarding.
71
+ -e --escape [escape] escape_char Sets the escape character for
72
+ sessions with a pty.
73
+ -F --config [config] configfile
74
+ -f --background [background] Requests ssh to go to background just before
75
+ command execution.
76
+ -g --local_forward_remote [local_forward_remote] Allows remote hosts to connect to local forwarded
77
+ ports.
78
+ -I --smartcard [smartcard] smartcard_device Specify the device ssh.
79
+ -i --identity [identity] Private key filename.
80
+ -K --gssapi_auth [gssapi_auth] Enables GSSAPI-based authentication and
81
+ forwarding (delegation) of GSSAPI credentials to
82
+ the server.
83
+ -k --gssapi_disable [gssapi_disable] Disables forwarding (delegation) of GSSAPI
84
+ credentials to the server.
85
+ -L --local_forward_out [local_forward_out...] bind_address:port:host:hostport
86
+ -l --login_name [login_name] login_name
87
+ -M --master_mode [master_mode] Places the ssh client into 'master' mode for
88
+ connection sharing. Multiple -M options
89
+ -m --mac_spec [mac_spec] mac_spec
90
+ -N --no_exec [no_exec] Do not execute a remote command.
91
+ -n --redirect_stdin [redirect_stdin] Redirects stdin from /dev/null
92
+ -O --ctl_cmd [ctl_cmd] ctl_cmd
93
+ -o --option [option] option
94
+ -p --port [port] port Port to connect to on the remote host.
95
+ -q --quiet [quiet] Quiet mode. Causes most warning and diagnostic
96
+ messages to be suppressed.
97
+ -R --local_forward_in [local_forward_in...] bind_address:port:host:hostport
98
+ -S --ctl_path [ctl_path] ctl_path Specifies the location of a control
99
+ socket for connection sharing.
100
+ -s --subsystem [subsystem] May be used to request invocation of a subsystem
101
+ on the remote system.
102
+ -T --disable_tty [disable_tty] Disable pseudo-tty allocation.
103
+ -t --force_tty [force_tty] Force pseudo-tty allocation.
104
+ -V --version [version] Display the version number and exit.
105
+ -v --verbose [verbose] Verbose mode. Causes ssh to print debugging
106
+ messages about its progress.
107
+ -W --forward_stdin_stdout [forward_stdin_stdout] host:port Requests that standard input and output
108
+ on the client be forwarded to host on port ver
109
+ the secure channel.
110
+ -w --tunnel [tunnel] Requests tunnel device forwarding with the
111
+ specified tun(4) devices between the client
112
+ (local_tun) and the server (remote_tun).
113
+ -X --x11 [x11] Enables X11 forwarding.
114
+ -x --x11_disable [x11_disable] Disables X11 forwarding.
115
+ -Y --x11_trusted [x11_trusted] Enables trusted X11 forwarding.
116
+ -y --log [log] Send log information using the syslog(3)
117
+ -H --ngrok [ngrok] Obtain connectiion hostport from ngrok
118
+ -J --keychain_service [keychain_service] Service name to obtain private key from system
119
+ keychain.
120
+ -j --keychain_account [keychain_account] Account name to obtain private key from system
121
+ keychain.
122
+ -h, --help display help for command
58
123
  ```
124
+ ### Api examples
59
125
 
60
- Start a terminal session on the remote host:
61
- ```
62
- node main.js -c -S
63
- ```
64
-
65
- Example use of api to exec remote commands using async await and processing result through streams. Complete example is in test/test_remote_exec.js:
126
+ Exec remote commands using async await and processing result through streams.
66
127
 
67
128
  ```js
68
- // lsLongShellProc to json stream test
69
- async function lsTest(sshTunnelProxy) {
70
- return new Promise(async (resolve) => {
71
-
72
- // exec remote command and pipe data through tunnel until end of data
73
- const tunnel = new PassThrough();
74
- pipeline(tunnel,
75
- split(),
76
- to_lsParse(),
77
- to_JSONString(),
78
- process.stdout,
79
- () => { }
80
- );
81
-
82
- const lscmd = 'ls -all';
83
- console.log('\ninvoking ' + lscmd + ' on remote host:\n');
84
- await sshTunnelProxy.execCmd(lscmd, tunnel);
85
-
86
- // stream processing complete
87
- console.log('ls -all completed');
88
- resolve();
129
+ // send result of cmd through pipeline, generating a stream of json objects
130
+ function lsTest(cmdProxy, cmd, destination) {
131
+
132
+ return new Promise( (resolveCmd) => {
133
+
134
+ // set input of pipeline to split data into lines (npm i split)
135
+ const tunnel = split();
136
+
137
+ // when pipeline is ready exec shell cmd
138
+ const pipelineReady = (socket) => {
139
+
140
+ return new Promise((resolve) => {
141
+
142
+ // invoke command on remote host and send results to pipeline
143
+ cmdProxy.execCmd(cmd, tunnel)
144
+
145
+ // stream processing complete, cleanup pipeline and exit
146
+ .then(() => {
147
+ //self.cleanupPipeline(socket);
148
+ resolveCmd();
149
+ });
150
+ resolve();
151
+ })
152
+ }
153
+
154
+ // pipe shell cmd result through json parser pipeline to destination
155
+ pipeline(tunnel,
156
+ self.parse(),
157
+ self.toJSONString(),
158
+ destination,
159
+ pipelineReady
160
+ );
89
161
  })
90
162
  }
91
163
 
92
- async function runTests() {
164
+ async function runCmd() {
93
165
 
94
- const sshTunnelProxy = new SSHTunnelProxy();
166
+ const opts = {
167
+ "hostname":"rh2",
168
+ "username": "<username>",
169
+ "private_key_filename":"~/.ssh/<private key>",
170
+ "ngrok_api": "<ngrok api key>"
171
+ }
95
172
 
96
- // connect to remote host
97
- await sshTunnelProxy.connectSSH(opts);
173
+ const sshTunnelProxy = new SSHTunnelProxy();
98
174
 
99
- // invoke ls -all on remote host and parse result to json object string
100
- await lsTest(sshTunnelProxy);
175
+ // connect to remote host
176
+ await sshTunnelProxy.connectSSH(opts);
101
177
 
102
- process.exit();
178
+ // invoke ls -all on remote host and parse result to json object string
179
+ await lsTest(sshTunnelProxy, 'ls -all', process.stdout);
103
180
  }
104
181
 
105
- runTests();
182
+ runCmd();
106
183
  ```
107
184
 
108
- The following code is an example of use of the api with electronjs.
185
+ Example of use of the api with electronjs.
109
186
 
110
187
  main.js:
111
188
  ```js
@@ -0,0 +1,65 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ import { Server, Socket } from 'net';
6
+ import { Writable } from 'stream';
7
+ import { EventEmitter } from 'events';
8
+ import { Client, Channel } from 'electron-ssh2';
9
+ import { KeypairStorage } from './keypair_storage';
10
+ import { NgrokApi } from './ngrok_service';
11
+ import { main } from './ssh2-node';
12
+ interface Listener {
13
+ [key: string]: Server;
14
+ }
15
+ export type SSHConfig = {
16
+ hostname: string;
17
+ username: string;
18
+ password?: string;
19
+ host?: string;
20
+ port?: string;
21
+ proxy_ports?: Array<string>;
22
+ remote_ports?: Array<string>;
23
+ private_key?: string | null;
24
+ private_key_filename?: string | null;
25
+ disabled?: boolean;
26
+ server_name?: string;
27
+ service_name?: string;
28
+ compress?: string;
29
+ cypher?: string;
30
+ exec?: Array<string>;
31
+ shell?: boolean;
32
+ ngrok_api?: string;
33
+ keepaliveInterval?: number;
34
+ };
35
+ export declare class SSHTunnelProxy extends EventEmitter {
36
+ protected client: Client;
37
+ protected keypairStorage: KeypairStorage;
38
+ protected config: SSHConfig;
39
+ protected listener: Listener;
40
+ protected retries: number;
41
+ protected networkOnline: boolean;
42
+ protected _tunnelReadyTimeout: ReturnType<typeof setTimeout>;
43
+ debug_en: boolean;
44
+ debug_ssh: boolean;
45
+ constructor();
46
+ protected close_sockets(proxy_ports: Array<string>): void;
47
+ protected setup_ssh_forward(socket: Socket, remote_hostname: string, remote_port: string): void;
48
+ setupProxyPorts(proxy_ports: Array<string>): Promise<void>;
49
+ execCmd(cmd: string, dataStream?: Writable, errStream?: Writable): Promise<void>;
50
+ protected remote_shell(err: Error, stream: Channel): void;
51
+ protected cleanup_events(client: Client): void;
52
+ do_ssh_connect(opts: SSHConfig): Promise<void>;
53
+ validate_port_number(port: number, whitelist: object): boolean;
54
+ validate_local_forward(proxy_ports: Array<string>, whitelist: object): boolean;
55
+ protected ssh_retry_connect(opts: SSHConfig): void;
56
+ protected ssh_start_tunnel(opts: SSHConfig): Promise<unknown>;
57
+ connectSSH(opts: SSHConfig, whitelist: object | null): Promise<void>;
58
+ onNetworkOnline(): void;
59
+ onNetworkOffline(): void;
60
+ generateAndStoreKeypair(serviceName: string, account: string): void;
61
+ getPublicKey(serviceName: string, account: string): void;
62
+ getClient(): Client;
63
+ protected debug(...args: any[]): void;
64
+ }
65
+ export { KeypairStorage, NgrokApi, main as sshcli };