@aikidosec/broker-client 1.0.1 → 1.0.3

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/README.md CHANGED
@@ -55,9 +55,11 @@ Resource IDs are displayed in the Aikido UI when you register them.
55
55
 
56
56
  **Optional:**
57
57
  - `ALLOWED_INTERNAL_SUBNETS` - Comma-separated subnet whitelist (e.g., `10.0.0.0/8,172.16.0.0/12`)
58
- - `DNS_SERVERS` - Custom DNS servers for internal hostname resolution
59
- - `CUSTOM_CA_BUNDLE` - Path to CA cert for self-signed certificates
60
- - `HTTP_PROXY` - HTTP proxy for outbound requests to internal resources (e.g., `http://proxy.company.local:8080`)
58
+ - `DNS_SERVERS` - Custom DNS servers for internal hostname resolution (e.g., `8.8.8.8,8.8.4.4`)
59
+ - `NODE_EXTRA_CA_CERTS` - Path to custom CA certificate bundle for self-signed certificates (e.g., `/certs/corporate-ca.crt`)
60
+ - `HTTP_PROXY` - Proxy server for HTTP requests (e.g., `http://proxy.company.local:8080`)
61
+ - `HTTPS_PROXY` - Proxy server for HTTPS requests (e.g., `http://proxy.company.local:8080`)
62
+ - `ALL_PROXY` - Universal proxy fallback for all protocols if protocol-specific proxy is not set
61
63
 
62
64
  ## How It Works
63
65
 
@@ -74,6 +76,9 @@ Resource IDs are displayed in the Aikido UI when you register them.
74
76
  CLIENT_SECRET=aikido_broker_123_123_123456789
75
77
  ALLOWED_INTERNAL_SUBNETS=10.0.0.0/8,172.16.0.0/12
76
78
  HTTP_PROXY=http://proxy.company.local:8080
79
+ HTTPS_PROXY=http://proxy.company.local:8080
80
+ NODE_EXTRA_CA_CERTS=/certs/corporate-ca.crt
81
+ DNS_SERVERS=10.0.0.1,10.0.0.2
77
82
  ```
78
83
 
79
84
  After registering resources through the Aikido UI, they will be accessible via subdomains like:
package/app/client.js CHANGED
@@ -35,42 +35,12 @@ const DNS_SERVERS = process.env.DNS_SERVERS
35
35
  ? process.env.DNS_SERVERS.split(',').map(s => s.trim()).filter(s => s)
36
36
  : null;
37
37
 
38
- // Optional: Custom CA certificate bundle for self-signed certificates
39
- const CUSTOM_CA_BUNDLE = process.env.CUSTOM_CA_BUNDLE || null;
40
-
41
- // Optional: HTTP proxy for outbound requests to internal resources
42
- const HTTP_PROXY = process.env.HTTP_PROXY || null;
43
-
44
- // Determine TLS verification setting
45
- let httpsAgent = null;
46
- if (CUSTOM_CA_BUNDLE) {
47
- const https = await import('https');
48
- const ca = fs.readFileSync(CUSTOM_CA_BUNDLE);
49
- httpsAgent = new https.Agent({ ca });
50
- log.info(`Using custom CA bundle: ${CUSTOM_CA_BUNDLE}`);
51
- } else {
52
- log.info("Using system CA certificates for TLS verification");
53
- }
54
-
55
38
  // Configure axios defaults
56
39
  const axiosConfig = {
57
40
  timeout: 30000,
58
- maxRedirects: 5,
59
- httpsAgent
41
+ maxRedirects: 5
60
42
  };
61
43
 
62
- if (HTTP_PROXY) {
63
- const proxyUrl = new URL(HTTP_PROXY);
64
- axiosConfig.proxy = {
65
- host: proxyUrl.hostname,
66
- port: proxyUrl.port || 80,
67
- protocol: proxyUrl.protocol
68
- };
69
- log.info(`Using HTTP proxy for internal requests: ${HTTP_PROXY}`);
70
- } else {
71
- log.info("No HTTP proxy configured for internal requests");
72
- }
73
-
74
44
  // Create axios instance for internal requests
75
45
  const internalHttpClient = axios.create(axiosConfig);
76
46
 
@@ -113,7 +83,6 @@ async function resolveInternalHostname(hostname) {
113
83
  const dnsPromises = await import('dns/promises');
114
84
  const result = await dnsPromises.resolve4(hostname);
115
85
  const ip = result[0];
116
- log.debug(`Resolved ${hostname} to ${ip} (system DNS)`);
117
86
  return ip;
118
87
  } catch (e) {
119
88
  log.error(`Failed to resolve ${hostname}: ${e.message}`);
@@ -192,13 +161,11 @@ function isInternalUrl(url) {
192
161
  // Not an IP, allow it through if we have custom DNS configured
193
162
  // The actual resolution will happen in the forward_request handler
194
163
  if (DNS_SERVERS !== null && DNS_SERVERS.length > 0) {
195
- log.debug(`Hostname ${hostname} will be resolved with custom DNS during forward`);
196
164
  return true;
197
165
  }
198
166
 
199
167
  // For system DNS, we can't do synchronous lookup here
200
168
  // Allow all private hostnames through and validate during forward
201
- log.debug(`Hostname ${hostname} will be validated during forward`);
202
169
  return true;
203
170
  }
204
171
  }
@@ -313,6 +280,30 @@ socket.on('disconnect', () => {
313
280
  log.warn("Disconnected from broker server");
314
281
  });
315
282
 
283
+ socket.on('connect_error', (error) => {
284
+ log.error(`Socket.IO connection error: ${error.message}`);
285
+ if (error.description) {
286
+ log.error(` Description: ${JSON.stringify(error.description)}`);
287
+ }
288
+ if (error.context) {
289
+ log.error(` Context: ${JSON.stringify(error.context)}`);
290
+ }
291
+ log.error(` Type: ${error.type || 'unknown'}`);
292
+ });
293
+
294
+ // Manager events (on socket.io)
295
+ socket.io.on('error', (error) => {
296
+ log.error(`Socket.IO Manager error: ${error.message || JSON.stringify(error)}`);
297
+ });
298
+
299
+ socket.io.on('reconnect_error', (error) => {
300
+ log.error(`Socket.IO reconnection error: ${error.message}`);
301
+ });
302
+
303
+ socket.io.on('reconnect_failed', () => {
304
+ log.error(`Socket.IO reconnection failed after all attempts`);
305
+ });
306
+
316
307
  socket.on('forward_request', async (data, callback) => {
317
308
  /**
318
309
  * Receive request from broker server and forward to internal resource
@@ -407,11 +398,13 @@ async function registerWithServer() {
407
398
 
408
399
  for (let attempt = 0; attempt < maxRetries; attempt++) {
409
400
  try {
401
+ const axiosConfig = {
402
+ timeout: 10000
403
+ };
404
+
410
405
  const response = await axios.post(serverUrl, {
411
406
  client_secret: CLIENT_SECRET
412
- }, {
413
- timeout: 10000
414
- });
407
+ }, axiosConfig);
415
408
 
416
409
  if (response.status === 200) {
417
410
  const clientId = response.data.client_id;
@@ -449,7 +442,14 @@ async function registerWithServer() {
449
442
  log.warn(`Registration attempt ${attempt + 1} failed: ${response.status} - ${response.data}`);
450
443
  }
451
444
  } catch (error) {
452
- log.warn(`Registration attempt ${attempt + 1} failed: ${error.name}: ${error.message}`);
445
+ if (error.response) {
446
+ // HTTP error response
447
+ log.warn(`Registration attempt ${attempt + 1} failed: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
448
+ } else {
449
+ // Error setting up request
450
+ log.warn(`Registration attempt ${attempt + 1} failed: ${error.message}`);
451
+ }
452
+
453
453
  if (getClientId() !== null) {
454
454
  // If we have a client_id already, don't retry
455
455
  // we should try once to deal with secret rotation
@@ -498,10 +498,10 @@ async function main() {
498
498
  log.info(`Registered resources: ${Object.keys(registeredResources).length > 0 ? Object.keys(registeredResources).join(', ') : 'None'}`);
499
499
 
500
500
  log.info(`Server URL: ${SERVER_URL}`);
501
- if (HTTP_PROXY) {
502
- log.info(`HTTP Proxy: ${HTTP_PROXY}`);
501
+ if (process.env.HTTP_PROXY || process.env.HTTPS_PROXY) {
502
+ log.info(`Proxy configured: HTTP_PROXY=${process.env.HTTP_PROXY || 'not set'}, HTTPS_PROXY=${process.env.HTTPS_PROXY || 'not set'}`);
503
503
  } else {
504
- log.info("HTTP Proxy: Not configured");
504
+ log.info("Proxy: Not configured");
505
505
  }
506
506
 
507
507
  // Register with server (creates client_id file, waits for propagation)
@@ -102,7 +102,7 @@ export class ResourceManager {
102
102
  this._resources = { ...resourcesDict };
103
103
  this._saveToFile();
104
104
  } else {
105
- log.debug("No resource changes detected");
105
+ log.info("No resource changes detected");
106
106
  }
107
107
  }
108
108
 
@@ -183,7 +183,13 @@ export class ResourceManager {
183
183
  }
184
184
 
185
185
  } catch (error) {
186
- log.error(`Error fetching resources from broker: ${error.message}`);
186
+ if (error.response) {
187
+ // HTTP error response
188
+ log.error(`Error fetching resources from broker: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
189
+ } else {
190
+ // Error setting up request
191
+ log.error(`Error fetching resources from broker: ${error.message}`);
192
+ }
187
193
  }
188
194
  }
189
195
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aikidosec/broker-client",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Aikido Broker Client - Runs in customer network to forward requests to internal resources",
5
5
  "main": "app/client.js",
6
6
  "type": "module",