@opensecurity/zonzon-core 0.1.7 → 0.1.9

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.
@@ -96,16 +96,19 @@ export class HttpHandler {
96
96
  const targetUrl = req.url || "";
97
97
  const [hostname, portStr] = targetUrl.split(':');
98
98
  const port = portStr ? parseInt(portStr, 10) : 443;
99
+ let srvSocket = null;
99
100
  try {
100
101
  const validatedIps = await this.proxyService.validateTargetFirewall(`https://${hostname}:${port}`, this.config.firewall);
101
102
  const targetIp = validatedIps[0];
102
103
  audit.http(clientIp, "CONNECT", hostname, `:${port}`, 200, `TCP Tunnel Established -> ${targetIp}`);
103
104
  clientSocket.setTimeout(this.idleTimeoutMs);
104
105
  clientSocket.on("timeout", () => {
105
- audit.error(`CONNECT Client tunnel idle timeout reached for ${clientIp}`);
106
106
  clientSocket.destroy();
107
+ if (srvSocket && !srvSocket.destroyed) {
108
+ srvSocket.destroy();
109
+ }
107
110
  });
108
- const srvSocket = net.connect(port, targetIp, () => {
111
+ srvSocket = net.connect(port, targetIp, () => {
109
112
  clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
110
113
  if (head && head.length > 0) {
111
114
  srvSocket.write(head);
@@ -115,18 +118,29 @@ export class HttpHandler {
115
118
  });
116
119
  srvSocket.setTimeout(this.idleTimeoutMs);
117
120
  srvSocket.on("timeout", () => {
118
- audit.error(`CONNECT Upstream tunnel idle timeout reached for ${hostname}:${port}`);
119
121
  srvSocket.destroy();
122
+ if (!clientSocket.destroyed) {
123
+ clientSocket.destroy();
124
+ }
120
125
  });
121
126
  this.activeConnections.add(srvSocket);
122
- srvSocket.on('close', () => this.activeConnections.delete(srvSocket));
127
+ srvSocket.on('close', () => {
128
+ this.activeConnections.delete(srvSocket);
129
+ if (!clientSocket.destroyed) {
130
+ clientSocket.destroy();
131
+ }
132
+ });
123
133
  srvSocket.on('error', (err) => {
124
134
  audit.error(`Upstream tunnel fault on ${hostname}:${port} - ${err.message}`);
125
135
  if (!clientSocket.destroyed)
126
136
  clientSocket.destroy();
127
137
  });
128
138
  clientSocket.on('error', (err) => {
129
- if (!srvSocket.destroyed)
139
+ if (srvSocket && !srvSocket.destroyed)
140
+ srvSocket.destroy();
141
+ });
142
+ clientSocket.on('close', () => {
143
+ if (srvSocket && !srvSocket.destroyed)
130
144
  srvSocket.destroy();
131
145
  });
132
146
  }
@@ -353,17 +367,31 @@ export class HttpHandler {
353
367
  return;
354
368
  }
355
369
  }
356
- if (firewallEngine.evaluateDomain(hostname, this.config.firewall) === "DENY") {
357
- audit.http(clientIp, reqMethod, hostname, reqUrl, 403, "Blocked by Domain Firewall");
358
- res.writeHead(403);
359
- res.end("Forbidden");
360
- return;
370
+ const isLiteralIp = net.isIP(hostname) !== 0;
371
+ if (isLiteralIp) {
372
+ if (firewallEngine.evaluateIp(hostname, this.config.firewall) === "DENY") {
373
+ audit.http(clientIp, reqMethod, hostname, reqUrl, 403, "Blocked by IP Firewall");
374
+ res.writeHead(403);
375
+ res.end("Forbidden");
376
+ return;
377
+ }
378
+ }
379
+ else {
380
+ if (firewallEngine.evaluateDomain(hostname, this.config.firewall) === "DENY") {
381
+ audit.http(clientIp, reqMethod, hostname, reqUrl, 403, "Blocked by Domain Firewall");
382
+ res.writeHead(403);
383
+ res.end("Forbidden");
384
+ return;
385
+ }
386
+ }
387
+ let targetIp = hostname;
388
+ if (!isLiteralIp) {
389
+ const records = await dns.resolve(hostname);
390
+ const targetIps = records.filter(ip => typeof ip === "string");
391
+ if (targetIps.length === 0)
392
+ throw new Error("NXDOMAIN");
393
+ targetIp = targetIps[0];
361
394
  }
362
- const records = await dns.resolve(hostname);
363
- const targetIps = records.filter(ip => typeof ip === "string");
364
- if (targetIps.length === 0)
365
- throw new Error("NXDOMAIN");
366
- const targetIp = targetIps[0];
367
395
  if (firewallEngine.evaluateIp(targetIp, this.config.firewall) === "DENY") {
368
396
  audit.http(clientIp, reqMethod, hostname, reqUrl, 403, "Blocked by IP Firewall");
369
397
  res.writeHead(403);
package/dist/sni-proxy.js CHANGED
@@ -75,8 +75,10 @@ export class SniProxyService {
75
75
  let upstreamSocket = null;
76
76
  clientSocket.setTimeout(this.idleTimeoutMs);
77
77
  clientSocket.on("timeout", () => {
78
- audit.error(`SNI Client tunnel idle timeout reached for ${clientIp}`);
79
78
  clientSocket.destroy();
79
+ if (upstreamSocket && !upstreamSocket.destroyed) {
80
+ upstreamSocket.destroy();
81
+ }
80
82
  });
81
83
  const absoluteHandshakeTimeout = setTimeout(() => {
82
84
  if (!isHandled && !clientSocket.destroyed) {
@@ -131,12 +133,17 @@ export class SniProxyService {
131
133
  });
132
134
  upstreamSocket.setTimeout(this.idleTimeoutMs);
133
135
  upstreamSocket.on("timeout", () => {
134
- audit.error(`SNI Upstream tunnel idle timeout reached for ${sni}:${targetIp}`);
135
136
  upstreamSocket.destroy();
137
+ if (!clientSocket.destroyed) {
138
+ clientSocket.destroy();
139
+ }
136
140
  });
137
141
  this.activeConnections.add(upstreamSocket);
138
142
  upstreamSocket.on("close", () => {
139
143
  this.activeConnections.delete(upstreamSocket);
144
+ if (!clientSocket.destroyed) {
145
+ clientSocket.destroy();
146
+ }
140
147
  });
141
148
  upstreamSocket.on("error", (err) => {
142
149
  audit.error(`Upstream tunnel fault on ${sni}:443 - ${err.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensecurity/zonzon-core",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "core routing, dns, and firewall engine",
5
5
  "type": "module",
6
6
  "author": "Lucian BLETAN <neuraluc@gmail.com>",