@push.rocks/smartproxy 22.4.2 → 23.0.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 (101) hide show
  1. package/changelog.md +36 -0
  2. package/dist_rust/rustproxy +0 -0
  3. package/dist_ts/00_commitinfo_data.js +1 -1
  4. package/dist_ts/index.d.ts +1 -6
  5. package/dist_ts/index.js +3 -11
  6. package/dist_ts/protocols/common/fragment-handler.js +5 -1
  7. package/dist_ts/proxies/index.d.ts +1 -6
  8. package/dist_ts/proxies/index.js +2 -8
  9. package/dist_ts/proxies/smart-proxy/index.d.ts +5 -10
  10. package/dist_ts/proxies/smart-proxy/index.js +7 -13
  11. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -2
  12. package/dist_ts/proxies/smart-proxy/models/route-types.js +1 -1
  13. package/dist_ts/proxies/smart-proxy/route-preprocessor.d.ts +37 -0
  14. package/dist_ts/proxies/smart-proxy/route-preprocessor.js +103 -0
  15. package/dist_ts/proxies/smart-proxy/rust-binary-locator.d.ts +23 -0
  16. package/dist_ts/proxies/smart-proxy/rust-binary-locator.js +104 -0
  17. package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.d.ts +74 -0
  18. package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.js +146 -0
  19. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.d.ts +49 -0
  20. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.js +259 -0
  21. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +39 -157
  22. package/dist_ts/proxies/smart-proxy/smart-proxy.js +224 -621
  23. package/dist_ts/proxies/smart-proxy/socket-handler-server.d.ts +45 -0
  24. package/dist_ts/proxies/smart-proxy/socket-handler-server.js +253 -0
  25. package/dist_ts/routing/index.d.ts +1 -1
  26. package/dist_ts/routing/index.js +3 -3
  27. package/dist_ts/routing/models/http-types.d.ts +119 -4
  28. package/dist_ts/routing/models/http-types.js +93 -5
  29. package/package.json +1 -1
  30. package/readme.md +444 -219
  31. package/ts/00_commitinfo_data.ts +1 -1
  32. package/ts/index.ts +4 -15
  33. package/ts/protocols/common/fragment-handler.ts +4 -0
  34. package/ts/proxies/index.ts +1 -12
  35. package/ts/proxies/smart-proxy/index.ts +6 -13
  36. package/ts/proxies/smart-proxy/models/interfaces.ts +6 -4
  37. package/ts/proxies/smart-proxy/models/route-types.ts +0 -2
  38. package/ts/proxies/smart-proxy/route-preprocessor.ts +122 -0
  39. package/ts/proxies/smart-proxy/rust-binary-locator.ts +112 -0
  40. package/ts/proxies/smart-proxy/rust-metrics-adapter.ts +161 -0
  41. package/ts/proxies/smart-proxy/rust-proxy-bridge.ts +310 -0
  42. package/ts/proxies/smart-proxy/smart-proxy.ts +282 -798
  43. package/ts/proxies/smart-proxy/socket-handler-server.ts +279 -0
  44. package/ts/routing/index.ts +2 -2
  45. package/ts/routing/models/http-types.ts +147 -4
  46. package/dist_ts/proxies/nftables-proxy/index.d.ts +0 -6
  47. package/dist_ts/proxies/nftables-proxy/index.js +0 -7
  48. package/dist_ts/proxies/nftables-proxy/models/errors.d.ts +0 -15
  49. package/dist_ts/proxies/nftables-proxy/models/errors.js +0 -28
  50. package/dist_ts/proxies/nftables-proxy/models/index.d.ts +0 -5
  51. package/dist_ts/proxies/nftables-proxy/models/index.js +0 -6
  52. package/dist_ts/proxies/nftables-proxy/models/interfaces.d.ts +0 -75
  53. package/dist_ts/proxies/nftables-proxy/models/interfaces.js +0 -5
  54. package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +0 -124
  55. package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +0 -1374
  56. package/dist_ts/proxies/nftables-proxy/utils/index.d.ts +0 -9
  57. package/dist_ts/proxies/nftables-proxy/utils/index.js +0 -12
  58. package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.d.ts +0 -66
  59. package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.js +0 -131
  60. package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.d.ts +0 -39
  61. package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.js +0 -112
  62. package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.d.ts +0 -59
  63. package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.js +0 -130
  64. package/ts/proxies/http-proxy/connection-pool.ts +0 -228
  65. package/ts/proxies/http-proxy/context-creator.ts +0 -145
  66. package/ts/proxies/http-proxy/default-certificates.ts +0 -150
  67. package/ts/proxies/http-proxy/function-cache.ts +0 -279
  68. package/ts/proxies/http-proxy/handlers/index.ts +0 -5
  69. package/ts/proxies/http-proxy/http-proxy.ts +0 -669
  70. package/ts/proxies/http-proxy/http-request-handler.ts +0 -331
  71. package/ts/proxies/http-proxy/http2-request-handler.ts +0 -255
  72. package/ts/proxies/http-proxy/index.ts +0 -18
  73. package/ts/proxies/http-proxy/models/http-types.ts +0 -148
  74. package/ts/proxies/http-proxy/models/index.ts +0 -5
  75. package/ts/proxies/http-proxy/models/types.ts +0 -125
  76. package/ts/proxies/http-proxy/request-handler.ts +0 -878
  77. package/ts/proxies/http-proxy/security-manager.ts +0 -413
  78. package/ts/proxies/http-proxy/websocket-handler.ts +0 -581
  79. package/ts/proxies/nftables-proxy/index.ts +0 -6
  80. package/ts/proxies/nftables-proxy/models/errors.ts +0 -30
  81. package/ts/proxies/nftables-proxy/models/index.ts +0 -5
  82. package/ts/proxies/nftables-proxy/models/interfaces.ts +0 -94
  83. package/ts/proxies/nftables-proxy/nftables-proxy.ts +0 -1754
  84. package/ts/proxies/nftables-proxy/utils/index.ts +0 -38
  85. package/ts/proxies/nftables-proxy/utils/nft-command-executor.ts +0 -162
  86. package/ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.ts +0 -125
  87. package/ts/proxies/nftables-proxy/utils/nft-rule-validator.ts +0 -156
  88. package/ts/proxies/smart-proxy/acme-state-manager.ts +0 -112
  89. package/ts/proxies/smart-proxy/cert-store.ts +0 -92
  90. package/ts/proxies/smart-proxy/certificate-manager.ts +0 -895
  91. package/ts/proxies/smart-proxy/connection-manager.ts +0 -809
  92. package/ts/proxies/smart-proxy/http-proxy-bridge.ts +0 -213
  93. package/ts/proxies/smart-proxy/metrics-collector.ts +0 -453
  94. package/ts/proxies/smart-proxy/nftables-manager.ts +0 -271
  95. package/ts/proxies/smart-proxy/port-manager.ts +0 -358
  96. package/ts/proxies/smart-proxy/route-connection-handler.ts +0 -1712
  97. package/ts/proxies/smart-proxy/route-orchestrator.ts +0 -297
  98. package/ts/proxies/smart-proxy/security-manager.ts +0 -269
  99. package/ts/proxies/smart-proxy/throughput-tracker.ts +0 -138
  100. package/ts/proxies/smart-proxy/timeout-manager.ts +0 -196
  101. package/ts/proxies/smart-proxy/tls-manager.ts +0 -171
@@ -1,196 +0,0 @@
1
- import type { IConnectionRecord } from './models/interfaces.js';
2
- import type { SmartProxy } from './smart-proxy.js';
3
-
4
- /**
5
- * Manages timeouts and inactivity tracking for connections
6
- */
7
- export class TimeoutManager {
8
- constructor(private smartProxy: SmartProxy) {}
9
-
10
- /**
11
- * Ensure timeout values don't exceed Node.js max safe integer
12
- */
13
- public ensureSafeTimeout(timeout: number): number {
14
- const MAX_SAFE_TIMEOUT = 2147483647; // Maximum safe value (2^31 - 1)
15
- return Math.min(Math.floor(timeout), MAX_SAFE_TIMEOUT);
16
- }
17
-
18
- /**
19
- * Generate a slightly randomized timeout to prevent thundering herd
20
- */
21
- public randomizeTimeout(baseTimeout: number, variationPercent: number = 5): number {
22
- const safeBaseTimeout = this.ensureSafeTimeout(baseTimeout);
23
- const variation = safeBaseTimeout * (variationPercent / 100);
24
- return this.ensureSafeTimeout(
25
- safeBaseTimeout + Math.floor(Math.random() * variation * 2) - variation
26
- );
27
- }
28
-
29
- /**
30
- * Update connection activity timestamp
31
- */
32
- public updateActivity(record: IConnectionRecord): void {
33
- record.lastActivity = Date.now();
34
-
35
- // Clear any inactivity warning
36
- if (record.inactivityWarningIssued) {
37
- record.inactivityWarningIssued = false;
38
- }
39
- }
40
-
41
- /**
42
- * Calculate effective inactivity timeout based on connection type
43
- */
44
- public getEffectiveInactivityTimeout(record: IConnectionRecord): number {
45
- let effectiveTimeout = this.smartProxy.settings.inactivityTimeout || 14400000; // 4 hours default
46
-
47
- // For immortal keep-alive connections, use an extremely long timeout
48
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
49
- return Number.MAX_SAFE_INTEGER;
50
- }
51
-
52
- // For extended keep-alive connections, apply multiplier
53
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'extended') {
54
- const multiplier = this.smartProxy.settings.keepAliveInactivityMultiplier || 6;
55
- effectiveTimeout = effectiveTimeout * multiplier;
56
- }
57
-
58
- return this.ensureSafeTimeout(effectiveTimeout);
59
- }
60
-
61
- /**
62
- * Calculate effective max lifetime based on connection type
63
- */
64
- public getEffectiveMaxLifetime(record: IConnectionRecord): number {
65
- // Use route-specific timeout if available from the routeConfig
66
- const baseTimeout = record.routeConfig?.action.advanced?.timeout ||
67
- this.smartProxy.settings.maxConnectionLifetime ||
68
- 86400000; // 24 hours default
69
-
70
- // For immortal keep-alive connections, use an extremely long lifetime
71
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
72
- return Number.MAX_SAFE_INTEGER;
73
- }
74
-
75
- // For extended keep-alive connections, use the extended lifetime setting
76
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'extended') {
77
- return this.ensureSafeTimeout(
78
- this.smartProxy.settings.extendedKeepAliveLifetime || 7 * 24 * 60 * 60 * 1000 // 7 days default
79
- );
80
- }
81
-
82
- // Apply randomization if enabled
83
- if (this.smartProxy.settings.enableRandomizedTimeouts) {
84
- return this.randomizeTimeout(baseTimeout);
85
- }
86
-
87
- return this.ensureSafeTimeout(baseTimeout);
88
- }
89
-
90
- /**
91
- * Setup connection timeout
92
- * @returns The cleanup timer
93
- */
94
- public setupConnectionTimeout(
95
- record: IConnectionRecord,
96
- onTimeout: (record: IConnectionRecord, reason: string) => void
97
- ): NodeJS.Timeout | null {
98
- // Clear any existing timer
99
- if (record.cleanupTimer) {
100
- clearTimeout(record.cleanupTimer);
101
- }
102
-
103
- // Skip timeout for immortal keep-alive connections
104
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
105
- return null;
106
- }
107
-
108
- // Calculate effective timeout
109
- const effectiveLifetime = this.getEffectiveMaxLifetime(record);
110
-
111
- // Set up the timeout
112
- const timer = setTimeout(() => {
113
- // Call the provided callback
114
- onTimeout(record, 'connection_timeout');
115
- }, effectiveLifetime);
116
-
117
- // Make sure timeout doesn't keep the process alive
118
- if (timer.unref) {
119
- timer.unref();
120
- }
121
-
122
- return timer;
123
- }
124
-
125
- /**
126
- * Check for inactivity on a connection
127
- * @returns Object with check results
128
- */
129
- public checkInactivity(record: IConnectionRecord): {
130
- isInactive: boolean;
131
- shouldWarn: boolean;
132
- inactivityTime: number;
133
- effectiveTimeout: number;
134
- } {
135
- // Skip for connections with inactivity check disabled
136
- if (this.smartProxy.settings.disableInactivityCheck) {
137
- return {
138
- isInactive: false,
139
- shouldWarn: false,
140
- inactivityTime: 0,
141
- effectiveTimeout: 0
142
- };
143
- }
144
-
145
- // Skip for immortal keep-alive connections
146
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
147
- return {
148
- isInactive: false,
149
- shouldWarn: false,
150
- inactivityTime: 0,
151
- effectiveTimeout: 0
152
- };
153
- }
154
-
155
- const now = Date.now();
156
- const inactivityTime = now - record.lastActivity;
157
- const effectiveTimeout = this.getEffectiveInactivityTimeout(record);
158
-
159
- // Check if inactive
160
- const isInactive = inactivityTime > effectiveTimeout;
161
-
162
- // For keep-alive connections, we should warn first
163
- const shouldWarn = record.hasKeepAlive &&
164
- isInactive &&
165
- !record.inactivityWarningIssued;
166
-
167
- return {
168
- isInactive,
169
- shouldWarn,
170
- inactivityTime,
171
- effectiveTimeout
172
- };
173
- }
174
-
175
- /**
176
- * Apply socket timeout settings
177
- */
178
- public applySocketTimeouts(record: IConnectionRecord): void {
179
- // Skip for immortal keep-alive connections
180
- if (record.hasKeepAlive && this.smartProxy.settings.keepAliveTreatment === 'immortal') {
181
- // Disable timeouts completely for immortal connections
182
- record.incoming.setTimeout(0);
183
- if (record.outgoing) {
184
- record.outgoing.setTimeout(0);
185
- }
186
- return;
187
- }
188
-
189
- // Apply normal timeouts
190
- const timeout = this.ensureSafeTimeout(this.smartProxy.settings.socketTimeout || 3600000); // 1 hour default
191
- record.incoming.setTimeout(timeout);
192
- if (record.outgoing) {
193
- record.outgoing.setTimeout(timeout);
194
- }
195
- }
196
- }
@@ -1,171 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
- import { SniHandler } from '../../tls/sni/sni-handler.js';
3
- import { ProtocolDetector, TlsDetector } from '../../detection/index.js';
4
- import type { SmartProxy } from './smart-proxy.js';
5
-
6
- /**
7
- * Interface for connection information used for SNI extraction
8
- */
9
- interface IConnectionInfo {
10
- sourceIp: string;
11
- sourcePort: number;
12
- destIp: string;
13
- destPort: number;
14
- }
15
-
16
- /**
17
- * Manages TLS-related operations including SNI extraction and validation
18
- */
19
- export class TlsManager {
20
- constructor(private smartProxy: SmartProxy) {}
21
-
22
- /**
23
- * Check if a data chunk appears to be a TLS handshake
24
- */
25
- public isTlsHandshake(chunk: Buffer): boolean {
26
- return SniHandler.isTlsHandshake(chunk);
27
- }
28
-
29
- /**
30
- * Check if a data chunk appears to be a TLS ClientHello
31
- */
32
- public isClientHello(chunk: Buffer): boolean {
33
- return SniHandler.isClientHello(chunk);
34
- }
35
-
36
- /**
37
- * Extract Server Name Indication (SNI) from TLS handshake
38
- */
39
- public extractSNI(
40
- chunk: Buffer,
41
- connInfo: IConnectionInfo,
42
- previousDomain?: string
43
- ): string | undefined {
44
- // Use the SniHandler to process the TLS packet
45
- return SniHandler.processTlsPacket(
46
- chunk,
47
- connInfo,
48
- this.smartProxy.settings.enableTlsDebugLogging || false,
49
- previousDomain
50
- );
51
- }
52
-
53
- /**
54
- * Check for SNI mismatch during renegotiation
55
- */
56
- public checkRenegotiationSNI(
57
- chunk: Buffer,
58
- connInfo: IConnectionInfo,
59
- expectedDomain: string,
60
- connectionId: string
61
- ): { hasMismatch: boolean; extractedSNI?: string } {
62
- // Only process if this looks like a TLS ClientHello
63
- if (!this.isClientHello(chunk)) {
64
- return { hasMismatch: false };
65
- }
66
-
67
- try {
68
- // Extract SNI with renegotiation support
69
- const newSNI = SniHandler.extractSNIWithResumptionSupport(
70
- chunk,
71
- connInfo,
72
- this.smartProxy.settings.enableTlsDebugLogging || false
73
- );
74
-
75
- // Skip if no SNI was found
76
- if (!newSNI) return { hasMismatch: false };
77
-
78
- // Check for SNI mismatch
79
- if (newSNI !== expectedDomain) {
80
- if (this.smartProxy.settings.enableTlsDebugLogging) {
81
- console.log(
82
- `[${connectionId}] Renegotiation with different SNI: ${expectedDomain} -> ${newSNI}. ` +
83
- `Terminating connection - SNI domain switching is not allowed.`
84
- );
85
- }
86
- return { hasMismatch: true, extractedSNI: newSNI };
87
- } else if (this.smartProxy.settings.enableTlsDebugLogging) {
88
- console.log(
89
- `[${connectionId}] Renegotiation detected with same SNI: ${newSNI}. Allowing.`
90
- );
91
- }
92
- } catch (err) {
93
- console.log(
94
- `[${connectionId}] Error processing ClientHello: ${err}. Allowing connection to continue.`
95
- );
96
- }
97
-
98
- return { hasMismatch: false };
99
- }
100
-
101
- /**
102
- * Create a renegotiation handler function for a connection
103
- */
104
- public createRenegotiationHandler(
105
- connectionId: string,
106
- lockedDomain: string,
107
- connInfo: IConnectionInfo,
108
- onMismatch: (connectionId: string, reason: string) => void
109
- ): (chunk: Buffer) => void {
110
- return (chunk: Buffer) => {
111
- const result = this.checkRenegotiationSNI(chunk, connInfo, lockedDomain, connectionId);
112
- if (result.hasMismatch) {
113
- onMismatch(connectionId, 'sni_mismatch');
114
- }
115
- };
116
- }
117
-
118
- /**
119
- * Analyze TLS connection for browser fingerprinting
120
- * This helps identify browser vs non-browser connections
121
- */
122
- public analyzeClientHello(chunk: Buffer): {
123
- isBrowserConnection: boolean;
124
- isRenewal: boolean;
125
- hasSNI: boolean;
126
- } {
127
- // Default result
128
- const result = {
129
- isBrowserConnection: false,
130
- isRenewal: false,
131
- hasSNI: false
132
- };
133
-
134
- try {
135
- // Check if it's a ClientHello
136
- if (!this.isClientHello(chunk)) {
137
- return result;
138
- }
139
-
140
- // Check for session resumption
141
- const resumptionInfo = SniHandler.hasSessionResumption(
142
- chunk,
143
- this.smartProxy.settings.enableTlsDebugLogging || false
144
- );
145
-
146
- // Extract SNI
147
- const sni = SniHandler.extractSNI(
148
- chunk,
149
- this.smartProxy.settings.enableTlsDebugLogging || false
150
- );
151
-
152
- // Update result
153
- result.isRenewal = resumptionInfo.isResumption;
154
- result.hasSNI = !!sni;
155
-
156
- // Browsers typically:
157
- // 1. Send SNI extension
158
- // 2. Have a variety of extensions (ALPN, etc.)
159
- // 3. Use standard cipher suites
160
- // ...more complex heuristics could be implemented here
161
-
162
- // Simple heuristic: presence of SNI suggests browser
163
- result.isBrowserConnection = !!sni;
164
-
165
- return result;
166
- } catch (err) {
167
- console.log(`Error analyzing ClientHello: ${err}`);
168
- return result;
169
- }
170
- }
171
- }