@tmlmobilidade/go-clients-ssh 20261002.1429.7 → 20261006.1122.0
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.
- package/dist/ssh.factory.js +53 -17
- package/package.json +1 -1
package/dist/ssh.factory.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* * */
|
|
2
|
+
import { Logger } from '@tmlmobilidade/go-utils-telemetry';
|
|
2
3
|
import { randomInt } from 'node:crypto';
|
|
3
4
|
import { readFileSync } from 'node:fs';
|
|
4
5
|
import { SshTunnel } from './client.js';
|
|
@@ -23,25 +24,64 @@ export function createSshTunnelFactory(type) {
|
|
|
23
24
|
return (options) => buildSshTunnel(type, options);
|
|
24
25
|
}
|
|
25
26
|
function buildSshTunnel(type, options) {
|
|
26
|
-
|
|
27
|
+
//
|
|
28
|
+
//
|
|
29
|
+
// Setup a helper function to get the environment variable
|
|
27
30
|
const env = (name) => process.env[`${type}_${name}`];
|
|
31
|
+
//
|
|
32
|
+
// Check if tunnel is enabled
|
|
28
33
|
if (env('TUNNEL_ENABLED') !== 'true') {
|
|
29
34
|
return null;
|
|
30
35
|
}
|
|
31
|
-
|
|
36
|
+
//
|
|
37
|
+
// Check if required SSH options are set
|
|
38
|
+
if (!options.dstAddr)
|
|
39
|
+
throw new Error(`Missing dstAddr in options.`);
|
|
40
|
+
if (!options.dstPort)
|
|
41
|
+
throw new Error(`Missing dstPort in options.`);
|
|
42
|
+
//
|
|
43
|
+
// Setup SHH Host and Username. Both are required for tunneling.
|
|
44
|
+
const tunnelSshHost = env('TUNNEL_SSH_HOST');
|
|
45
|
+
const tunnelSshUsername = env('TUNNEL_SSH_USERNAME');
|
|
46
|
+
if (!tunnelSshHost)
|
|
32
47
|
throw new Error(`Missing ${type}_TUNNEL_SSH_HOST environment variable.`);
|
|
33
|
-
|
|
34
|
-
if (!env('TUNNEL_SSH_USERNAME')) {
|
|
48
|
+
if (!tunnelSshUsername)
|
|
35
49
|
throw new Error(`Missing ${type}_TUNNEL_SSH_USERNAME environment variable.`);
|
|
50
|
+
//
|
|
51
|
+
// Setup the SSH agent and private key.
|
|
52
|
+
// SSH agent is used when no private key or key path is provided,
|
|
53
|
+
// and a value is set for the SSH_AUTH_SOCK environment variable.
|
|
54
|
+
const tunnelSshKeyPath = env('TUNNEL_SSH_KEY_PATH');
|
|
55
|
+
const tunnelSshKey = env('TUNNEL_SSH_KEY');
|
|
56
|
+
let shouldUseSshAgent;
|
|
57
|
+
let privateKeyValue;
|
|
58
|
+
if (tunnelSshKeyPath) {
|
|
59
|
+
shouldUseSshAgent = false;
|
|
60
|
+
privateKeyValue = readFileSync(tunnelSshKeyPath);
|
|
61
|
+
Logger.info(`Using ${type}_TUNNEL_SSH_KEY_PATH to connect to ${type}_TUNNEL.`);
|
|
62
|
+
}
|
|
63
|
+
else if (tunnelSshKey) {
|
|
64
|
+
shouldUseSshAgent = false;
|
|
65
|
+
privateKeyValue = tunnelSshKey;
|
|
66
|
+
Logger.info(`Using ${type}_TUNNEL_SSH_KEY to connect to ${type}_TUNNEL.`);
|
|
67
|
+
}
|
|
68
|
+
else if (process.env.SSH_AUTH_SOCK) {
|
|
69
|
+
shouldUseSshAgent = true;
|
|
70
|
+
privateKeyValue = undefined;
|
|
71
|
+
Logger.info(`Using SSH agent on ${process.env.SSH_AUTH_SOCK} to connect to ${type}_TUNNEL.`);
|
|
36
72
|
}
|
|
37
|
-
|
|
73
|
+
else {
|
|
38
74
|
throw new Error(`Missing authentication configuration. Please provide ${type}_TUNNEL_SSH_KEY_PATH, ${type}_TUNNEL_SSH_KEY, or ensure SSH_AUTH_SOCK is set.`);
|
|
39
75
|
}
|
|
76
|
+
//
|
|
77
|
+
// Assign a random source port
|
|
40
78
|
const srcPort = randomInt(8_000, 8_999);
|
|
79
|
+
//
|
|
80
|
+
// Build SSH config
|
|
41
81
|
const sshConfig = {
|
|
42
82
|
forwardOptions: {
|
|
43
|
-
dstAddr: dstAddr,
|
|
44
|
-
dstPort: dstPort,
|
|
83
|
+
dstAddr: options.dstAddr,
|
|
84
|
+
dstPort: options.dstPort,
|
|
45
85
|
srcAddr: 'localhost',
|
|
46
86
|
srcPort: srcPort,
|
|
47
87
|
},
|
|
@@ -49,17 +89,13 @@ function buildSshTunnel(type, options) {
|
|
|
49
89
|
port: srcPort,
|
|
50
90
|
},
|
|
51
91
|
sshOptions: {
|
|
52
|
-
agent:
|
|
53
|
-
host:
|
|
92
|
+
agent: shouldUseSshAgent ? process.env.SSH_AUTH_SOCK : undefined,
|
|
93
|
+
host: tunnelSshHost,
|
|
54
94
|
keepaliveCountMax: 3,
|
|
55
95
|
keepaliveInterval: 10_000,
|
|
56
96
|
port: 22,
|
|
57
|
-
privateKey:
|
|
58
|
-
|
|
59
|
-
: env('TUNNEL_SSH_KEY')
|
|
60
|
-
? env('TUNNEL_SSH_KEY')
|
|
61
|
-
: undefined,
|
|
62
|
-
username: env('TUNNEL_SSH_USERNAME'),
|
|
97
|
+
privateKey: privateKeyValue,
|
|
98
|
+
username: tunnelSshUsername,
|
|
63
99
|
},
|
|
64
100
|
tunnelOptions: {
|
|
65
101
|
autoClose: false,
|
|
@@ -67,9 +103,9 @@ function buildSshTunnel(type, options) {
|
|
|
67
103
|
},
|
|
68
104
|
};
|
|
69
105
|
const sshOptions = {
|
|
70
|
-
maxRetries: maxRetries ?? 3,
|
|
106
|
+
maxRetries: options.maxRetries ?? 3,
|
|
71
107
|
};
|
|
72
|
-
const cacheKey = `${type}:${dstAddr}:${dstPort}`;
|
|
108
|
+
const cacheKey = `${type}:${options.dstAddr}:${options.dstPort}`;
|
|
73
109
|
const cached = tunnelCache.get(cacheKey);
|
|
74
110
|
if (cached) {
|
|
75
111
|
return cached;
|