@push.rocks/smartproxy 21.1.6 → 22.4.2
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 +89 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/core/utils/shared-security-manager.d.ts +17 -0
- package/dist_ts/core/utils/shared-security-manager.js +66 -1
- package/dist_ts/proxies/http-proxy/default-certificates.d.ts +54 -0
- package/dist_ts/proxies/http-proxy/default-certificates.js +127 -0
- package/dist_ts/proxies/http-proxy/http-proxy.d.ts +1 -1
- package/dist_ts/proxies/http-proxy/http-proxy.js +9 -14
- package/dist_ts/proxies/http-proxy/index.d.ts +5 -1
- package/dist_ts/proxies/http-proxy/index.js +6 -2
- package/dist_ts/proxies/http-proxy/security-manager.d.ts +4 -12
- package/dist_ts/proxies/http-proxy/security-manager.js +66 -99
- package/dist_ts/proxies/nftables-proxy/index.d.ts +1 -0
- package/dist_ts/proxies/nftables-proxy/index.js +2 -1
- package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +4 -26
- package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +84 -236
- package/dist_ts/proxies/nftables-proxy/utils/index.d.ts +9 -0
- package/dist_ts/proxies/nftables-proxy/utils/index.js +12 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.d.ts +66 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.js +131 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.d.ts +39 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.js +112 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.d.ts +59 -0
- package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.js +130 -0
- package/dist_ts/proxies/smart-proxy/certificate-manager.js +4 -3
- package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +13 -2
- package/dist_ts/proxies/smart-proxy/connection-manager.js +16 -6
- package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +35 -10
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +0 -1
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +17 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +72 -9
- package/dist_ts/proxies/smart-proxy/security-manager.d.ts +14 -12
- package/dist_ts/proxies/smart-proxy/security-manager.js +80 -74
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +1 -2
- package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +2 -9
- package/dist_ts/proxies/smart-proxy/tls-manager.js +3 -26
- package/dist_ts/proxies/smart-proxy/utils/index.d.ts +1 -1
- package/dist_ts/proxies/smart-proxy/utils/index.js +3 -4
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/api-helpers.d.ts +49 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/api-helpers.js +108 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/dynamic-helpers.d.ts +57 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/dynamic-helpers.js +89 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/http-helpers.d.ts +17 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/http-helpers.js +32 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/https-helpers.d.ts +68 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/https-helpers.js +117 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/index.d.ts +17 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/index.js +27 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/load-balancer-helpers.d.ts +63 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/load-balancer-helpers.js +105 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/nftables-helpers.d.ts +83 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/nftables-helpers.js +126 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/security-helpers.d.ts +47 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/security-helpers.js +66 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.d.ts +70 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.js +287 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/websocket-helpers.d.ts +46 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers/websocket-helpers.js +67 -0
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +4 -457
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +6 -950
- package/dist_ts/proxies/smart-proxy/utils/route-utils.js +2 -2
- package/dist_ts/proxies/smart-proxy/utils/route-validator.d.ts +67 -1
- package/dist_ts/proxies/smart-proxy/utils/route-validator.js +266 -6
- package/npmextra.json +12 -6
- package/package.json +34 -24
- package/readme.hints.md +184 -1
- package/readme.md +235 -172
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/utils/shared-security-manager.ts +98 -13
- package/ts/proxies/http-proxy/default-certificates.ts +150 -0
- package/ts/proxies/http-proxy/http-proxy.ts +9 -15
- package/ts/proxies/http-proxy/index.ts +6 -1
- package/ts/proxies/http-proxy/security-manager.ts +141 -161
- package/ts/proxies/nftables-proxy/index.ts +1 -0
- package/ts/proxies/nftables-proxy/nftables-proxy.ts +116 -290
- package/ts/proxies/nftables-proxy/utils/index.ts +38 -0
- package/ts/proxies/nftables-proxy/utils/nft-command-executor.ts +162 -0
- package/ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.ts +125 -0
- package/ts/proxies/nftables-proxy/utils/nft-rule-validator.ts +156 -0
- package/ts/proxies/smart-proxy/certificate-manager.ts +3 -2
- package/ts/proxies/smart-proxy/connection-manager.ts +21 -8
- package/ts/proxies/smart-proxy/http-proxy-bridge.ts +39 -13
- package/ts/proxies/smart-proxy/models/interfaces.ts +0 -1
- package/ts/proxies/smart-proxy/route-connection-handler.ts +88 -16
- package/ts/proxies/smart-proxy/security-manager.ts +98 -86
- package/ts/proxies/smart-proxy/smart-proxy.ts +0 -2
- package/ts/proxies/smart-proxy/tls-manager.ts +1 -37
- package/ts/proxies/smart-proxy/utils/index.ts +3 -5
- package/ts/proxies/smart-proxy/utils/route-helpers/api-helpers.ts +144 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/dynamic-helpers.ts +124 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/http-helpers.ts +40 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/https-helpers.ts +163 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/index.ts +62 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/load-balancer-helpers.ts +154 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/nftables-helpers.ts +202 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/security-helpers.ts +96 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/socket-handlers.ts +337 -0
- package/ts/proxies/smart-proxy/utils/route-helpers/websocket-helpers.ts +98 -0
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +5 -1302
- package/ts/proxies/smart-proxy/utils/route-utils.ts +1 -1
- package/ts/proxies/smart-proxy/utils/route-validator.ts +289 -7
- package/ts/proxies/http-proxy/certificate-manager.ts +0 -244
- package/ts/proxies/smart-proxy/utils/route-validators.ts +0 -283
|
@@ -148,31 +148,66 @@ export class SharedSecurityManager {
|
|
|
148
148
|
|
|
149
149
|
/**
|
|
150
150
|
* Validate IP against rate limits and connection limits
|
|
151
|
-
*
|
|
151
|
+
*
|
|
152
152
|
* @param ip - The IP address to validate
|
|
153
153
|
* @returns Result with allowed status and reason if blocked
|
|
154
154
|
*/
|
|
155
155
|
public validateIP(ip: string): IIpValidationResult {
|
|
156
156
|
// Check connection count limit
|
|
157
157
|
const connectionResult = checkMaxConnections(
|
|
158
|
-
ip,
|
|
159
|
-
this.connectionsByIP,
|
|
158
|
+
ip,
|
|
159
|
+
this.connectionsByIP,
|
|
160
160
|
this.maxConnectionsPerIP
|
|
161
161
|
);
|
|
162
162
|
if (!connectionResult.allowed) {
|
|
163
163
|
return connectionResult;
|
|
164
164
|
}
|
|
165
|
-
|
|
165
|
+
|
|
166
166
|
// Check connection rate limit
|
|
167
167
|
const rateResult = checkConnectionRate(
|
|
168
|
-
ip,
|
|
169
|
-
this.connectionsByIP,
|
|
168
|
+
ip,
|
|
169
|
+
this.connectionsByIP,
|
|
170
170
|
this.connectionRateLimitPerMinute
|
|
171
171
|
);
|
|
172
172
|
if (!rateResult.allowed) {
|
|
173
173
|
return rateResult;
|
|
174
174
|
}
|
|
175
|
-
|
|
175
|
+
|
|
176
|
+
return { allowed: true };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Atomically validate an IP and track the connection if allowed.
|
|
181
|
+
* This prevents race conditions where concurrent connections could bypass per-IP limits.
|
|
182
|
+
*
|
|
183
|
+
* @param ip - The IP address to validate
|
|
184
|
+
* @param connectionId - The connection ID to track if validation passes
|
|
185
|
+
* @returns Object with validation result and reason
|
|
186
|
+
*/
|
|
187
|
+
public validateAndTrackIP(ip: string, connectionId: string): IIpValidationResult {
|
|
188
|
+
// Check connection count limit BEFORE tracking
|
|
189
|
+
const connectionResult = checkMaxConnections(
|
|
190
|
+
ip,
|
|
191
|
+
this.connectionsByIP,
|
|
192
|
+
this.maxConnectionsPerIP
|
|
193
|
+
);
|
|
194
|
+
if (!connectionResult.allowed) {
|
|
195
|
+
return connectionResult;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Check connection rate limit
|
|
199
|
+
const rateResult = checkConnectionRate(
|
|
200
|
+
ip,
|
|
201
|
+
this.connectionsByIP,
|
|
202
|
+
this.connectionRateLimitPerMinute
|
|
203
|
+
);
|
|
204
|
+
if (!rateResult.allowed) {
|
|
205
|
+
return rateResult;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Validation passed - immediately track to prevent race conditions
|
|
209
|
+
this.trackConnectionByIP(ip, connectionId);
|
|
210
|
+
|
|
176
211
|
return { allowed: true };
|
|
177
212
|
}
|
|
178
213
|
|
|
@@ -304,7 +339,7 @@ export class SharedSecurityManager {
|
|
|
304
339
|
|
|
305
340
|
/**
|
|
306
341
|
* Validate HTTP Basic Authentication
|
|
307
|
-
*
|
|
342
|
+
*
|
|
308
343
|
* @param route - The route to check
|
|
309
344
|
* @param authHeader - The Authorization header
|
|
310
345
|
* @returns Whether authentication is valid
|
|
@@ -314,26 +349,76 @@ export class SharedSecurityManager {
|
|
|
314
349
|
if (!route.security?.basicAuth?.enabled) {
|
|
315
350
|
return true;
|
|
316
351
|
}
|
|
317
|
-
|
|
352
|
+
|
|
318
353
|
// No auth header means auth failed
|
|
319
354
|
if (!authHeader) {
|
|
320
355
|
return false;
|
|
321
356
|
}
|
|
322
|
-
|
|
357
|
+
|
|
323
358
|
// Parse auth header
|
|
324
359
|
const credentials = parseBasicAuthHeader(authHeader);
|
|
325
360
|
if (!credentials) {
|
|
326
361
|
return false;
|
|
327
362
|
}
|
|
328
|
-
|
|
363
|
+
|
|
329
364
|
// Check credentials against configured users
|
|
330
365
|
const { username, password } = credentials;
|
|
331
366
|
const users = route.security.basicAuth.users;
|
|
332
|
-
|
|
333
|
-
return users.some(user =>
|
|
367
|
+
|
|
368
|
+
return users.some(user =>
|
|
334
369
|
user.username === username && user.password === password
|
|
335
370
|
);
|
|
336
371
|
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Verify a JWT token against route configuration
|
|
375
|
+
*
|
|
376
|
+
* @param route - The route to verify the token for
|
|
377
|
+
* @param token - The JWT token to verify
|
|
378
|
+
* @returns True if the token is valid, false otherwise
|
|
379
|
+
*/
|
|
380
|
+
public verifyJwtToken(route: IRouteConfig, token: string): boolean {
|
|
381
|
+
if (!route.security?.jwtAuth?.enabled) {
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
try {
|
|
386
|
+
const jwtAuth = route.security.jwtAuth;
|
|
387
|
+
|
|
388
|
+
// Verify structure (header.payload.signature)
|
|
389
|
+
const parts = token.split('.');
|
|
390
|
+
if (parts.length !== 3) {
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Decode payload
|
|
395
|
+
const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString());
|
|
396
|
+
|
|
397
|
+
// Check expiration
|
|
398
|
+
if (payload.exp && payload.exp < Math.floor(Date.now() / 1000)) {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Check issuer
|
|
403
|
+
if (jwtAuth.issuer && payload.iss !== jwtAuth.issuer) {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Check audience
|
|
408
|
+
if (jwtAuth.audience && payload.aud !== jwtAuth.audience) {
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Note: In a real implementation, you'd also verify the signature
|
|
413
|
+
// using the secret and algorithm specified in jwtAuth.
|
|
414
|
+
// This requires a proper JWT library for cryptographic verification.
|
|
415
|
+
|
|
416
|
+
return true;
|
|
417
|
+
} catch (err) {
|
|
418
|
+
this.logger?.error?.(`Error verifying JWT: ${err}`);
|
|
419
|
+
return false;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
337
422
|
|
|
338
423
|
/**
|
|
339
424
|
* Clean up caches to prevent memory leaks
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { AsyncFileSystem } from '../../core/utils/fs-utils.js';
|
|
6
|
+
import type { ILogger, ICertificateEntry } from './models/types.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Interface for default certificate data
|
|
10
|
+
*/
|
|
11
|
+
export interface IDefaultCertificates {
|
|
12
|
+
key: string;
|
|
13
|
+
cert: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Provides default SSL certificates for HttpProxy.
|
|
18
|
+
* This is a minimal replacement for the deprecated CertificateManager.
|
|
19
|
+
*
|
|
20
|
+
* For production certificate management, use SmartCertManager instead.
|
|
21
|
+
*/
|
|
22
|
+
export class DefaultCertificateProvider {
|
|
23
|
+
private defaultCertificates: IDefaultCertificates | null = null;
|
|
24
|
+
private certificateCache: Map<string, ICertificateEntry> = new Map();
|
|
25
|
+
private initialized = false;
|
|
26
|
+
|
|
27
|
+
constructor(private logger?: ILogger) {}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Load default certificates asynchronously (preferred)
|
|
31
|
+
*/
|
|
32
|
+
public async loadDefaultCertificatesAsync(): Promise<IDefaultCertificates> {
|
|
33
|
+
if (this.defaultCertificates) {
|
|
34
|
+
return this.defaultCertificates;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
38
|
+
const certPath = path.join(__dirname, '..', '..', '..', 'assets', 'certs');
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const [key, cert] = await Promise.all([
|
|
42
|
+
AsyncFileSystem.readFile(path.join(certPath, 'key.pem')),
|
|
43
|
+
AsyncFileSystem.readFile(path.join(certPath, 'cert.pem'))
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
this.defaultCertificates = { key, cert };
|
|
47
|
+
this.logger?.info?.('Loaded default certificates from filesystem');
|
|
48
|
+
this.initialized = true;
|
|
49
|
+
return this.defaultCertificates;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
this.logger?.warn?.(`Failed to load default certificates: ${error}`);
|
|
52
|
+
this.defaultCertificates = this.generateFallbackCertificate();
|
|
53
|
+
this.initialized = true;
|
|
54
|
+
return this.defaultCertificates;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Load default certificates synchronously (for backward compatibility)
|
|
60
|
+
* @deprecated Use loadDefaultCertificatesAsync instead
|
|
61
|
+
*/
|
|
62
|
+
public loadDefaultCertificatesSync(): IDefaultCertificates {
|
|
63
|
+
if (this.defaultCertificates) {
|
|
64
|
+
return this.defaultCertificates;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
68
|
+
const certPath = path.join(__dirname, '..', '..', '..', 'assets', 'certs');
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
this.defaultCertificates = {
|
|
72
|
+
key: fs.readFileSync(path.join(certPath, 'key.pem'), 'utf8'),
|
|
73
|
+
cert: fs.readFileSync(path.join(certPath, 'cert.pem'), 'utf8')
|
|
74
|
+
};
|
|
75
|
+
this.logger?.info?.('Loaded default certificates from filesystem (sync)');
|
|
76
|
+
} catch (error) {
|
|
77
|
+
this.logger?.warn?.(`Failed to load default certificates: ${error}`);
|
|
78
|
+
this.defaultCertificates = this.generateFallbackCertificate();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.initialized = true;
|
|
82
|
+
return this.defaultCertificates;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Gets the default certificates (loads synchronously if not already loaded)
|
|
87
|
+
*/
|
|
88
|
+
public getDefaultCertificates(): IDefaultCertificates {
|
|
89
|
+
if (!this.defaultCertificates) {
|
|
90
|
+
return this.loadDefaultCertificatesSync();
|
|
91
|
+
}
|
|
92
|
+
return this.defaultCertificates;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Updates a certificate in the cache
|
|
97
|
+
*/
|
|
98
|
+
public updateCertificate(domain: string, cert: string, key: string): void {
|
|
99
|
+
this.certificateCache.set(domain, {
|
|
100
|
+
cert,
|
|
101
|
+
key,
|
|
102
|
+
expires: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000) // 90 days
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
this.logger?.info?.(`Certificate updated for ${domain}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Gets a cached certificate
|
|
110
|
+
*/
|
|
111
|
+
public getCachedCertificate(domain: string): ICertificateEntry | null {
|
|
112
|
+
return this.certificateCache.get(domain) || null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Gets statistics for metrics
|
|
117
|
+
*/
|
|
118
|
+
public getStats(): { cachedCertificates: number; defaultCertEnabled: boolean } {
|
|
119
|
+
return {
|
|
120
|
+
cachedCertificates: this.certificateCache.size,
|
|
121
|
+
defaultCertEnabled: this.defaultCertificates !== null
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Generate a fallback self-signed certificate placeholder
|
|
127
|
+
* Note: This is just a placeholder - real apps should provide proper certificates
|
|
128
|
+
*/
|
|
129
|
+
private generateFallbackCertificate(): IDefaultCertificates {
|
|
130
|
+
this.logger?.warn?.('Using fallback self-signed certificate placeholder');
|
|
131
|
+
|
|
132
|
+
// Minimal self-signed certificate for fallback only
|
|
133
|
+
// In production, proper certificates should be provided via SmartCertManager
|
|
134
|
+
const selfSignedCert = `-----BEGIN CERTIFICATE-----
|
|
135
|
+
MIIBkTCB+wIJAKHHIgIIA0/cMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAYTAlVT
|
|
136
|
+
MB4XDTE0MDEwMTAwMDAwMFoXDTI0MDEwMTAwMDAwMFowDTELMAkGA1UEBhMCVVMw
|
|
137
|
+
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMRiH0VwnOH3jCV7c6JFZWYrvuqy
|
|
138
|
+
-----END CERTIFICATE-----`;
|
|
139
|
+
|
|
140
|
+
const selfSignedKey = `-----BEGIN PRIVATE KEY-----
|
|
141
|
+
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMRiH0VwnOH3jCV7
|
|
142
|
+
c6JFZWYrvuqyALCLXj0pcr1iqNdHjegNXnkl5zjdaUjq4edNOKl7M1AlFiYjG2xk
|
|
143
|
+
-----END PRIVATE KEY-----`;
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
key: selfSignedKey,
|
|
147
|
+
cert: selfSignedCert
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
import type { IRouteConfig } from '../smart-proxy/models/route-types.js';
|
|
11
11
|
import type { IRouteContext, IHttpRouteContext } from '../../core/models/route-context.js';
|
|
12
12
|
import { createBaseRouteContext } from '../../core/models/route-context.js';
|
|
13
|
-
import {
|
|
13
|
+
import { DefaultCertificateProvider } from './default-certificates.js';
|
|
14
14
|
import { ConnectionPool } from './connection-pool.js';
|
|
15
15
|
import { RequestHandler, type IMetricsTracker } from './request-handler.js';
|
|
16
16
|
import { WebSocketHandler } from './websocket-handler.js';
|
|
@@ -38,7 +38,7 @@ export class HttpProxy implements IMetricsTracker {
|
|
|
38
38
|
public httpsServer: plugins.http2.Http2SecureServer;
|
|
39
39
|
|
|
40
40
|
// Core components
|
|
41
|
-
private
|
|
41
|
+
private defaultCertProvider: DefaultCertificateProvider;
|
|
42
42
|
private connectionPool: ConnectionPool;
|
|
43
43
|
private requestHandler: RequestHandler;
|
|
44
44
|
private webSocketHandler: WebSocketHandler;
|
|
@@ -126,7 +126,7 @@ export class HttpProxy implements IMetricsTracker {
|
|
|
126
126
|
);
|
|
127
127
|
|
|
128
128
|
// Initialize other components
|
|
129
|
-
this.
|
|
129
|
+
this.defaultCertProvider = new DefaultCertificateProvider(this.logger);
|
|
130
130
|
this.connectionPool = new ConnectionPool(this.options);
|
|
131
131
|
this.requestHandler = new RequestHandler(
|
|
132
132
|
this.options,
|
|
@@ -237,10 +237,11 @@ export class HttpProxy implements IMetricsTracker {
|
|
|
237
237
|
this.startTime = Date.now();
|
|
238
238
|
|
|
239
239
|
// Create HTTP/2 server with HTTP/1 fallback
|
|
240
|
+
const defaultCerts = this.defaultCertProvider.getDefaultCertificates();
|
|
240
241
|
this.httpsServer = plugins.http2.createSecureServer(
|
|
241
242
|
{
|
|
242
|
-
key:
|
|
243
|
-
cert:
|
|
243
|
+
key: defaultCerts.key,
|
|
244
|
+
cert: defaultCerts.cert,
|
|
244
245
|
allowHTTP1: true,
|
|
245
246
|
ALPNProtocols: ['h2', 'http/1.1']
|
|
246
247
|
}
|
|
@@ -258,9 +259,6 @@ export class HttpProxy implements IMetricsTracker {
|
|
|
258
259
|
this.requestHandler.handleRequest(req, res);
|
|
259
260
|
});
|
|
260
261
|
|
|
261
|
-
// Share server with certificate manager for dynamic contexts
|
|
262
|
-
// Cast to https.Server as Http2SecureServer is compatible for certificate contexts
|
|
263
|
-
this.certificateManager.setHttpsServer(this.httpsServer as any);
|
|
264
262
|
// Setup WebSocket support on HTTP/1 fallback
|
|
265
263
|
this.webSocketHandler.initialize(this.httpsServer as any);
|
|
266
264
|
// Start metrics logging
|
|
@@ -304,7 +302,7 @@ export class HttpProxy implements IMetricsTracker {
|
|
|
304
302
|
// For SmartProxy connections, wait for CLIENT_IP header
|
|
305
303
|
if (isFromSmartProxy) {
|
|
306
304
|
const MAX_PREFACE = 256; // bytes - prevent DoS
|
|
307
|
-
const HEADER_TIMEOUT_MS =
|
|
305
|
+
const HEADER_TIMEOUT_MS = 2000; // timeout for header parsing (increased for slow networks)
|
|
308
306
|
let headerTimer: NodeJS.Timeout | undefined;
|
|
309
307
|
let buffered = Buffer.alloc(0);
|
|
310
308
|
|
|
@@ -506,10 +504,6 @@ export class HttpProxy implements IMetricsTracker {
|
|
|
506
504
|
this.requestHandler.securityManager.setRoutes(routes);
|
|
507
505
|
this.routes = routes;
|
|
508
506
|
|
|
509
|
-
// Directly update the certificate manager with the new routes
|
|
510
|
-
// This will extract domains and handle certificate provisioning
|
|
511
|
-
this.certificateManager.updateRoutes(routes);
|
|
512
|
-
|
|
513
507
|
// Collect all domains and certificates for configuration
|
|
514
508
|
const currentHostnames = new Set<string>();
|
|
515
509
|
const certificateUpdates = new Map<string, { cert: string, key: string }>();
|
|
@@ -548,7 +542,7 @@ export class HttpProxy implements IMetricsTracker {
|
|
|
548
542
|
// Update certificate cache with any static certificates
|
|
549
543
|
for (const [domain, certData] of certificateUpdates.entries()) {
|
|
550
544
|
try {
|
|
551
|
-
this.
|
|
545
|
+
this.defaultCertProvider.updateCertificate(
|
|
552
546
|
domain,
|
|
553
547
|
certData.cert,
|
|
554
548
|
certData.key
|
|
@@ -663,7 +657,7 @@ export class HttpProxy implements IMetricsTracker {
|
|
|
663
657
|
expiryDate?: Date
|
|
664
658
|
): void {
|
|
665
659
|
this.logger.info(`Updating certificate for ${domain}`);
|
|
666
|
-
this.
|
|
660
|
+
this.defaultCertProvider.updateCertificate(domain, certificate, privateKey);
|
|
667
661
|
}
|
|
668
662
|
|
|
669
663
|
/**
|
|
@@ -6,8 +6,13 @@ export * from './models/index.js';
|
|
|
6
6
|
|
|
7
7
|
// Export HttpProxy and supporting classes
|
|
8
8
|
export { HttpProxy } from './http-proxy.js';
|
|
9
|
-
export {
|
|
9
|
+
export { DefaultCertificateProvider } from './default-certificates.js';
|
|
10
10
|
export { ConnectionPool } from './connection-pool.js';
|
|
11
11
|
export { RequestHandler } from './request-handler.js';
|
|
12
12
|
export type { IMetricsTracker, MetricsTracker } from './request-handler.js';
|
|
13
13
|
export { WebSocketHandler } from './websocket-handler.js';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @deprecated Use DefaultCertificateProvider instead. This alias is for backward compatibility.
|
|
17
|
+
*/
|
|
18
|
+
export { DefaultCertificateProvider as CertificateManager } from './default-certificates.js';
|