@push.rocks/smartproxy 21.1.7 → 22.6.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 +109 -0
- package/dist_rust/rustproxy +0 -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/index.d.ts +1 -5
- package/dist_ts/index.js +3 -9
- package/dist_ts/protocols/common/fragment-handler.js +5 -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/index.d.ts +1 -5
- package/dist_ts/proxies/index.js +2 -6
- 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/index.d.ts +5 -10
- package/dist_ts/proxies/smart-proxy/index.js +7 -13
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -3
- 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/route-preprocessor.d.ts +37 -0
- package/dist_ts/proxies/smart-proxy/route-preprocessor.js +103 -0
- package/dist_ts/proxies/smart-proxy/rust-binary-locator.d.ts +23 -0
- package/dist_ts/proxies/smart-proxy/rust-binary-locator.js +104 -0
- package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.d.ts +74 -0
- package/dist_ts/proxies/smart-proxy/rust-metrics-adapter.js +146 -0
- package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.d.ts +49 -0
- package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.js +259 -0
- 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.d.ts +39 -157
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +224 -622
- package/dist_ts/proxies/smart-proxy/socket-handler-server.d.ts +45 -0
- package/dist_ts/proxies/smart-proxy/socket-handler-server.js +253 -0
- 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 +251 -3
- package/dist_ts/routing/index.d.ts +1 -1
- package/dist_ts/routing/index.js +3 -3
- package/dist_ts/routing/models/http-types.d.ts +119 -4
- package/dist_ts/routing/models/http-types.js +93 -5
- package/npmextra.json +12 -6
- package/package.json +34 -24
- package/readme.hints.md +184 -1
- package/readme.md +580 -266
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/utils/shared-security-manager.ts +98 -13
- package/ts/index.ts +4 -12
- package/ts/protocols/common/fragment-handler.ts +4 -0
- package/ts/proxies/index.ts +1 -9
- 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/index.ts +6 -13
- package/ts/proxies/smart-proxy/models/interfaces.ts +6 -5
- package/ts/proxies/smart-proxy/route-preprocessor.ts +122 -0
- package/ts/proxies/smart-proxy/rust-binary-locator.ts +112 -0
- package/ts/proxies/smart-proxy/rust-metrics-adapter.ts +161 -0
- package/ts/proxies/smart-proxy/rust-proxy-bridge.ts +310 -0
- package/ts/proxies/smart-proxy/smart-proxy.ts +282 -800
- package/ts/proxies/smart-proxy/socket-handler-server.ts +279 -0
- 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 +274 -4
- package/ts/routing/index.ts +2 -2
- package/ts/routing/models/http-types.ts +147 -4
- package/ts/proxies/http-proxy/certificate-manager.ts +0 -244
- package/ts/proxies/http-proxy/connection-pool.ts +0 -228
- package/ts/proxies/http-proxy/context-creator.ts +0 -145
- package/ts/proxies/http-proxy/function-cache.ts +0 -279
- package/ts/proxies/http-proxy/handlers/index.ts +0 -5
- package/ts/proxies/http-proxy/http-proxy.ts +0 -675
- package/ts/proxies/http-proxy/http-request-handler.ts +0 -331
- package/ts/proxies/http-proxy/http2-request-handler.ts +0 -255
- package/ts/proxies/http-proxy/index.ts +0 -13
- package/ts/proxies/http-proxy/models/http-types.ts +0 -148
- package/ts/proxies/http-proxy/models/index.ts +0 -5
- package/ts/proxies/http-proxy/models/types.ts +0 -125
- package/ts/proxies/http-proxy/request-handler.ts +0 -878
- package/ts/proxies/http-proxy/security-manager.ts +0 -433
- package/ts/proxies/http-proxy/websocket-handler.ts +0 -581
- package/ts/proxies/smart-proxy/acme-state-manager.ts +0 -112
- package/ts/proxies/smart-proxy/cert-store.ts +0 -92
- package/ts/proxies/smart-proxy/certificate-manager.ts +0 -894
- package/ts/proxies/smart-proxy/connection-manager.ts +0 -796
- package/ts/proxies/smart-proxy/http-proxy-bridge.ts +0 -187
- package/ts/proxies/smart-proxy/metrics-collector.ts +0 -453
- package/ts/proxies/smart-proxy/nftables-manager.ts +0 -271
- package/ts/proxies/smart-proxy/port-manager.ts +0 -358
- package/ts/proxies/smart-proxy/route-connection-handler.ts +0 -1640
- package/ts/proxies/smart-proxy/route-orchestrator.ts +0 -297
- package/ts/proxies/smart-proxy/security-manager.ts +0 -257
- package/ts/proxies/smart-proxy/throughput-tracker.ts +0 -138
- package/ts/proxies/smart-proxy/timeout-manager.ts +0 -196
- package/ts/proxies/smart-proxy/tls-manager.ts +0 -207
- package/ts/proxies/smart-proxy/utils/route-validators.ts +0 -283
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SmartProxy } from './smart-proxy.js';
|
|
2
2
|
/**
|
|
3
3
|
* Handles security aspects like IP tracking, rate limiting, and authorization
|
|
4
|
+
* for SmartProxy. This is a lightweight wrapper that uses shared utilities.
|
|
4
5
|
*/
|
|
5
6
|
export declare class SecurityManager {
|
|
6
7
|
private smartProxy;
|
|
@@ -9,7 +10,7 @@ export declare class SecurityManager {
|
|
|
9
10
|
private cleanupInterval;
|
|
10
11
|
constructor(smartProxy: SmartProxy);
|
|
11
12
|
/**
|
|
12
|
-
* Get connections count by IP
|
|
13
|
+
* Get connections count by IP (checks normalized variants)
|
|
13
14
|
*/
|
|
14
15
|
getConnectionCountByIP(ip: string): number;
|
|
15
16
|
/**
|
|
@@ -38,17 +39,6 @@ export declare class SecurityManager {
|
|
|
38
39
|
* @returns true if IP is authorized, false if blocked
|
|
39
40
|
*/
|
|
40
41
|
isIPAuthorized(ip: string, allowedIPs: string[], blockedIPs?: string[]): boolean;
|
|
41
|
-
/**
|
|
42
|
-
* Check if the IP matches any of the glob patterns from security configuration
|
|
43
|
-
*
|
|
44
|
-
* This method checks IP addresses against glob patterns and handles IPv4/IPv6 normalization.
|
|
45
|
-
* It's used to implement IP filtering based on the route.security configuration.
|
|
46
|
-
*
|
|
47
|
-
* @param ip - The IP address to check
|
|
48
|
-
* @param patterns - Array of glob patterns from security.ipAllowList or ipBlockList
|
|
49
|
-
* @returns true if IP matches any pattern, false otherwise
|
|
50
|
-
*/
|
|
51
|
-
private isGlobIPMatch;
|
|
52
42
|
/**
|
|
53
43
|
* Check if IP should be allowed considering connection rate and max connections
|
|
54
44
|
* @returns Object with result and reason
|
|
@@ -57,6 +47,18 @@ export declare class SecurityManager {
|
|
|
57
47
|
allowed: boolean;
|
|
58
48
|
reason?: string;
|
|
59
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Atomically validate an IP and track the connection if allowed.
|
|
52
|
+
* This prevents race conditions where concurrent connections could bypass per-IP limits.
|
|
53
|
+
*
|
|
54
|
+
* @param ip - The IP address to validate
|
|
55
|
+
* @param connectionId - The connection ID to track if validation passes
|
|
56
|
+
* @returns Object with validation result and reason
|
|
57
|
+
*/
|
|
58
|
+
validateAndTrackIP(ip: string, connectionId: string): {
|
|
59
|
+
allowed: boolean;
|
|
60
|
+
reason?: string;
|
|
61
|
+
};
|
|
60
62
|
/**
|
|
61
63
|
* Clears all IP tracking data (for shutdown)
|
|
62
64
|
*/
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
|
-
import { logger } from '../../core/utils/logger.js';
|
|
3
2
|
import { connectionLogDeduplicator } from '../../core/utils/log-deduplicator.js';
|
|
3
|
+
import { isIPAuthorized, normalizeIP } from '../../core/utils/security-utils.js';
|
|
4
4
|
/**
|
|
5
5
|
* Handles security aspects like IP tracking, rate limiting, and authorization
|
|
6
|
+
* for SmartProxy. This is a lightweight wrapper that uses shared utilities.
|
|
6
7
|
*/
|
|
7
8
|
export class SecurityManager {
|
|
8
9
|
constructor(smartProxy) {
|
|
@@ -14,10 +15,18 @@ export class SecurityManager {
|
|
|
14
15
|
this.startPeriodicCleanup();
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
17
|
-
* Get connections count by IP
|
|
18
|
+
* Get connections count by IP (checks normalized variants)
|
|
18
19
|
*/
|
|
19
20
|
getConnectionCountByIP(ip) {
|
|
20
|
-
|
|
21
|
+
// Check all normalized variants of the IP
|
|
22
|
+
const variants = normalizeIP(ip);
|
|
23
|
+
for (const variant of variants) {
|
|
24
|
+
const connections = this.connectionsByIP.get(variant);
|
|
25
|
+
if (connections) {
|
|
26
|
+
return connections.size;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return 0;
|
|
21
30
|
}
|
|
22
31
|
/**
|
|
23
32
|
* Check and update connection rate for an IP
|
|
@@ -26,14 +35,24 @@ export class SecurityManager {
|
|
|
26
35
|
checkConnectionRate(ip) {
|
|
27
36
|
const now = Date.now();
|
|
28
37
|
const minute = 60 * 1000;
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
// Find existing rate tracking (check normalized variants)
|
|
39
|
+
const variants = normalizeIP(ip);
|
|
40
|
+
let existingKey = null;
|
|
41
|
+
for (const variant of variants) {
|
|
42
|
+
if (this.connectionRateByIP.has(variant)) {
|
|
43
|
+
existingKey = variant;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const key = existingKey || ip;
|
|
48
|
+
if (!this.connectionRateByIP.has(key)) {
|
|
49
|
+
this.connectionRateByIP.set(key, [now]);
|
|
31
50
|
return true;
|
|
32
51
|
}
|
|
33
52
|
// Get timestamps and filter out entries older than 1 minute
|
|
34
|
-
const timestamps = this.connectionRateByIP.get(
|
|
53
|
+
const timestamps = this.connectionRateByIP.get(key).filter((time) => now - time < minute);
|
|
35
54
|
timestamps.push(now);
|
|
36
|
-
this.connectionRateByIP.set(
|
|
55
|
+
this.connectionRateByIP.set(key, timestamps);
|
|
37
56
|
// Check if rate exceeds limit
|
|
38
57
|
return timestamps.length <= this.smartProxy.settings.connectionRateLimitPerMinute;
|
|
39
58
|
}
|
|
@@ -41,20 +60,35 @@ export class SecurityManager {
|
|
|
41
60
|
* Track connection by IP
|
|
42
61
|
*/
|
|
43
62
|
trackConnectionByIP(ip, connectionId) {
|
|
44
|
-
if
|
|
45
|
-
|
|
63
|
+
// Check if any variant already exists
|
|
64
|
+
const variants = normalizeIP(ip);
|
|
65
|
+
let existingKey = null;
|
|
66
|
+
for (const variant of variants) {
|
|
67
|
+
if (this.connectionsByIP.has(variant)) {
|
|
68
|
+
existingKey = variant;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const key = existingKey || ip;
|
|
73
|
+
if (!this.connectionsByIP.has(key)) {
|
|
74
|
+
this.connectionsByIP.set(key, new Set());
|
|
46
75
|
}
|
|
47
|
-
this.connectionsByIP.get(
|
|
76
|
+
this.connectionsByIP.get(key).add(connectionId);
|
|
48
77
|
}
|
|
49
78
|
/**
|
|
50
79
|
* Remove connection tracking for an IP
|
|
51
80
|
*/
|
|
52
81
|
removeConnectionByIP(ip, connectionId) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (
|
|
57
|
-
this.connectionsByIP.
|
|
82
|
+
// Check all variants to find where the connection is tracked
|
|
83
|
+
const variants = normalizeIP(ip);
|
|
84
|
+
for (const variant of variants) {
|
|
85
|
+
if (this.connectionsByIP.has(variant)) {
|
|
86
|
+
const connections = this.connectionsByIP.get(variant);
|
|
87
|
+
connections.delete(connectionId);
|
|
88
|
+
if (connections.size === 0) {
|
|
89
|
+
this.connectionsByIP.delete(variant);
|
|
90
|
+
}
|
|
91
|
+
break;
|
|
58
92
|
}
|
|
59
93
|
}
|
|
60
94
|
}
|
|
@@ -71,64 +105,7 @@ export class SecurityManager {
|
|
|
71
105
|
* @returns true if IP is authorized, false if blocked
|
|
72
106
|
*/
|
|
73
107
|
isIPAuthorized(ip, allowedIPs, blockedIPs = []) {
|
|
74
|
-
|
|
75
|
-
if (!ip || (allowedIPs.length === 0 && blockedIPs.length === 0)) {
|
|
76
|
-
return true;
|
|
77
|
-
}
|
|
78
|
-
// First check if IP is blocked - blocked IPs take precedence
|
|
79
|
-
if (blockedIPs.length > 0 && this.isGlobIPMatch(ip, blockedIPs)) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
// Then check if IP is allowed
|
|
83
|
-
return this.isGlobIPMatch(ip, allowedIPs);
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Check if the IP matches any of the glob patterns from security configuration
|
|
87
|
-
*
|
|
88
|
-
* This method checks IP addresses against glob patterns and handles IPv4/IPv6 normalization.
|
|
89
|
-
* It's used to implement IP filtering based on the route.security configuration.
|
|
90
|
-
*
|
|
91
|
-
* @param ip - The IP address to check
|
|
92
|
-
* @param patterns - Array of glob patterns from security.ipAllowList or ipBlockList
|
|
93
|
-
* @returns true if IP matches any pattern, false otherwise
|
|
94
|
-
*/
|
|
95
|
-
isGlobIPMatch(ip, patterns) {
|
|
96
|
-
if (!ip || !patterns || patterns.length === 0)
|
|
97
|
-
return false;
|
|
98
|
-
// Handle IPv4/IPv6 normalization for proper matching
|
|
99
|
-
const normalizeIP = (ip) => {
|
|
100
|
-
if (!ip)
|
|
101
|
-
return [];
|
|
102
|
-
// Handle IPv4-mapped IPv6 addresses (::ffff:127.0.0.1)
|
|
103
|
-
if (ip.startsWith('::ffff:')) {
|
|
104
|
-
const ipv4 = ip.slice(7);
|
|
105
|
-
return [ip, ipv4];
|
|
106
|
-
}
|
|
107
|
-
// Handle IPv4 addresses by also checking IPv4-mapped form
|
|
108
|
-
if (/^\d{1,3}(\.\d{1,3}){3}$/.test(ip)) {
|
|
109
|
-
return [ip, `::ffff:${ip}`];
|
|
110
|
-
}
|
|
111
|
-
return [ip];
|
|
112
|
-
};
|
|
113
|
-
// Normalize the IP being checked
|
|
114
|
-
const normalizedIPVariants = normalizeIP(ip);
|
|
115
|
-
if (normalizedIPVariants.length === 0)
|
|
116
|
-
return false;
|
|
117
|
-
// Expand shorthand patterns and normalize IPs for consistent comparison
|
|
118
|
-
const expandShorthand = (pattern) => {
|
|
119
|
-
// Expand shorthand IP patterns like '192.168.*' to '192.168.*.*'
|
|
120
|
-
if (pattern.includes('*') && !pattern.includes(':')) {
|
|
121
|
-
const parts = pattern.split('.');
|
|
122
|
-
while (parts.length < 4) {
|
|
123
|
-
parts.push('*');
|
|
124
|
-
}
|
|
125
|
-
return parts.join('.');
|
|
126
|
-
}
|
|
127
|
-
return pattern;
|
|
128
|
-
};
|
|
129
|
-
const expandedPatterns = patterns.map(expandShorthand).flatMap(normalizeIP);
|
|
130
|
-
// Check for any match between normalized IP variants and patterns
|
|
131
|
-
return normalizedIPVariants.some((ipVariant) => expandedPatterns.some((pattern) => plugins.minimatch(ipVariant, pattern)));
|
|
108
|
+
return isIPAuthorized(ip, allowedIPs, blockedIPs);
|
|
132
109
|
}
|
|
133
110
|
/**
|
|
134
111
|
* Check if IP should be allowed considering connection rate and max connections
|
|
@@ -153,6 +130,35 @@ export class SecurityManager {
|
|
|
153
130
|
}
|
|
154
131
|
return { allowed: true };
|
|
155
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Atomically validate an IP and track the connection if allowed.
|
|
135
|
+
* This prevents race conditions where concurrent connections could bypass per-IP limits.
|
|
136
|
+
*
|
|
137
|
+
* @param ip - The IP address to validate
|
|
138
|
+
* @param connectionId - The connection ID to track if validation passes
|
|
139
|
+
* @returns Object with validation result and reason
|
|
140
|
+
*/
|
|
141
|
+
validateAndTrackIP(ip, connectionId) {
|
|
142
|
+
// Check connection count limit BEFORE tracking
|
|
143
|
+
if (this.smartProxy.settings.maxConnectionsPerIP &&
|
|
144
|
+
this.getConnectionCountByIP(ip) >= this.smartProxy.settings.maxConnectionsPerIP) {
|
|
145
|
+
return {
|
|
146
|
+
allowed: false,
|
|
147
|
+
reason: `Maximum connections per IP (${this.smartProxy.settings.maxConnectionsPerIP}) exceeded`
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
// Check connection rate limit
|
|
151
|
+
if (this.smartProxy.settings.connectionRateLimitPerMinute &&
|
|
152
|
+
!this.checkConnectionRate(ip)) {
|
|
153
|
+
return {
|
|
154
|
+
allowed: false,
|
|
155
|
+
reason: `Connection rate limit (${this.smartProxy.settings.connectionRateLimitPerMinute}/min) exceeded`
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
// Validation passed - immediately track to prevent race conditions
|
|
159
|
+
this.trackConnectionByIP(ip, connectionId);
|
|
160
|
+
return { allowed: true };
|
|
161
|
+
}
|
|
156
162
|
/**
|
|
157
163
|
* Clears all IP tracking data (for shutdown)
|
|
158
164
|
*/
|
|
@@ -218,4 +224,4 @@ export class SecurityManager {
|
|
|
218
224
|
}
|
|
219
225
|
}
|
|
220
226
|
}
|
|
221
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
227
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHktbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Byb3hpZXMvc21hcnQtcHJveHkvc2VjdXJpdHktbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFFakY7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFLMUIsWUFBb0IsVUFBc0I7UUFBdEIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUpsQyxvQkFBZSxHQUE2QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ3RELHVCQUFrQixHQUEwQixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ3RELG9CQUFlLEdBQTBCLElBQUksQ0FBQztRQUdwRCwwQ0FBMEM7UUFDMUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksc0JBQXNCLENBQUMsRUFBVTtRQUN0QywwQ0FBMEM7UUFDMUMsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2pDLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFLENBQUM7WUFDL0IsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDdEQsSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDaEIsT0FBTyxXQUFXLENBQUMsSUFBSSxDQUFDO1lBQzFCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksbUJBQW1CLENBQUMsRUFBVTtRQUNuQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxF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
|
|
@@ -1,208 +1,90 @@
|
|
|
1
1
|
import * as plugins from '../../plugins.js';
|
|
2
|
-
import { ConnectionManager } from './connection-manager.js';
|
|
3
|
-
import { SecurityManager } from './security-manager.js';
|
|
4
|
-
import { TlsManager } from './tls-manager.js';
|
|
5
|
-
import { HttpProxyBridge } from './http-proxy-bridge.js';
|
|
6
|
-
import { TimeoutManager } from './timeout-manager.js';
|
|
7
2
|
import { SharedRouteManager as RouteManager } from '../../core/routing/route-manager.js';
|
|
8
|
-
import { RouteConnectionHandler } from './route-connection-handler.js';
|
|
9
|
-
import { NFTablesManager } from './nftables-manager.js';
|
|
10
|
-
import { SmartCertManager, type ICertStatus } from './certificate-manager.js';
|
|
11
3
|
import type { ISmartProxyOptions } from './models/interfaces.js';
|
|
12
4
|
import type { IRouteConfig } from './models/route-types.js';
|
|
13
|
-
import { AcmeStateManager } from './acme-state-manager.js';
|
|
14
|
-
import { MetricsCollector } from './metrics-collector.js';
|
|
15
5
|
import type { IMetrics } from './models/metrics-types.js';
|
|
16
6
|
/**
|
|
17
|
-
* SmartProxy -
|
|
7
|
+
* SmartProxy - Rust-backed proxy engine with TypeScript configuration API.
|
|
18
8
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* -
|
|
24
|
-
* -
|
|
25
|
-
* - How to handle TLS (passthrough, terminate, terminate-and-reencrypt)
|
|
26
|
-
* - Security settings (IP restrictions, connection limits)
|
|
27
|
-
* - Advanced options (timeout, headers, etc.)
|
|
9
|
+
* All networking (TCP, TLS, HTTP reverse proxy, connection management, security,
|
|
10
|
+
* NFTables) is handled by the Rust binary. TypeScript is only:
|
|
11
|
+
* - The npm module interface (types, route helpers)
|
|
12
|
+
* - The thin IPC wrapper (this class)
|
|
13
|
+
* - Socket-handler callback relay (for JS-defined handlers)
|
|
14
|
+
* - Certificate provisioning callbacks (certProvisionFunction)
|
|
28
15
|
*/
|
|
29
16
|
export declare class SmartProxy extends plugins.EventEmitter {
|
|
30
|
-
|
|
31
|
-
private connectionLogger;
|
|
32
|
-
private isShuttingDown;
|
|
33
|
-
connectionManager: ConnectionManager;
|
|
34
|
-
securityManager: SecurityManager;
|
|
35
|
-
tlsManager: TlsManager;
|
|
36
|
-
httpProxyBridge: HttpProxyBridge;
|
|
37
|
-
timeoutManager: TimeoutManager;
|
|
17
|
+
settings: ISmartProxyOptions;
|
|
38
18
|
routeManager: RouteManager;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
private
|
|
19
|
+
private bridge;
|
|
20
|
+
private preprocessor;
|
|
21
|
+
private socketHandlerServer;
|
|
22
|
+
private metricsAdapter;
|
|
43
23
|
private routeUpdateLock;
|
|
44
|
-
|
|
45
|
-
metricsCollector: MetricsCollector;
|
|
46
|
-
private routeOrchestrator;
|
|
47
|
-
private portUsageMap;
|
|
48
|
-
/**
|
|
49
|
-
* Constructor for SmartProxy
|
|
50
|
-
*
|
|
51
|
-
* @param settingsArg Configuration options containing routes and other settings
|
|
52
|
-
* Routes define how traffic is matched and handled, with each route having:
|
|
53
|
-
* - match: criteria for matching traffic (ports, domains, paths, IPs)
|
|
54
|
-
* - action: what to do with matched traffic (forward, redirect, block)
|
|
55
|
-
*
|
|
56
|
-
* Example:
|
|
57
|
-
* ```ts
|
|
58
|
-
* const proxy = new SmartProxy({
|
|
59
|
-
* routes: [
|
|
60
|
-
* {
|
|
61
|
-
* match: {
|
|
62
|
-
* ports: 443,
|
|
63
|
-
* domains: ['example.com', '*.example.com']
|
|
64
|
-
* },
|
|
65
|
-
* action: {
|
|
66
|
-
* type: 'forward',
|
|
67
|
-
* target: { host: '10.0.0.1', port: 8443 },
|
|
68
|
-
* tls: { mode: 'passthrough' }
|
|
69
|
-
* }
|
|
70
|
-
* }
|
|
71
|
-
* ],
|
|
72
|
-
* defaults: {
|
|
73
|
-
* target: { host: 'localhost', port: 8080 },
|
|
74
|
-
* security: { ipAllowList: ['*'] }
|
|
75
|
-
* }
|
|
76
|
-
* });
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
24
|
+
private stopping;
|
|
79
25
|
constructor(settingsArg: ISmartProxyOptions);
|
|
80
26
|
/**
|
|
81
|
-
*
|
|
82
|
-
|
|
83
|
-
settings: ISmartProxyOptions;
|
|
84
|
-
/**
|
|
85
|
-
* Helper method to create and configure certificate manager
|
|
86
|
-
* This ensures consistent setup including the required ACME callback
|
|
87
|
-
*/
|
|
88
|
-
private createCertificateManager;
|
|
89
|
-
/**
|
|
90
|
-
* Initialize certificate manager
|
|
91
|
-
*/
|
|
92
|
-
private initializeCertificateManager;
|
|
93
|
-
/**
|
|
94
|
-
* Check if we have routes with static certificates
|
|
95
|
-
*/
|
|
96
|
-
private hasStaticCertRoutes;
|
|
97
|
-
/**
|
|
98
|
-
* Start the proxy server with support for both configuration types
|
|
27
|
+
* Start the proxy.
|
|
28
|
+
* Spawns the Rust binary, configures socket relay if needed, sends routes, handles cert provisioning.
|
|
99
29
|
*/
|
|
100
30
|
start(): Promise<void>;
|
|
101
31
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* Note: This method has been removed as we now work directly with routes
|
|
105
|
-
*/
|
|
106
|
-
/**
|
|
107
|
-
* Stop the proxy server
|
|
32
|
+
* Stop the proxy.
|
|
108
33
|
*/
|
|
109
34
|
stop(): Promise<void>;
|
|
110
35
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* Note: This legacy method has been removed. Use updateRoutes instead.
|
|
114
|
-
*/
|
|
115
|
-
updateDomainConfigs(): Promise<void>;
|
|
116
|
-
/**
|
|
117
|
-
* Verify the challenge route has been properly removed from routes
|
|
118
|
-
*/
|
|
119
|
-
private verifyChallengeRouteRemoved;
|
|
120
|
-
/**
|
|
121
|
-
* Update routes with new configuration
|
|
122
|
-
*
|
|
123
|
-
* This method replaces the current route configuration with the provided routes.
|
|
124
|
-
* It also provisions certificates for routes that require TLS termination and have
|
|
125
|
-
* `certificate: 'auto'` set in their TLS configuration.
|
|
126
|
-
*
|
|
127
|
-
* @param newRoutes Array of route configurations to use
|
|
128
|
-
*
|
|
129
|
-
* Example:
|
|
130
|
-
* ```ts
|
|
131
|
-
* proxy.updateRoutes([
|
|
132
|
-
* {
|
|
133
|
-
* match: { ports: 443, domains: 'secure.example.com' },
|
|
134
|
-
* action: {
|
|
135
|
-
* type: 'forward',
|
|
136
|
-
* target: { host: '10.0.0.1', port: 8443 },
|
|
137
|
-
* tls: { mode: 'terminate', certificate: 'auto' }
|
|
138
|
-
* }
|
|
139
|
-
* }
|
|
140
|
-
* ]);
|
|
141
|
-
* ```
|
|
36
|
+
* Update routes atomically.
|
|
142
37
|
*/
|
|
143
38
|
updateRoutes(newRoutes: IRouteConfig[]): Promise<void>;
|
|
144
39
|
/**
|
|
145
|
-
*
|
|
40
|
+
* Provision a certificate for a named route.
|
|
146
41
|
*/
|
|
147
42
|
provisionCertificate(routeName: string): Promise<void>;
|
|
148
43
|
/**
|
|
149
|
-
* Force renewal of a certificate
|
|
44
|
+
* Force renewal of a certificate.
|
|
150
45
|
*/
|
|
151
46
|
renewCertificate(routeName: string): Promise<void>;
|
|
152
47
|
/**
|
|
153
|
-
* Get certificate status for a route
|
|
48
|
+
* Get certificate status for a route (async - calls Rust).
|
|
154
49
|
*/
|
|
155
|
-
getCertificateStatus(routeName: string):
|
|
50
|
+
getCertificateStatus(routeName: string): Promise<any>;
|
|
156
51
|
/**
|
|
157
|
-
* Get
|
|
158
|
-
*
|
|
159
|
-
* @returns IMetrics interface with grouped metrics methods
|
|
52
|
+
* Get the metrics interface.
|
|
160
53
|
*/
|
|
161
54
|
getMetrics(): IMetrics;
|
|
162
55
|
/**
|
|
163
|
-
*
|
|
56
|
+
* Get statistics (async - calls Rust).
|
|
164
57
|
*/
|
|
165
|
-
|
|
58
|
+
getStatistics(): Promise<any>;
|
|
166
59
|
/**
|
|
167
|
-
* Add a
|
|
168
|
-
*
|
|
169
|
-
* This allows you to add a port listener without updating routes.
|
|
170
|
-
* Useful for preparing to listen on a port before adding routes for it.
|
|
171
|
-
*
|
|
172
|
-
* @param port The port to start listening on
|
|
173
|
-
* @returns Promise that resolves when the port is listening
|
|
60
|
+
* Add a listening port at runtime.
|
|
174
61
|
*/
|
|
175
62
|
addListeningPort(port: number): Promise<void>;
|
|
176
63
|
/**
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
* This allows you to stop a port listener without updating routes.
|
|
180
|
-
* Useful for temporary maintenance or port changes.
|
|
181
|
-
*
|
|
182
|
-
* @param port The port to stop listening on
|
|
183
|
-
* @returns Promise that resolves when the port is closed
|
|
64
|
+
* Remove a listening port at runtime.
|
|
184
65
|
*/
|
|
185
66
|
removeListeningPort(port: number): Promise<void>;
|
|
186
67
|
/**
|
|
187
|
-
* Get
|
|
188
|
-
*
|
|
189
|
-
* @returns Array of port numbers
|
|
190
|
-
*/
|
|
191
|
-
getListeningPorts(): number[];
|
|
192
|
-
/**
|
|
193
|
-
* Get statistics about current connections
|
|
68
|
+
* Get all currently listening ports (async - calls Rust).
|
|
194
69
|
*/
|
|
195
|
-
|
|
70
|
+
getListeningPorts(): Promise<number[]>;
|
|
196
71
|
/**
|
|
197
|
-
* Get
|
|
72
|
+
* Get eligible domains for ACME certificates (sync - reads local routes).
|
|
198
73
|
*/
|
|
199
74
|
getEligibleDomainsForCertificates(): string[];
|
|
200
75
|
/**
|
|
201
|
-
* Get NFTables status
|
|
76
|
+
* Get NFTables status (async - calls Rust).
|
|
202
77
|
*/
|
|
203
78
|
getNfTablesStatus(): Promise<Record<string, any>>;
|
|
204
79
|
/**
|
|
205
|
-
*
|
|
80
|
+
* Build the Rust configuration object from TS settings.
|
|
206
81
|
*/
|
|
207
|
-
private
|
|
82
|
+
private buildRustConfig;
|
|
83
|
+
/**
|
|
84
|
+
* For routes with certificate: 'auto', call certProvisionFunction if set.
|
|
85
|
+
* If the callback returns a cert object, load it into Rust.
|
|
86
|
+
* If it returns 'http01', let Rust handle ACME.
|
|
87
|
+
*/
|
|
88
|
+
private provisionCertificatesViaCallback;
|
|
89
|
+
private isValidDomain;
|
|
208
90
|
}
|