@push.rocks/smartproxy 4.1.3 → 4.1.5

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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartproxy',
6
- version: '4.1.3',
6
+ version: '4.1.5',
7
7
  description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx3QkFBd0I7SUFDOUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLG1PQUFtTztDQUNqUCxDQUFBIn0=
@@ -134,8 +134,8 @@ export class ConnectionHandler {
134
134
  // Check if this looks like a TLS handshake
135
135
  if (this.tlsManager.isTlsHandshake(chunk)) {
136
136
  record.isTLS = true;
137
- // Check session tickets if they're disabled
138
- if (this.settings.allowSessionTicket === false && this.tlsManager.isClientHello(chunk)) {
137
+ // Check for ClientHello to extract SNI - but don't enforce it for NetworkProxy
138
+ if (this.tlsManager.isClientHello(chunk)) {
139
139
  // Create connection info for SNI extraction
140
140
  const connInfo = {
141
141
  sourceIp: record.remoteIP,
@@ -143,63 +143,30 @@ export class ConnectionHandler {
143
143
  destIp: socket.localAddress || '',
144
144
  destPort: socket.localPort || 0,
145
145
  };
146
- // Extract SNI for domain-specific NetworkProxy handling
146
+ // Extract SNI for domain-specific NetworkProxy handling if available
147
147
  const serverName = this.tlsManager.extractSNI(chunk, connInfo);
148
- // If allowSessionTicket is false and we can't determine SNI, terminate the connection
149
- if (!serverName) {
150
- // Always block when allowSessionTicket is false and there's no SNI
151
- console.log(`[${connectionId}] No SNI detected in ClientHello and allowSessionTicket=false. ` +
152
- `Terminating connection to force new TLS handshake with SNI.`);
153
- // Send a proper TLS alert before ending the connection
154
- // Using "unrecognized_name" (112) alert which is a warning level alert (1)
155
- // that encourages clients to retry with proper SNI
156
- const alertData = Buffer.from([
157
- 0x15, // Alert record type
158
- 0x03, 0x03, // TLS 1.2 version
159
- 0x00, 0x02, // Length
160
- 0x01, // Warning alert level (not fatal)
161
- 0x70 // unrecognized_name alert (code 112)
162
- ]);
163
- try {
164
- socket.write(alertData, () => {
165
- // Only close the socket after we're sure the alert was sent
166
- // Give the alert time to be processed by the client
167
- setTimeout(() => {
168
- socket.end();
169
- // Ensure complete cleanup happens a bit later
170
- setTimeout(() => {
171
- if (!socket.destroyed) {
172
- socket.destroy();
173
- }
174
- this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
175
- }, 100);
176
- }, 100);
177
- });
178
- }
179
- catch (err) {
180
- // If we can't send the alert, fall back to immediate termination
181
- socket.end();
182
- this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
183
- }
184
- if (record.incomingTerminationReason === null) {
185
- record.incomingTerminationReason = 'session_ticket_blocked_no_sni';
186
- this.connectionManager.incrementTerminationStat('incoming', 'session_ticket_blocked_no_sni');
148
+ // For NetworkProxy connections, we'll allow session tickets even without SNI
149
+ // We'll only use the serverName if available to determine the specific NetworkProxy port
150
+ if (serverName) {
151
+ // Save domain config and SNI in connection record
152
+ const domainConfig = this.domainConfigManager.findDomainConfig(serverName);
153
+ record.domainConfig = domainConfig;
154
+ record.lockedDomain = serverName;
155
+ // Use domain-specific NetworkProxy port if configured
156
+ if (domainConfig && this.domainConfigManager.shouldUseNetworkProxy(domainConfig)) {
157
+ const networkProxyPort = this.domainConfigManager.getNetworkProxyPort(domainConfig);
158
+ if (this.settings.enableDetailedLogging) {
159
+ console.log(`[${connectionId}] Using domain-specific NetworkProxy for ${serverName} on port ${networkProxyPort}`);
160
+ }
161
+ // Forward to NetworkProxy with domain-specific port
162
+ this.networkProxyBridge.forwardToNetworkProxy(connectionId, socket, record, chunk, networkProxyPort, (reason) => this.connectionManager.initiateCleanupOnce(record, reason));
163
+ return;
187
164
  }
188
- return;
189
165
  }
190
- // Save domain config and SNI in connection record
191
- const domainConfig = this.domainConfigManager.findDomainConfig(serverName);
192
- record.domainConfig = domainConfig;
193
- record.lockedDomain = serverName;
194
- // Use domain-specific NetworkProxy port if configured
195
- if (domainConfig && this.domainConfigManager.shouldUseNetworkProxy(domainConfig)) {
196
- const networkProxyPort = this.domainConfigManager.getNetworkProxyPort(domainConfig);
197
- if (this.settings.enableDetailedLogging) {
198
- console.log(`[${connectionId}] Using domain-specific NetworkProxy for ${serverName} on port ${networkProxyPort}`);
199
- }
200
- // Forward to NetworkProxy with domain-specific port
201
- this.networkProxyBridge.forwardToNetworkProxy(connectionId, socket, record, chunk, networkProxyPort, (reason) => this.connectionManager.initiateCleanupOnce(record, reason));
202
- return;
166
+ else if (this.settings.allowSessionTicket === false &&
167
+ this.settings.enableDetailedLogging) {
168
+ // Log that we're allowing a session resumption without SNI for NetworkProxy
169
+ console.log(`[${connectionId}] Allowing session resumption without SNI for NetworkProxy forwarding`);
203
170
  }
204
171
  }
205
172
  // Forward directly to NetworkProxy without domain-specific settings
@@ -321,8 +288,7 @@ export class ConnectionHandler {
321
288
  return rejectIncomingConnection('rejected', `Connection rejected: IP ${record.remoteIP} not allowed for domain ${domainConfig.domains.join(', ')}`);
322
289
  }
323
290
  }
324
- else if (this.settings.defaultAllowedIPs &&
325
- this.settings.defaultAllowedIPs.length > 0) {
291
+ else if (this.settings.defaultAllowedIPs && this.settings.defaultAllowedIPs.length > 0) {
326
292
  if (!this.securityManager.isIPAuthorized(record.remoteIP, this.settings.defaultAllowedIPs, this.settings.defaultBlockedIPs || [])) {
327
293
  return rejectIncomingConnection('rejected', `Connection rejected: IP ${record.remoteIP} not allowed by default allowed list`);
328
294
  }
@@ -420,42 +386,104 @@ export class ConnectionHandler {
420
386
  !serverName) {
421
387
  // Always block ClientHello without SNI when allowSessionTicket is false
422
388
  console.log(`[${connectionId}] No SNI detected in ClientHello and allowSessionTicket=false. ` +
423
- `Terminating connection to force new TLS handshake with SNI.`);
389
+ `Sending unrecognized_name alert to encourage client to retry with SNI.`);
390
+ // Set the termination reason first to avoid races
391
+ if (record.incomingTerminationReason === null) {
392
+ record.incomingTerminationReason = 'session_ticket_blocked_no_sni';
393
+ this.connectionManager.incrementTerminationStat('incoming', 'session_ticket_blocked_no_sni');
394
+ }
424
395
  // Send a proper TLS alert before ending the connection
425
- // Using "unrecognized_name" (112) alert which is a warning level alert (1)
396
+ // Using "unrecognized_name" (112) alert which is a warning level alert (1)
426
397
  // that encourages clients to retry with proper SNI
427
398
  const alertData = Buffer.from([
428
399
  0x15, // Alert record type
429
- 0x03, 0x03, // TLS 1.2 version
430
- 0x00, 0x02, // Length
400
+ 0x03,
401
+ 0x03, // TLS 1.2 version
402
+ 0x00,
403
+ 0x02, // Length
431
404
  0x01, // Warning alert level (not fatal)
432
- 0x70 // unrecognized_name alert (code 112)
405
+ 0x70, // unrecognized_name alert (code 112)
433
406
  ]);
434
407
  try {
435
- socket.write(alertData, () => {
436
- // Only close the socket after we're sure the alert was sent
437
- // Give the alert time to be processed by the client
438
- setTimeout(() => {
408
+ // Make sure the alert is sent as a single packet
409
+ socket.cork();
410
+ socket.write(alertData);
411
+ socket.uncork();
412
+ // Set a longer timeout to allow the client to properly handle the alert
413
+ // The client might respond by closing the connection or initiating a new handshake
414
+ const alertTimeout = setTimeout(() => {
415
+ if (!socket.destroyed) {
416
+ console.log(`[${connectionId}] Client didn't respond to TLS alert, closing connection gracefully.`);
417
+ // Gracefully end the connection
439
418
  socket.end();
440
- // Ensure complete cleanup happens a bit later
419
+ // Only destroy after a delay if it's still hanging
441
420
  setTimeout(() => {
442
421
  if (!socket.destroyed) {
422
+ console.log(`[${connectionId}] Forcibly closing connection that didn't terminate properly.`);
443
423
  socket.destroy();
444
424
  }
445
425
  this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
446
- }, 100);
447
- }, 100);
426
+ }, 2000);
427
+ }
428
+ }, 5000); // Give the client 5 seconds to respond to our alert
429
+ // Don't let this timeout keep the process alive
430
+ if (alertTimeout.unref) {
431
+ alertTimeout.unref();
432
+ }
433
+ // Handle a proper close from the client
434
+ socket.once('close', () => {
435
+ clearTimeout(alertTimeout);
436
+ console.log(`[${connectionId}] Client closed connection after receiving TLS alert.`);
437
+ this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni_client_closed');
438
+ });
439
+ // Also handle if the client sends more data (possibly a new handshake with SNI)
440
+ socket.once('data', (newChunk) => {
441
+ clearTimeout(alertTimeout);
442
+ console.log(`[${connectionId}] Client sent new data after TLS alert, checking for SNI...`);
443
+ // This would normally be handled by our renegotiation handler,
444
+ // but since we're in a special case, we'll check for SNI again
445
+ if (this.tlsManager.isTlsHandshake(newChunk) && this.tlsManager.isClientHello(newChunk)) {
446
+ const newServerName = this.tlsManager.extractSNI(newChunk, connInfo);
447
+ if (newServerName) {
448
+ console.log(`[${connectionId}] Client provided SNI in new handshake: ${newServerName}`);
449
+ // Update the record
450
+ record.incomingTerminationReason = null;
451
+ // Remove termination stats increment
452
+ // Note: This is a little hacky as we don't have a proper way to decrement stats
453
+ // Process the new handshake with SNI
454
+ record.lockedDomain = newServerName;
455
+ setupConnection(newServerName, newChunk);
456
+ return;
457
+ }
458
+ else {
459
+ console.log(`[${connectionId}] Client sent new handshake but still without SNI, closing connection.`);
460
+ socket.end();
461
+ setTimeout(() => {
462
+ if (!socket.destroyed) {
463
+ socket.destroy();
464
+ }
465
+ this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni_retry_failed');
466
+ }, 500);
467
+ }
468
+ }
469
+ else {
470
+ console.log(`[${connectionId}] Client sent non-handshake data after TLS alert, closing connection.`);
471
+ socket.end();
472
+ setTimeout(() => {
473
+ if (!socket.destroyed) {
474
+ socket.destroy();
475
+ }
476
+ this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_invalid_response');
477
+ }, 500);
478
+ }
448
479
  });
449
480
  }
450
481
  catch (err) {
451
482
  // If we can't send the alert, fall back to immediate termination
483
+ console.log(`[${connectionId}] Error sending TLS alert: ${err.message}`);
452
484
  socket.end();
453
485
  this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
454
486
  }
455
- if (record.incomingTerminationReason === null) {
456
- record.incomingTerminationReason = 'session_ticket_blocked_no_sni';
457
- this.connectionManager.incrementTerminationStat('incoming', 'session_ticket_blocked_no_sni');
458
- }
459
487
  return;
460
488
  }
461
489
  }
@@ -488,9 +516,7 @@ export class ConnectionHandler {
488
516
  ? this.domainConfigManager.getTargetIP(domainConfig)
489
517
  : this.settings.targetIP;
490
518
  // Determine target port
491
- const targetPort = overridePort !== undefined
492
- ? overridePort
493
- : this.settings.toPort;
519
+ const targetPort = overridePort !== undefined ? overridePort : this.settings.toPort;
494
520
  // Setup connection options
495
521
  const connectionOptions = {
496
522
  host: targetHost,
@@ -773,4 +799,4 @@ export class ConnectionHandler {
773
799
  });
774
800
  }
775
801
  }
776
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wcC5jb25uZWN0aW9uaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMucHAuY29ubmVjdGlvbmhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFFeEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN4RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDaEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFcEU7O0dBRUc7QUFDSCxNQUFNLE9BQU8saUJBQWlCO0lBQzVCLFlBQ1UsUUFBNEIsRUFDNUIsaUJBQW9DLEVBQ3BDLGVBQWdDLEVBQ2hDLG1CQUF3QyxFQUN4QyxVQUFzQixFQUN0QixrQkFBc0MsRUFDdEMsY0FBOEIsRUFDOUIsZ0JBQWtDO1FBUGxDLGFBQVEsR0FBUixRQUFRLENBQW9CO1FBQzVCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0Qix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3RDLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO0lBQ3pDLENBQUM7SUFFSjs7T0FFRztJQUNJLGdCQUFnQixD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
802
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wcC5jb25uZWN0aW9uaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMucHAuY29ubmVjdGlvbmhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFNeEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDdEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUN4RSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDaEUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFcEU7O0dBRUc7QUFDSCxNQUFNLE9BQU8saUJBQWlCO0lBQzVCLFlBQ1UsUUFBNEIsRUFDNUIsaUJBQW9DLEVBQ3BDLGVBQWdDLEVBQ2hDLG1CQUF3QyxFQUN4QyxVQUFzQixFQUN0QixrQkFBc0MsRUFDdEMsY0FBOEIsRUFDOUIsZ0JBQWtDO1FBUGxDLGFBQVEsR0FBUixRQUFRLENBQW9CO1FBQzVCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLHdCQUFtQixHQUFuQixtQkFBbUIsQ0FBcUI7UUFDeEMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0Qix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBQ3RDLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO0lBQ3pDLENBQUM7SUFFSjs7T0FFRztJQUNJLGdCQUFnQixD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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartproxy",
3
- "version": "4.1.3",
3
+ "version": "4.1.5",
4
4
  "private": false,
5
5
  "description": "A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.",
6
6
  "main": "dist_ts/index.js",
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartproxy',
6
- version: '4.1.3',
6
+ version: '4.1.5',
7
7
  description: 'A powerful proxy package that effectively handles high traffic, with features such as SSL/TLS support, port proxying, WebSocket handling, dynamic routing with authentication options, and automatic ACME certificate management.'
8
8
  }
@@ -1,5 +1,9 @@
1
1
  import * as plugins from './plugins.js';
2
- import type { IConnectionRecord, IDomainConfig, IPortProxySettings } from './classes.pp.interfaces.js';
2
+ import type {
3
+ IConnectionRecord,
4
+ IDomainConfig,
5
+ IPortProxySettings,
6
+ } from './classes.pp.interfaces.js';
3
7
  import { ConnectionManager } from './classes.pp.connectionmanager.js';
4
8
  import { SecurityManager } from './classes.pp.securitymanager.js';
5
9
  import { DomainConfigManager } from './classes.pp.domainconfigmanager.js';
@@ -73,8 +77,8 @@ export class ConnectionHandler {
73
77
  if (this.settings.enableDetailedLogging) {
74
78
  console.log(
75
79
  `[${connectionId}] New connection from ${remoteIP} on port ${localPort}. ` +
76
- `Keep-Alive: ${record.hasKeepAlive ? 'Enabled' : 'Disabled'}. ` +
77
- `Active connections: ${this.connectionManager.getConnectionCount()}`
80
+ `Keep-Alive: ${record.hasKeepAlive ? 'Enabled' : 'Disabled'}. ` +
81
+ `Active connections: ${this.connectionManager.getConnectionCount()}`
78
82
  );
79
83
  } else {
80
84
  console.log(
@@ -94,7 +98,10 @@ export class ConnectionHandler {
94
98
  /**
95
99
  * Handle a connection that should be forwarded to NetworkProxy
96
100
  */
97
- private handleNetworkProxyConnection(socket: plugins.net.Socket, record: IConnectionRecord): void {
101
+ private handleNetworkProxyConnection(
102
+ socket: plugins.net.Socket,
103
+ record: IConnectionRecord
104
+ ): void {
98
105
  const connectionId = record.id;
99
106
  let initialDataReceived = false;
100
107
 
@@ -104,7 +111,7 @@ export class ConnectionHandler {
104
111
  console.log(
105
112
  `[${connectionId}] Initial data warning (${this.settings.initialDataTimeout}ms) for connection from ${record.remoteIP}`
106
113
  );
107
-
114
+
108
115
  // Add a grace period instead of immediate termination
109
116
  setTimeout(() => {
110
117
  if (!initialDataReceived) {
@@ -144,7 +151,7 @@ export class ConnectionHandler {
144
151
  if (!this.tlsManager.isTlsHandshake(chunk) && localPort === 443) {
145
152
  console.log(
146
153
  `[${connectionId}] Non-TLS connection detected on port 443. ` +
147
- `Terminating connection - only TLS traffic is allowed on standard HTTPS port.`
154
+ `Terminating connection - only TLS traffic is allowed on standard HTTPS port.`
148
155
  );
149
156
  if (record.incomingTerminationReason === null) {
150
157
  record.incomingTerminationReason = 'non_tls_blocked';
@@ -159,8 +166,8 @@ export class ConnectionHandler {
159
166
  if (this.tlsManager.isTlsHandshake(chunk)) {
160
167
  record.isTLS = true;
161
168
 
162
- // Check session tickets if they're disabled
163
- if (this.settings.allowSessionTicket === false && this.tlsManager.isClientHello(chunk)) {
169
+ // Check for ClientHello to extract SNI - but don't enforce it for NetworkProxy
170
+ if (this.tlsManager.isClientHello(chunk)) {
164
171
  // Create connection info for SNI extraction
165
172
  const connInfo = {
166
173
  sourceIp: record.remoteIP,
@@ -169,83 +176,46 @@ export class ConnectionHandler {
169
176
  destPort: socket.localPort || 0,
170
177
  };
171
178
 
172
- // Extract SNI for domain-specific NetworkProxy handling
179
+ // Extract SNI for domain-specific NetworkProxy handling if available
173
180
  const serverName = this.tlsManager.extractSNI(chunk, connInfo);
174
181
 
175
- // If allowSessionTicket is false and we can't determine SNI, terminate the connection
176
- if (!serverName) {
177
- // Always block when allowSessionTicket is false and there's no SNI
178
- console.log(
179
- `[${connectionId}] No SNI detected in ClientHello and allowSessionTicket=false. ` +
180
- `Terminating connection to force new TLS handshake with SNI.`
181
- );
182
-
183
- // Send a proper TLS alert before ending the connection
184
- // Using "unrecognized_name" (112) alert which is a warning level alert (1)
185
- // that encourages clients to retry with proper SNI
186
- const alertData = Buffer.from([
187
- 0x15, // Alert record type
188
- 0x03, 0x03, // TLS 1.2 version
189
- 0x00, 0x02, // Length
190
- 0x01, // Warning alert level (not fatal)
191
- 0x70 // unrecognized_name alert (code 112)
192
- ]);
193
-
194
- try {
195
- socket.write(alertData, () => {
196
- // Only close the socket after we're sure the alert was sent
197
- // Give the alert time to be processed by the client
198
- setTimeout(() => {
199
- socket.end();
200
-
201
- // Ensure complete cleanup happens a bit later
202
- setTimeout(() => {
203
- if (!socket.destroyed) {
204
- socket.destroy();
205
- }
206
- this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
207
- }, 100);
208
- }, 100);
209
- });
210
- } catch (err) {
211
- // If we can't send the alert, fall back to immediate termination
212
- socket.end();
213
- this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
214
- }
215
-
216
- if (record.incomingTerminationReason === null) {
217
- record.incomingTerminationReason = 'session_ticket_blocked_no_sni';
218
- this.connectionManager.incrementTerminationStat('incoming', 'session_ticket_blocked_no_sni');
219
- }
220
-
221
- return;
222
- }
223
-
224
- // Save domain config and SNI in connection record
225
- const domainConfig = this.domainConfigManager.findDomainConfig(serverName);
226
- record.domainConfig = domainConfig;
227
- record.lockedDomain = serverName;
228
-
229
- // Use domain-specific NetworkProxy port if configured
230
- if (domainConfig && this.domainConfigManager.shouldUseNetworkProxy(domainConfig)) {
231
- const networkProxyPort = this.domainConfigManager.getNetworkProxyPort(domainConfig);
182
+ // For NetworkProxy connections, we'll allow session tickets even without SNI
183
+ // We'll only use the serverName if available to determine the specific NetworkProxy port
184
+ if (serverName) {
185
+ // Save domain config and SNI in connection record
186
+ const domainConfig = this.domainConfigManager.findDomainConfig(serverName);
187
+ record.domainConfig = domainConfig;
188
+ record.lockedDomain = serverName;
189
+
190
+ // Use domain-specific NetworkProxy port if configured
191
+ if (domainConfig && this.domainConfigManager.shouldUseNetworkProxy(domainConfig)) {
192
+ const networkProxyPort = this.domainConfigManager.getNetworkProxyPort(domainConfig);
193
+
194
+ if (this.settings.enableDetailedLogging) {
195
+ console.log(
196
+ `[${connectionId}] Using domain-specific NetworkProxy for ${serverName} on port ${networkProxyPort}`
197
+ );
198
+ }
232
199
 
233
- if (this.settings.enableDetailedLogging) {
234
- console.log(
235
- `[${connectionId}] Using domain-specific NetworkProxy for ${serverName} on port ${networkProxyPort}`
200
+ // Forward to NetworkProxy with domain-specific port
201
+ this.networkProxyBridge.forwardToNetworkProxy(
202
+ connectionId,
203
+ socket,
204
+ record,
205
+ chunk,
206
+ networkProxyPort,
207
+ (reason) => this.connectionManager.initiateCleanupOnce(record, reason)
236
208
  );
209
+ return;
237
210
  }
238
-
239
- // Forward to NetworkProxy with domain-specific port
240
- this.networkProxyBridge.forwardToNetworkProxy(
241
- connectionId,
242
- socket,
243
- record,
244
- chunk,
245
- networkProxyPort,
246
- (reason) => this.connectionManager.initiateCleanupOnce(record, reason)
211
+ } else if (
212
+ this.settings.allowSessionTicket === false &&
213
+ this.settings.enableDetailedLogging
214
+ ) {
215
+ // Log that we're allowing a session resumption without SNI for NetworkProxy
216
+ console.log(
217
+ `[${connectionId}] Allowing session resumption without SNI for NetworkProxy forwarding`
247
218
  );
248
- return;
249
219
  }
250
220
  }
251
221
 
@@ -260,14 +230,10 @@ export class ConnectionHandler {
260
230
  );
261
231
  } else {
262
232
  // If not TLS, use normal direct connection
263
- console.log(`[${connectionId}] Non-TLS connection on NetworkProxy port ${record.localPort}`);
264
- this.setupDirectConnection(
265
- socket,
266
- record,
267
- undefined,
268
- undefined,
269
- chunk
233
+ console.log(
234
+ `[${connectionId}] Non-TLS connection on NetworkProxy port ${record.localPort}`
270
235
  );
236
+ this.setupDirectConnection(socket, record, undefined, undefined, chunk);
271
237
  }
272
238
  });
273
239
  }
@@ -300,7 +266,7 @@ export class ConnectionHandler {
300
266
  console.log(
301
267
  `[${connectionId}] Initial data warning (${this.settings.initialDataTimeout}ms) for connection from ${record.remoteIP}`
302
268
  );
303
-
269
+
304
270
  // Add a grace period instead of immediate termination
305
271
  setTimeout(() => {
306
272
  if (!initialDataReceived) {
@@ -385,14 +351,13 @@ export class ConnectionHandler {
385
351
  record.domainConfig = domainConfig;
386
352
 
387
353
  // Check if this domain should use NetworkProxy (domain-specific setting)
388
- if (domainConfig &&
389
- this.domainConfigManager.shouldUseNetworkProxy(domainConfig) &&
390
- this.networkProxyBridge.getNetworkProxy()) {
391
-
354
+ if (
355
+ domainConfig &&
356
+ this.domainConfigManager.shouldUseNetworkProxy(domainConfig) &&
357
+ this.networkProxyBridge.getNetworkProxy()
358
+ ) {
392
359
  if (this.settings.enableDetailedLogging) {
393
- console.log(
394
- `[${connectionId}] Domain ${serverName} is configured to use NetworkProxy`
395
- );
360
+ console.log(`[${connectionId}] Domain ${serverName} is configured to use NetworkProxy`);
396
361
  }
397
362
 
398
363
  const networkProxyPort = this.domainConfigManager.getNetworkProxyPort(domainConfig);
@@ -414,23 +379,24 @@ export class ConnectionHandler {
414
379
  // IP validation
415
380
  if (domainConfig) {
416
381
  const ipRules = this.domainConfigManager.getEffectiveIPRules(domainConfig);
417
-
382
+
418
383
  // Skip IP validation if allowedIPs is empty
419
384
  if (
420
385
  domainConfig.allowedIPs.length > 0 &&
421
- !this.securityManager.isIPAuthorized(record.remoteIP, ipRules.allowedIPs, ipRules.blockedIPs)
386
+ !this.securityManager.isIPAuthorized(
387
+ record.remoteIP,
388
+ ipRules.allowedIPs,
389
+ ipRules.blockedIPs
390
+ )
422
391
  ) {
423
392
  return rejectIncomingConnection(
424
393
  'rejected',
425
- `Connection rejected: IP ${record.remoteIP} not allowed for domain ${domainConfig.domains.join(
426
- ', '
427
- )}`
394
+ `Connection rejected: IP ${
395
+ record.remoteIP
396
+ } not allowed for domain ${domainConfig.domains.join(', ')}`
428
397
  );
429
398
  }
430
- } else if (
431
- this.settings.defaultAllowedIPs &&
432
- this.settings.defaultAllowedIPs.length > 0
433
- ) {
399
+ } else if (this.settings.defaultAllowedIPs && this.settings.defaultAllowedIPs.length > 0) {
434
400
  if (
435
401
  !this.securityManager.isIPAuthorized(
436
402
  record.remoteIP,
@@ -497,28 +463,36 @@ export class ConnectionHandler {
497
463
  } else {
498
464
  // Attempt to find a matching forced domain config based on the local port.
499
465
  const forcedDomain = this.domainConfigManager.findDomainConfigForPort(localPort);
500
-
466
+
501
467
  if (forcedDomain) {
502
468
  const ipRules = this.domainConfigManager.getEffectiveIPRules(forcedDomain);
503
-
504
- if (!this.securityManager.isIPAuthorized(record.remoteIP, ipRules.allowedIPs, ipRules.blockedIPs)) {
469
+
470
+ if (
471
+ !this.securityManager.isIPAuthorized(
472
+ record.remoteIP,
473
+ ipRules.allowedIPs,
474
+ ipRules.blockedIPs
475
+ )
476
+ ) {
505
477
  console.log(
506
- `[${connectionId}] Connection from ${record.remoteIP} rejected: IP not allowed for domain ${forcedDomain.domains.join(
478
+ `[${connectionId}] Connection from ${
479
+ record.remoteIP
480
+ } rejected: IP not allowed for domain ${forcedDomain.domains.join(
507
481
  ', '
508
482
  )} on port ${localPort}.`
509
483
  );
510
484
  socket.end();
511
485
  return;
512
486
  }
513
-
487
+
514
488
  if (this.settings.enableDetailedLogging) {
515
489
  console.log(
516
- `[${connectionId}] Port-based connection from ${record.remoteIP} on port ${localPort} matched domain ${forcedDomain.domains.join(
517
- ', '
518
- )}.`
490
+ `[${connectionId}] Port-based connection from ${
491
+ record.remoteIP
492
+ } on port ${localPort} matched domain ${forcedDomain.domains.join(', ')}.`
519
493
  );
520
494
  }
521
-
495
+
522
496
  setupConnection('', undefined, forcedDomain, localPort);
523
497
  return;
524
498
  }
@@ -536,14 +510,14 @@ export class ConnectionHandler {
536
510
  clearTimeout(initialTimeout);
537
511
  initialTimeout = null;
538
512
  }
539
-
513
+
540
514
  initialDataReceived = true;
541
-
515
+
542
516
  // Block non-TLS connections on port 443
543
517
  if (!this.tlsManager.isTlsHandshake(chunk) && localPort === 443) {
544
518
  console.log(
545
519
  `[${connectionId}] Non-TLS connection detected on port 443 in SNI handler. ` +
546
- `Terminating connection - only TLS traffic is allowed on standard HTTPS port.`
520
+ `Terminating connection - only TLS traffic is allowed on standard HTTPS port.`
547
521
  );
548
522
  if (record.incomingTerminationReason === null) {
549
523
  record.incomingTerminationReason = 'non_tls_blocked';
@@ -576,56 +550,131 @@ export class ConnectionHandler {
576
550
 
577
551
  // Extract SNI
578
552
  serverName = this.tlsManager.extractSNI(chunk, connInfo) || '';
579
-
553
+
580
554
  // If allowSessionTicket is false and this is a ClientHello with no SNI, terminate the connection
581
- if (this.settings.allowSessionTicket === false &&
582
- this.tlsManager.isClientHello(chunk) &&
583
- !serverName) {
584
-
555
+ if (
556
+ this.settings.allowSessionTicket === false &&
557
+ this.tlsManager.isClientHello(chunk) &&
558
+ !serverName
559
+ ) {
585
560
  // Always block ClientHello without SNI when allowSessionTicket is false
586
561
  console.log(
587
562
  `[${connectionId}] No SNI detected in ClientHello and allowSessionTicket=false. ` +
588
- `Terminating connection to force new TLS handshake with SNI.`
563
+ `Sending unrecognized_name alert to encourage client to retry with SNI.`
589
564
  );
590
-
565
+
566
+ // Set the termination reason first to avoid races
567
+ if (record.incomingTerminationReason === null) {
568
+ record.incomingTerminationReason = 'session_ticket_blocked_no_sni';
569
+ this.connectionManager.incrementTerminationStat(
570
+ 'incoming',
571
+ 'session_ticket_blocked_no_sni'
572
+ );
573
+ }
574
+
591
575
  // Send a proper TLS alert before ending the connection
592
- // Using "unrecognized_name" (112) alert which is a warning level alert (1)
576
+ // Using "unrecognized_name" (112) alert which is a warning level alert (1)
593
577
  // that encourages clients to retry with proper SNI
594
578
  const alertData = Buffer.from([
595
- 0x15, // Alert record type
596
- 0x03, 0x03, // TLS 1.2 version
597
- 0x00, 0x02, // Length
598
- 0x01, // Warning alert level (not fatal)
599
- 0x70 // unrecognized_name alert (code 112)
579
+ 0x15, // Alert record type
580
+ 0x03,
581
+ 0x03, // TLS 1.2 version
582
+ 0x00,
583
+ 0x02, // Length
584
+ 0x01, // Warning alert level (not fatal)
585
+ 0x70, // unrecognized_name alert (code 112)
600
586
  ]);
601
-
587
+
602
588
  try {
603
- socket.write(alertData, () => {
604
- // Only close the socket after we're sure the alert was sent
605
- // Give the alert time to be processed by the client
606
- setTimeout(() => {
589
+ // Make sure the alert is sent as a single packet
590
+ socket.cork();
591
+ socket.write(alertData);
592
+ socket.uncork();
593
+
594
+ // Set a longer timeout to allow the client to properly handle the alert
595
+ // The client might respond by closing the connection or initiating a new handshake
596
+ const alertTimeout = setTimeout(() => {
597
+ if (!socket.destroyed) {
598
+ console.log(`[${connectionId}] Client didn't respond to TLS alert, closing connection gracefully.`);
599
+
600
+ // Gracefully end the connection
607
601
  socket.end();
608
602
 
609
- // Ensure complete cleanup happens a bit later
603
+ // Only destroy after a delay if it's still hanging
610
604
  setTimeout(() => {
611
605
  if (!socket.destroyed) {
606
+ console.log(`[${connectionId}] Forcibly closing connection that didn't terminate properly.`);
612
607
  socket.destroy();
613
608
  }
614
609
  this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
615
- }, 100);
616
- }, 100);
610
+ }, 2000);
611
+ }
612
+ }, 5000); // Give the client 5 seconds to respond to our alert
613
+
614
+ // Don't let this timeout keep the process alive
615
+ if (alertTimeout.unref) {
616
+ alertTimeout.unref();
617
+ }
618
+
619
+ // Handle a proper close from the client
620
+ socket.once('close', () => {
621
+ clearTimeout(alertTimeout);
622
+ console.log(`[${connectionId}] Client closed connection after receiving TLS alert.`);
623
+ this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni_client_closed');
617
624
  });
625
+
626
+ // Also handle if the client sends more data (possibly a new handshake with SNI)
627
+ socket.once('data', (newChunk) => {
628
+ clearTimeout(alertTimeout);
629
+ console.log(`[${connectionId}] Client sent new data after TLS alert, checking for SNI...`);
630
+
631
+ // This would normally be handled by our renegotiation handler,
632
+ // but since we're in a special case, we'll check for SNI again
633
+ if (this.tlsManager.isTlsHandshake(newChunk) && this.tlsManager.isClientHello(newChunk)) {
634
+ const newServerName = this.tlsManager.extractSNI(newChunk, connInfo);
635
+
636
+ if (newServerName) {
637
+ console.log(`[${connectionId}] Client provided SNI in new handshake: ${newServerName}`);
638
+
639
+ // Update the record
640
+ record.incomingTerminationReason = null;
641
+
642
+ // Remove termination stats increment
643
+ // Note: This is a little hacky as we don't have a proper way to decrement stats
644
+
645
+ // Process the new handshake with SNI
646
+ record.lockedDomain = newServerName;
647
+ setupConnection(newServerName, newChunk);
648
+ return;
649
+ } else {
650
+ console.log(`[${connectionId}] Client sent new handshake but still without SNI, closing connection.`);
651
+ socket.end();
652
+ setTimeout(() => {
653
+ if (!socket.destroyed) {
654
+ socket.destroy();
655
+ }
656
+ this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni_retry_failed');
657
+ }, 500);
658
+ }
659
+ } else {
660
+ console.log(`[${connectionId}] Client sent non-handshake data after TLS alert, closing connection.`);
661
+ socket.end();
662
+ setTimeout(() => {
663
+ if (!socket.destroyed) {
664
+ socket.destroy();
665
+ }
666
+ this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_invalid_response');
667
+ }, 500);
668
+ }
669
+ });
670
+
618
671
  } catch (err) {
619
672
  // If we can't send the alert, fall back to immediate termination
673
+ console.log(`[${connectionId}] Error sending TLS alert: ${err.message}`);
620
674
  socket.end();
621
675
  this.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
622
676
  }
623
-
624
- if (record.incomingTerminationReason === null) {
625
- record.incomingTerminationReason = 'session_ticket_blocked_no_sni';
626
- this.connectionManager.incrementTerminationStat('incoming', 'session_ticket_blocked_no_sni');
627
- }
628
-
677
+
629
678
  return;
630
679
  }
631
680
  }
@@ -674,23 +723,21 @@ export class ConnectionHandler {
674
723
  overridePort?: number
675
724
  ): void {
676
725
  const connectionId = record.id;
677
-
726
+
678
727
  // Determine target host
679
- const targetHost = domainConfig
680
- ? this.domainConfigManager.getTargetIP(domainConfig)
728
+ const targetHost = domainConfig
729
+ ? this.domainConfigManager.getTargetIP(domainConfig)
681
730
  : this.settings.targetIP!;
682
-
731
+
683
732
  // Determine target port
684
- const targetPort = overridePort !== undefined
685
- ? overridePort
686
- : this.settings.toPort;
687
-
733
+ const targetPort = overridePort !== undefined ? overridePort : this.settings.toPort;
734
+
688
735
  // Setup connection options
689
736
  const connectionOptions: plugins.net.NetConnectOpts = {
690
737
  host: targetHost,
691
738
  port: targetPort,
692
739
  };
693
-
740
+
694
741
  // Preserve source IP if configured
695
742
  if (this.settings.preserveSourceIP) {
696
743
  connectionOptions.localAddress = record.remoteIP.replace('::ffff:', '');
@@ -947,18 +994,20 @@ export class ConnectionHandler {
947
994
 
948
995
  // Process any remaining data in the queue before switching to piping
949
996
  processDataQueue();
950
-
997
+
951
998
  // Set up piping immediately
952
999
  pipingEstablished = true;
953
-
1000
+
954
1001
  // Flush all pending data to target
955
1002
  if (record.pendingData.length > 0) {
956
1003
  const combinedData = Buffer.concat(record.pendingData);
957
-
1004
+
958
1005
  if (this.settings.enableDetailedLogging) {
959
- console.log(`[${connectionId}] Forwarding ${combinedData.length} bytes of initial data to target`);
1006
+ console.log(
1007
+ `[${connectionId}] Forwarding ${combinedData.length} bytes of initial data to target`
1008
+ );
960
1009
  }
961
-
1010
+
962
1011
  // Write pending data immediately
963
1012
  targetSocket.write(combinedData, (err) => {
964
1013
  if (err) {
@@ -966,19 +1015,19 @@ export class ConnectionHandler {
966
1015
  return this.connectionManager.initiateCleanupOnce(record, 'write_error');
967
1016
  }
968
1017
  });
969
-
1018
+
970
1019
  // Clear the buffer now that we've processed it
971
1020
  record.pendingData = [];
972
1021
  record.pendingDataSize = 0;
973
1022
  }
974
-
1023
+
975
1024
  // Setup piping in both directions without any delays
976
1025
  socket.pipe(targetSocket);
977
1026
  targetSocket.pipe(socket);
978
-
1027
+
979
1028
  // Resume the socket to ensure data flows
980
1029
  socket.resume();
981
-
1030
+
982
1031
  // Process any data that might be queued in the interim
983
1032
  if (dataQueue.length > 0) {
984
1033
  // Write any remaining queued data directly to the target socket
@@ -989,7 +1038,7 @@ export class ConnectionHandler {
989
1038
  dataQueue.length = 0;
990
1039
  queueSize = 0;
991
1040
  }
992
-
1041
+
993
1042
  if (this.settings.enableDetailedLogging) {
994
1043
  console.log(
995
1044
  `[${connectionId}] Connection established: ${record.remoteIP} -> ${targetHost}:${connectionOptions.port}` +
@@ -1054,15 +1103,12 @@ export class ConnectionHandler {
1054
1103
  }
1055
1104
 
1056
1105
  // Set connection timeout
1057
- record.cleanupTimer = this.timeoutManager.setupConnectionTimeout(
1058
- record,
1059
- (record, reason) => {
1060
- console.log(
1061
- `[${connectionId}] Connection from ${record.remoteIP} exceeded max lifetime, forcing cleanup.`
1062
- );
1063
- this.connectionManager.initiateCleanupOnce(record, reason);
1064
- }
1065
- );
1106
+ record.cleanupTimer = this.timeoutManager.setupConnectionTimeout(record, (record, reason) => {
1107
+ console.log(
1108
+ `[${connectionId}] Connection from ${record.remoteIP} exceeded max lifetime, forcing cleanup.`
1109
+ );
1110
+ this.connectionManager.initiateCleanupOnce(record, reason);
1111
+ });
1066
1112
 
1067
1113
  // Mark TLS handshake as complete for TLS connections
1068
1114
  if (record.isTLS) {