@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.
Files changed (2) hide show
  1. package/dist/ssh.factory.js +53 -17
  2. package/package.json +1 -1
@@ -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
- const { dstAddr, dstPort, maxRetries } = options;
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
- if (!env('TUNNEL_SSH_HOST')) {
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
- if (!env('TUNNEL_SSH_KEY_PATH') && !env('TUNNEL_SSH_KEY') && !process.env.SSH_AUTH_SOCK) {
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: (env('TUNNEL_SSH_KEY_PATH') || env('TUNNEL_SSH_KEY')) ? undefined : process.env.SSH_AUTH_SOCK,
53
- host: env('TUNNEL_SSH_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: env('TUNNEL_SSH_KEY_PATH')
58
- ? readFileSync(env('TUNNEL_SSH_KEY_PATH'))
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tmlmobilidade/go-clients-ssh",
3
- "version": "20261002.1429.7",
3
+ "version": "20261006.1122.0",
4
4
  "author": {
5
5
  "email": "iso@tmlmobilidade.pt",
6
6
  "name": "TML-ISO"