@push.rocks/smartproxy 20.0.1 → 21.1.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/changelog.md +26 -0
- package/dist_ts/core/utils/proxy-protocol.d.ts +5 -17
- package/dist_ts/core/utils/proxy-protocol.js +13 -97
- package/dist_ts/core/utils/websocket-utils.d.ts +6 -7
- package/dist_ts/core/utils/websocket-utils.js +10 -66
- package/dist_ts/detection/detectors/http-detector-v2.d.ts +33 -0
- package/dist_ts/detection/detectors/http-detector-v2.js +87 -0
- package/dist_ts/detection/detectors/http-detector.d.ts +33 -0
- package/dist_ts/detection/detectors/http-detector.js +89 -0
- package/dist_ts/detection/detectors/quick-detector.d.ts +28 -0
- package/dist_ts/detection/detectors/quick-detector.js +131 -0
- package/dist_ts/detection/detectors/routing-extractor.d.ts +28 -0
- package/dist_ts/detection/detectors/routing-extractor.js +122 -0
- package/dist_ts/detection/detectors/tls-detector-v2.d.ts +33 -0
- package/dist_ts/detection/detectors/tls-detector-v2.js +80 -0
- package/dist_ts/detection/detectors/tls-detector.d.ts +33 -0
- package/dist_ts/detection/detectors/tls-detector.js +106 -0
- package/dist_ts/detection/index.d.ts +17 -0
- package/dist_ts/detection/index.js +22 -0
- package/dist_ts/detection/models/detection-types.d.ts +87 -0
- package/dist_ts/detection/models/detection-types.js +5 -0
- package/dist_ts/detection/models/interfaces.d.ts +97 -0
- package/dist_ts/detection/models/interfaces.js +5 -0
- package/dist_ts/detection/protocol-detector-v2.d.ts +46 -0
- package/dist_ts/detection/protocol-detector-v2.js +116 -0
- package/dist_ts/detection/protocol-detector.d.ts +74 -0
- package/dist_ts/detection/protocol-detector.js +173 -0
- package/dist_ts/detection/utils/buffer-utils.d.ts +61 -0
- package/dist_ts/detection/utils/buffer-utils.js +127 -0
- package/dist_ts/detection/utils/fragment-manager.d.ts +31 -0
- package/dist_ts/detection/utils/fragment-manager.js +53 -0
- package/dist_ts/detection/utils/parser-utils.d.ts +42 -0
- package/dist_ts/detection/utils/parser-utils.js +63 -0
- package/dist_ts/index.d.ts +2 -1
- package/dist_ts/index.js +3 -2
- package/dist_ts/protocols/common/fragment-handler.d.ts +73 -0
- package/dist_ts/protocols/common/fragment-handler.js +117 -0
- package/dist_ts/protocols/common/index.d.ts +7 -0
- package/dist_ts/protocols/common/index.js +8 -0
- package/dist_ts/protocols/common/types.d.ts +68 -0
- package/dist_ts/protocols/common/types.js +7 -0
- package/dist_ts/protocols/http/constants.d.ts +119 -0
- package/dist_ts/protocols/http/constants.js +200 -0
- package/dist_ts/protocols/http/index.d.ts +7 -0
- package/dist_ts/protocols/http/index.js +8 -0
- package/dist_ts/protocols/http/parser.d.ts +58 -0
- package/dist_ts/protocols/http/parser.js +184 -0
- package/dist_ts/protocols/http/types.d.ts +62 -0
- package/dist_ts/protocols/http/types.js +5 -0
- package/dist_ts/protocols/index.d.ts +11 -0
- package/dist_ts/protocols/index.js +12 -0
- package/dist_ts/protocols/proxy/index.d.ts +6 -0
- package/dist_ts/protocols/proxy/index.js +7 -0
- package/dist_ts/protocols/proxy/parser.d.ts +44 -0
- package/dist_ts/protocols/proxy/parser.js +153 -0
- package/dist_ts/protocols/proxy/types.d.ts +47 -0
- package/dist_ts/protocols/proxy/types.js +6 -0
- package/dist_ts/protocols/tls/alerts/index.d.ts +4 -0
- package/dist_ts/protocols/tls/alerts/index.js +5 -0
- package/dist_ts/protocols/tls/alerts/tls-alert.d.ts +150 -0
- package/dist_ts/protocols/tls/alerts/tls-alert.js +226 -0
- package/dist_ts/protocols/tls/constants.d.ts +122 -0
- package/dist_ts/protocols/tls/constants.js +135 -0
- package/dist_ts/protocols/tls/index.d.ts +12 -0
- package/dist_ts/protocols/tls/index.js +27 -0
- package/dist_ts/protocols/tls/parser.d.ts +53 -0
- package/dist_ts/protocols/tls/parser.js +294 -0
- package/dist_ts/protocols/tls/sni/client-hello-parser.d.ts +100 -0
- package/dist_ts/protocols/tls/sni/client-hello-parser.js +463 -0
- package/dist_ts/protocols/tls/sni/index.d.ts +5 -0
- package/dist_ts/protocols/tls/sni/index.js +6 -0
- package/dist_ts/protocols/tls/sni/sni-extraction.d.ts +58 -0
- package/dist_ts/protocols/tls/sni/sni-extraction.js +275 -0
- package/dist_ts/protocols/tls/types.d.ts +65 -0
- package/dist_ts/protocols/tls/types.js +5 -0
- package/dist_ts/protocols/tls/utils/index.d.ts +4 -0
- package/dist_ts/protocols/tls/utils/index.js +5 -0
- package/dist_ts/protocols/tls/utils/tls-utils.d.ts +158 -0
- package/dist_ts/protocols/tls/utils/tls-utils.js +187 -0
- package/dist_ts/protocols/websocket/constants.d.ts +55 -0
- package/dist_ts/protocols/websocket/constants.js +58 -0
- package/dist_ts/protocols/websocket/index.d.ts +7 -0
- package/dist_ts/protocols/websocket/index.js +8 -0
- package/dist_ts/protocols/websocket/types.d.ts +47 -0
- package/dist_ts/protocols/websocket/types.js +5 -0
- package/dist_ts/protocols/websocket/utils.d.ts +25 -0
- package/dist_ts/protocols/websocket/utils.js +103 -0
- package/dist_ts/proxies/http-proxy/models/http-types.d.ts +25 -27
- package/dist_ts/proxies/http-proxy/models/http-types.js +24 -44
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -0
- package/dist_ts/proxies/smart-proxy/models/route-types.js +1 -1
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +81 -61
- package/dist_ts/proxies/smart-proxy/tls-manager.js +2 -1
- package/dist_ts/proxies/smart-proxy/utils/index.d.ts +1 -2
- package/dist_ts/proxies/smart-proxy/utils/index.js +3 -4
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +112 -8
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +231 -76
- package/dist_ts/tls/index.d.ts +5 -7
- package/dist_ts/tls/index.js +8 -11
- package/dist_ts/tls/sni/client-hello-parser.js +3 -2
- package/dist_ts/tls/sni/sni-handler.js +4 -4
- package/dist_ts/tls/utils/tls-utils.d.ts +1 -110
- package/dist_ts/tls/utils/tls-utils.js +4 -116
- package/package.json +17 -8
- package/readme.md +471 -2345
- package/readme.plan.md +0 -0
- package/ts/core/utils/proxy-protocol.ts +14 -131
- package/ts/core/utils/websocket-utils.ts +12 -60
- package/ts/detection/detectors/http-detector.ts +114 -0
- package/ts/detection/detectors/quick-detector.ts +148 -0
- package/ts/detection/detectors/routing-extractor.ts +147 -0
- package/ts/detection/detectors/tls-detector.ts +120 -0
- package/ts/detection/index.ts +25 -0
- package/ts/detection/models/detection-types.ts +102 -0
- package/ts/detection/models/interfaces.ts +115 -0
- package/ts/detection/protocol-detector.ts +230 -0
- package/ts/detection/utils/buffer-utils.ts +141 -0
- package/ts/detection/utils/fragment-manager.ts +64 -0
- package/ts/detection/utils/parser-utils.ts +77 -0
- package/ts/index.ts +3 -2
- package/ts/protocols/common/fragment-handler.ts +163 -0
- package/ts/protocols/common/index.ts +8 -0
- package/ts/protocols/common/types.ts +76 -0
- package/ts/protocols/http/constants.ts +219 -0
- package/ts/protocols/http/index.ts +8 -0
- package/ts/protocols/http/parser.ts +219 -0
- package/ts/protocols/http/types.ts +70 -0
- package/ts/protocols/index.ts +12 -0
- package/ts/protocols/proxy/index.ts +7 -0
- package/ts/protocols/proxy/parser.ts +183 -0
- package/ts/protocols/proxy/types.ts +53 -0
- package/ts/{tls → protocols/tls}/alerts/tls-alert.ts +1 -1
- package/ts/protocols/tls/index.ts +37 -0
- package/ts/protocols/tls/sni/index.ts +6 -0
- package/ts/{tls → protocols/tls}/utils/tls-utils.ts +1 -1
- package/ts/protocols/websocket/constants.ts +60 -0
- package/ts/protocols/websocket/index.ts +8 -0
- package/ts/protocols/websocket/types.ts +53 -0
- package/ts/protocols/websocket/utils.ts +98 -0
- package/ts/proxies/http-proxy/models/http-types.ts +29 -46
- package/ts/proxies/smart-proxy/models/interfaces.ts +7 -1
- package/ts/proxies/smart-proxy/models/route-types.ts +0 -1
- package/ts/proxies/smart-proxy/route-connection-handler.ts +91 -68
- package/ts/proxies/smart-proxy/tls-manager.ts +1 -0
- package/ts/proxies/smart-proxy/utils/index.ts +2 -13
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +323 -86
- package/ts/tls/index.ts +8 -12
- package/ts/tls/sni/sni-handler.ts +3 -3
- package/ts/forwarding/config/forwarding-types.ts +0 -76
- package/ts/forwarding/config/index.ts +0 -26
- package/ts/forwarding/factory/forwarding-factory.ts +0 -189
- package/ts/forwarding/factory/index.ts +0 -5
- package/ts/forwarding/handlers/base-handler.ts +0 -155
- package/ts/forwarding/handlers/http-handler.ts +0 -163
- package/ts/forwarding/handlers/https-passthrough-handler.ts +0 -185
- package/ts/forwarding/handlers/https-terminate-to-http-handler.ts +0 -312
- package/ts/forwarding/handlers/https-terminate-to-https-handler.ts +0 -297
- package/ts/forwarding/handlers/index.ts +0 -9
- package/ts/forwarding/index.ts +0 -35
- package/ts/proxies/smart-proxy/utils/route-patterns.ts +0 -403
- /package/ts/{tls → protocols/tls}/alerts/index.ts +0 -0
- /package/ts/{tls → protocols/tls}/sni/client-hello-parser.ts +0 -0
- /package/ts/{tls → protocols/tls}/sni/sni-extraction.ts +0 -0
- /package/ts/{tls → protocols/tls}/utils/index.ts +0 -0
|
@@ -10,6 +10,7 @@ import { WrappedSocket } from '../../core/models/wrapped-socket.js';
|
|
|
10
10
|
import { getUnderlyingSocket } from '../../core/models/socket-types.js';
|
|
11
11
|
import { ProxyProtocolParser } from '../../core/utils/proxy-protocol.js';
|
|
12
12
|
import type { SmartProxy } from './smart-proxy.js';
|
|
13
|
+
import { ProtocolDetector } from '../../detection/index.js';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Handles new connection processing and setup logic with support for route-based configuration
|
|
@@ -301,11 +302,27 @@ export class RouteConnectionHandler {
|
|
|
301
302
|
});
|
|
302
303
|
|
|
303
304
|
// Handler for processing initial data (after potential PROXY protocol)
|
|
304
|
-
const processInitialData = (chunk: Buffer) => {
|
|
305
|
+
const processInitialData = async (chunk: Buffer) => {
|
|
306
|
+
// Use ProtocolDetector to identify protocol
|
|
307
|
+
const connectionId = ProtocolDetector.createConnectionId({
|
|
308
|
+
sourceIp: record.remoteIP,
|
|
309
|
+
sourcePort: socket.remotePort,
|
|
310
|
+
destIp: socket.localAddress,
|
|
311
|
+
destPort: socket.localPort,
|
|
312
|
+
socketId: record.id
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
const detectionResult = await ProtocolDetector.detectWithConnectionTracking(
|
|
316
|
+
chunk,
|
|
317
|
+
connectionId,
|
|
318
|
+
{ extractFullHeaders: false } // Only extract essential info for routing
|
|
319
|
+
);
|
|
320
|
+
|
|
305
321
|
// Block non-TLS connections on port 443
|
|
306
|
-
if (
|
|
307
|
-
logger.log('warn', `Non-TLS connection ${
|
|
308
|
-
connectionId,
|
|
322
|
+
if (localPort === 443 && detectionResult.protocol !== 'tls') {
|
|
323
|
+
logger.log('warn', `Non-TLS connection ${record.id} detected on port 443. Terminating connection - only TLS traffic is allowed on standard HTTPS port.`, {
|
|
324
|
+
connectionId: record.id,
|
|
325
|
+
detectedProtocol: detectionResult.protocol,
|
|
309
326
|
message: 'Terminating connection - only TLS traffic is allowed on standard HTTPS port.',
|
|
310
327
|
component: 'route-handler'
|
|
311
328
|
});
|
|
@@ -318,71 +335,78 @@ export class RouteConnectionHandler {
|
|
|
318
335
|
return;
|
|
319
336
|
}
|
|
320
337
|
|
|
321
|
-
//
|
|
338
|
+
// Extract domain and protocol info
|
|
322
339
|
let serverName = '';
|
|
323
|
-
if (
|
|
340
|
+
if (detectionResult.protocol === 'tls') {
|
|
324
341
|
record.isTLS = true;
|
|
342
|
+
serverName = detectionResult.connectionInfo.domain || '';
|
|
343
|
+
|
|
344
|
+
// Lock the connection to the negotiated SNI
|
|
345
|
+
record.lockedDomain = serverName;
|
|
325
346
|
|
|
326
|
-
// Check
|
|
327
|
-
if (this.smartProxy.
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
connectionId,
|
|
346
|
-
component: 'route-handler'
|
|
347
|
-
});
|
|
348
|
-
if (record.incomingTerminationReason === null) {
|
|
349
|
-
record.incomingTerminationReason = 'session_ticket_blocked_no_sni';
|
|
350
|
-
this.smartProxy.connectionManager.incrementTerminationStat(
|
|
351
|
-
'incoming',
|
|
352
|
-
'session_ticket_blocked_no_sni'
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
const alert = Buffer.from([0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x70]);
|
|
356
|
-
try {
|
|
357
|
-
// Count the alert bytes being sent
|
|
358
|
-
record.bytesSent += alert.length;
|
|
359
|
-
if (this.smartProxy.metricsCollector) {
|
|
360
|
-
this.smartProxy.metricsCollector.recordBytes(record.id, 0, alert.length);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
socket.cork();
|
|
364
|
-
socket.write(alert);
|
|
365
|
-
socket.uncork();
|
|
366
|
-
socket.end();
|
|
367
|
-
} catch {
|
|
368
|
-
socket.end();
|
|
347
|
+
// Check if we should reject connections without SNI
|
|
348
|
+
if (!serverName && this.smartProxy.settings.allowSessionTicket === false) {
|
|
349
|
+
logger.log('warn', `No SNI detected in TLS ClientHello for connection ${record.id}; sending TLS alert`, {
|
|
350
|
+
connectionId: record.id,
|
|
351
|
+
component: 'route-handler'
|
|
352
|
+
});
|
|
353
|
+
if (record.incomingTerminationReason === null) {
|
|
354
|
+
record.incomingTerminationReason = 'session_ticket_blocked_no_sni';
|
|
355
|
+
this.smartProxy.connectionManager.incrementTerminationStat(
|
|
356
|
+
'incoming',
|
|
357
|
+
'session_ticket_blocked_no_sni'
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
const alert = Buffer.from([0x15, 0x03, 0x03, 0x00, 0x02, 0x01, 0x70]);
|
|
361
|
+
try {
|
|
362
|
+
// Count the alert bytes being sent
|
|
363
|
+
record.bytesSent += alert.length;
|
|
364
|
+
if (this.smartProxy.metricsCollector) {
|
|
365
|
+
this.smartProxy.metricsCollector.recordBytes(record.id, 0, alert.length);
|
|
369
366
|
}
|
|
370
|
-
|
|
371
|
-
|
|
367
|
+
|
|
368
|
+
socket.cork();
|
|
369
|
+
socket.write(alert);
|
|
370
|
+
socket.uncork();
|
|
371
|
+
socket.end();
|
|
372
|
+
} catch {
|
|
373
|
+
socket.end();
|
|
372
374
|
}
|
|
375
|
+
this.smartProxy.connectionManager.cleanupConnection(record, 'session_ticket_blocked_no_sni');
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
373
378
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
379
|
+
if (this.smartProxy.settings.enableDetailedLogging) {
|
|
380
|
+
logger.log('info', `TLS connection with SNI`, {
|
|
381
|
+
connectionId: record.id,
|
|
382
|
+
serverName: serverName || '(empty)',
|
|
383
|
+
component: 'route-handler'
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
} else if (detectionResult.protocol === 'http') {
|
|
387
|
+
// For HTTP, extract domain from Host header
|
|
388
|
+
serverName = detectionResult.connectionInfo.domain || '';
|
|
389
|
+
|
|
390
|
+
// Store HTTP-specific info for later use
|
|
391
|
+
record.httpInfo = {
|
|
392
|
+
method: detectionResult.connectionInfo.method,
|
|
393
|
+
path: detectionResult.connectionInfo.path,
|
|
394
|
+
headers: detectionResult.connectionInfo.headers
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
if (this.smartProxy.settings.enableDetailedLogging) {
|
|
398
|
+
logger.log('info', `HTTP connection detected`, {
|
|
399
|
+
connectionId: record.id,
|
|
400
|
+
domain: serverName || '(no host header)',
|
|
401
|
+
method: detectionResult.connectionInfo.method,
|
|
402
|
+
path: detectionResult.connectionInfo.path,
|
|
403
|
+
component: 'route-handler'
|
|
404
|
+
});
|
|
381
405
|
}
|
|
382
406
|
}
|
|
383
407
|
|
|
384
408
|
// Find the appropriate route for this connection
|
|
385
|
-
this.routeConnection(socket, record, serverName, chunk);
|
|
409
|
+
this.routeConnection(socket, record, serverName, chunk, detectionResult);
|
|
386
410
|
};
|
|
387
411
|
|
|
388
412
|
// First data handler to capture initial TLS handshake or PROXY protocol
|
|
@@ -454,7 +478,8 @@ export class RouteConnectionHandler {
|
|
|
454
478
|
socket: plugins.net.Socket | WrappedSocket,
|
|
455
479
|
record: IConnectionRecord,
|
|
456
480
|
serverName: string,
|
|
457
|
-
initialChunk?: Buffer
|
|
481
|
+
initialChunk?: Buffer,
|
|
482
|
+
detectionResult?: any // Using any temporarily to avoid circular dependency issues
|
|
458
483
|
): void {
|
|
459
484
|
const connectionId = record.id;
|
|
460
485
|
const localPort = record.localPort;
|
|
@@ -635,7 +660,7 @@ export class RouteConnectionHandler {
|
|
|
635
660
|
// Handle the route based on its action type
|
|
636
661
|
switch (route.action.type) {
|
|
637
662
|
case 'forward':
|
|
638
|
-
return this.handleForwardAction(socket, record, route, initialChunk);
|
|
663
|
+
return this.handleForwardAction(socket, record, route, initialChunk, detectionResult);
|
|
639
664
|
|
|
640
665
|
case 'socket-handler':
|
|
641
666
|
logger.log('info', `Handling socket-handler action for route ${route.name}`, {
|
|
@@ -738,7 +763,8 @@ export class RouteConnectionHandler {
|
|
|
738
763
|
socket: plugins.net.Socket | WrappedSocket,
|
|
739
764
|
record: IConnectionRecord,
|
|
740
765
|
route: IRouteConfig,
|
|
741
|
-
initialChunk?: Buffer
|
|
766
|
+
initialChunk?: Buffer,
|
|
767
|
+
detectionResult?: any // Using any temporarily to avoid circular dependency issues
|
|
742
768
|
): void {
|
|
743
769
|
const connectionId = record.id;
|
|
744
770
|
const action = route.action as IRouteAction;
|
|
@@ -819,14 +845,11 @@ export class RouteConnectionHandler {
|
|
|
819
845
|
// Create context for target selection
|
|
820
846
|
const targetSelectionContext = {
|
|
821
847
|
port: record.localPort,
|
|
822
|
-
path:
|
|
823
|
-
headers:
|
|
824
|
-
method:
|
|
848
|
+
path: record.httpInfo?.path,
|
|
849
|
+
headers: record.httpInfo?.headers,
|
|
850
|
+
method: record.httpInfo?.method
|
|
825
851
|
};
|
|
826
852
|
|
|
827
|
-
// TODO: Extract path, headers, and method from initialChunk if it's HTTP
|
|
828
|
-
// For now, we'll select based on port only
|
|
829
|
-
|
|
830
853
|
const selectedTarget = this.selectTarget(action.targets, targetSelectionContext);
|
|
831
854
|
if (!selectedTarget) {
|
|
832
855
|
logger.log('error', `No matching target found for connection ${connectionId}`, {
|
|
@@ -14,23 +14,12 @@ export * from './route-validators.js';
|
|
|
14
14
|
// Export route utilities for route operations
|
|
15
15
|
export * from './route-utils.js';
|
|
16
16
|
|
|
17
|
-
// Export
|
|
18
|
-
import {
|
|
19
|
-
createWebSocketRoute as createWebSocketPatternRoute,
|
|
20
|
-
createLoadBalancerRoute as createLoadBalancerPatternRoute,
|
|
21
|
-
createApiGatewayRoute,
|
|
22
|
-
addRateLimiting,
|
|
23
|
-
addBasicAuth,
|
|
24
|
-
addJwtAuth
|
|
25
|
-
} from './route-patterns.js';
|
|
26
|
-
|
|
17
|
+
// Export additional functions from route-helpers that weren't already exported
|
|
27
18
|
export {
|
|
28
|
-
createWebSocketPatternRoute,
|
|
29
|
-
createLoadBalancerPatternRoute,
|
|
30
19
|
createApiGatewayRoute,
|
|
31
20
|
addRateLimiting,
|
|
32
21
|
addBasicAuth,
|
|
33
22
|
addJwtAuth
|
|
34
|
-
};
|
|
23
|
+
} from './route-helpers.js';
|
|
35
24
|
|
|
36
25
|
// Migration utilities have been removed as they are no longer needed
|