@push.rocks/smartproxy 16.0.2 → 16.0.3
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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/core/models/index.d.ts +2 -0
- package/dist_ts/core/models/index.js +3 -1
- package/dist_ts/core/models/route-context.d.ts +62 -0
- package/dist_ts/core/models/route-context.js +43 -0
- package/dist_ts/core/models/socket-augmentation.d.ts +12 -0
- package/dist_ts/core/models/socket-augmentation.js +18 -0
- package/dist_ts/core/utils/event-system.d.ts +200 -0
- package/dist_ts/core/utils/event-system.js +224 -0
- package/dist_ts/core/utils/index.d.ts +7 -0
- package/dist_ts/core/utils/index.js +8 -1
- package/dist_ts/core/utils/route-manager.d.ts +118 -0
- package/dist_ts/core/utils/route-manager.js +383 -0
- package/dist_ts/core/utils/route-utils.d.ts +94 -0
- package/dist_ts/core/utils/route-utils.js +264 -0
- package/dist_ts/core/utils/security-utils.d.ts +111 -0
- package/dist_ts/core/utils/security-utils.js +212 -0
- package/dist_ts/core/utils/shared-security-manager.d.ts +110 -0
- package/dist_ts/core/utils/shared-security-manager.js +252 -0
- package/dist_ts/core/utils/template-utils.d.ts +37 -0
- package/dist_ts/core/utils/template-utils.js +104 -0
- package/dist_ts/core/utils/websocket-utils.d.ts +23 -0
- package/dist_ts/core/utils/websocket-utils.js +86 -0
- package/dist_ts/http/router/index.d.ts +5 -1
- package/dist_ts/http/router/index.js +4 -2
- package/dist_ts/http/router/route-router.d.ts +108 -0
- package/dist_ts/http/router/route-router.js +393 -0
- package/dist_ts/index.d.ts +8 -2
- package/dist_ts/index.js +10 -3
- package/dist_ts/proxies/index.d.ts +7 -2
- package/dist_ts/proxies/index.js +10 -4
- package/dist_ts/proxies/network-proxy/certificate-manager.d.ts +21 -0
- package/dist_ts/proxies/network-proxy/certificate-manager.js +92 -1
- package/dist_ts/proxies/network-proxy/context-creator.d.ts +34 -0
- package/dist_ts/proxies/network-proxy/context-creator.js +108 -0
- package/dist_ts/proxies/network-proxy/function-cache.d.ts +90 -0
- package/dist_ts/proxies/network-proxy/function-cache.js +198 -0
- package/dist_ts/proxies/network-proxy/http-request-handler.d.ts +40 -0
- package/dist_ts/proxies/network-proxy/http-request-handler.js +256 -0
- package/dist_ts/proxies/network-proxy/http2-request-handler.d.ts +24 -0
- package/dist_ts/proxies/network-proxy/http2-request-handler.js +201 -0
- package/dist_ts/proxies/network-proxy/models/types.d.ts +73 -1
- package/dist_ts/proxies/network-proxy/models/types.js +242 -1
- package/dist_ts/proxies/network-proxy/network-proxy.d.ts +23 -20
- package/dist_ts/proxies/network-proxy/network-proxy.js +147 -60
- package/dist_ts/proxies/network-proxy/request-handler.d.ts +38 -5
- package/dist_ts/proxies/network-proxy/request-handler.js +584 -198
- package/dist_ts/proxies/network-proxy/security-manager.d.ts +65 -0
- package/dist_ts/proxies/network-proxy/security-manager.js +255 -0
- package/dist_ts/proxies/network-proxy/websocket-handler.d.ts +13 -2
- package/dist_ts/proxies/network-proxy/websocket-handler.js +238 -20
- package/dist_ts/proxies/smart-proxy/index.d.ts +1 -1
- package/dist_ts/proxies/smart-proxy/index.js +3 -3
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +3 -5
- package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +56 -3
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +4 -57
- package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +19 -228
- package/dist_ts/proxies/smart-proxy/port-manager.d.ts +81 -0
- package/dist_ts/proxies/smart-proxy/port-manager.js +166 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +5 -0
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +131 -15
- package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +3 -1
- package/dist_ts/proxies/smart-proxy/route-helpers/index.js +5 -3
- package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +5 -178
- package/dist_ts/proxies/smart-proxy/route-helpers.js +8 -296
- package/dist_ts/proxies/smart-proxy/route-manager.d.ts +11 -2
- package/dist_ts/proxies/smart-proxy/route-manager.js +79 -10
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +29 -2
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +48 -43
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.d.ts +67 -1
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +120 -1
- package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +3 -3
- package/dist_ts/proxies/smart-proxy/utils/route-validators.js +27 -5
- package/package.json +1 -1
- package/readme.md +102 -14
- package/readme.plan.md +103 -168
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/models/index.ts +2 -0
- package/ts/core/models/route-context.ts +113 -0
- package/ts/core/models/socket-augmentation.ts +33 -0
- package/ts/core/utils/event-system.ts +376 -0
- package/ts/core/utils/index.ts +7 -0
- package/ts/core/utils/route-manager.ts +489 -0
- package/ts/core/utils/route-utils.ts +312 -0
- package/ts/core/utils/security-utils.ts +309 -0
- package/ts/core/utils/shared-security-manager.ts +333 -0
- package/ts/core/utils/template-utils.ts +124 -0
- package/ts/core/utils/websocket-utils.ts +81 -0
- package/ts/http/router/index.ts +8 -1
- package/ts/http/router/route-router.ts +482 -0
- package/ts/index.ts +14 -2
- package/ts/proxies/index.ts +12 -3
- package/ts/proxies/network-proxy/certificate-manager.ts +114 -10
- package/ts/proxies/network-proxy/context-creator.ts +145 -0
- package/ts/proxies/network-proxy/function-cache.ts +259 -0
- package/ts/proxies/network-proxy/http-request-handler.ts +330 -0
- package/ts/proxies/network-proxy/http2-request-handler.ts +255 -0
- package/ts/proxies/network-proxy/models/types.ts +312 -1
- package/ts/proxies/network-proxy/network-proxy.ts +195 -86
- package/ts/proxies/network-proxy/request-handler.ts +698 -246
- package/ts/proxies/network-proxy/security-manager.ts +298 -0
- package/ts/proxies/network-proxy/websocket-handler.ts +276 -33
- package/ts/proxies/smart-proxy/index.ts +2 -12
- package/ts/proxies/smart-proxy/models/interfaces.ts +7 -4
- package/ts/proxies/smart-proxy/models/route-types.ts +78 -10
- package/ts/proxies/smart-proxy/network-proxy-bridge.ts +20 -257
- package/ts/proxies/smart-proxy/port-manager.ts +195 -0
- package/ts/proxies/smart-proxy/route-connection-handler.ts +156 -21
- package/ts/proxies/smart-proxy/route-manager.ts +98 -14
- package/ts/proxies/smart-proxy/smart-proxy.ts +56 -55
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +167 -1
- package/ts/proxies/smart-proxy/utils/route-validators.ts +24 -5
- package/ts/proxies/smart-proxy/domain-config-manager.ts.bak +0 -441
- package/ts/proxies/smart-proxy/route-helpers/index.ts +0 -9
- package/ts/proxies/smart-proxy/route-helpers.ts +0 -498
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartproxy",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
package/readme.md
CHANGED
|
@@ -7,6 +7,7 @@ A unified high-performance proxy toolkit for Node.js, with **SmartProxy** as the
|
|
|
7
7
|
- **Flexible Matching Patterns**: Route by port, domain, path, client IP, and TLS version
|
|
8
8
|
- **Advanced SNI Handling**: Smart TCP/SNI-based forwarding with IP filtering
|
|
9
9
|
- **Multiple Action Types**: Forward (with TLS modes), redirect, or block traffic
|
|
10
|
+
- **Dynamic Port Management**: Add or remove listening ports at runtime without restart
|
|
10
11
|
- **Security Features**: IP allowlists, connection limits, timeouts, and more
|
|
11
12
|
|
|
12
13
|
## Project Architecture Overview
|
|
@@ -211,12 +212,18 @@ proxy.on('certificate', evt => {
|
|
|
211
212
|
await proxy.start();
|
|
212
213
|
|
|
213
214
|
// Dynamically add new routes later
|
|
214
|
-
await proxy.
|
|
215
|
+
await proxy.updateRoutes([
|
|
216
|
+
...proxy.settings.routes,
|
|
215
217
|
createHttpsTerminateRoute('new-domain.com', { host: 'localhost', port: 9000 }, {
|
|
216
218
|
certificate: 'auto'
|
|
217
219
|
})
|
|
218
220
|
]);
|
|
219
221
|
|
|
222
|
+
// Dynamically add or remove port listeners
|
|
223
|
+
await proxy.addListeningPort(8081);
|
|
224
|
+
await proxy.removeListeningPort(8081);
|
|
225
|
+
console.log('Currently listening on ports:', proxy.getListeningPorts());
|
|
226
|
+
|
|
220
227
|
// Later, gracefully shut down
|
|
221
228
|
await proxy.stop();
|
|
222
229
|
```
|
|
@@ -557,12 +564,37 @@ Available helper functions:
|
|
|
557
564
|
})
|
|
558
565
|
```
|
|
559
566
|
|
|
567
|
+
8. **Dynamic Port Management**
|
|
568
|
+
```typescript
|
|
569
|
+
// Start the proxy with initial configuration
|
|
570
|
+
const proxy = new SmartProxy({
|
|
571
|
+
routes: [
|
|
572
|
+
createHttpRoute('example.com', { host: 'localhost', port: 8080 })
|
|
573
|
+
]
|
|
574
|
+
});
|
|
575
|
+
await proxy.start();
|
|
576
|
+
|
|
577
|
+
// Dynamically add a new port listener
|
|
578
|
+
await proxy.addListeningPort(8081);
|
|
579
|
+
|
|
580
|
+
// Add a route for the new port
|
|
581
|
+
const currentRoutes = proxy.settings.routes;
|
|
582
|
+
const newRoute = createHttpRoute('api.example.com', { host: 'api-server', port: 3000 });
|
|
583
|
+
newRoute.match.ports = 8081; // Override the default port
|
|
584
|
+
|
|
585
|
+
// Update routes - will automatically sync port listeners
|
|
586
|
+
await proxy.updateRoutes([...currentRoutes, newRoute]);
|
|
587
|
+
|
|
588
|
+
// Later, remove a port listener when needed
|
|
589
|
+
await proxy.removeListeningPort(8081);
|
|
590
|
+
```
|
|
591
|
+
|
|
560
592
|
## Other Components
|
|
561
593
|
|
|
562
594
|
While SmartProxy provides a unified API for most needs, you can also use individual components:
|
|
563
595
|
|
|
564
596
|
### NetworkProxy
|
|
565
|
-
For HTTP/HTTPS reverse proxy with TLS termination and WebSocket support:
|
|
597
|
+
For HTTP/HTTPS reverse proxy with TLS termination and WebSocket support. Now with native route-based configuration support:
|
|
566
598
|
|
|
567
599
|
```typescript
|
|
568
600
|
import { NetworkProxy } from '@push.rocks/smartproxy';
|
|
@@ -570,9 +602,49 @@ import * as fs from 'fs';
|
|
|
570
602
|
|
|
571
603
|
const proxy = new NetworkProxy({ port: 443 });
|
|
572
604
|
await proxy.start();
|
|
605
|
+
|
|
606
|
+
// Modern route-based configuration (recommended)
|
|
607
|
+
await proxy.updateRouteConfigs([
|
|
608
|
+
{
|
|
609
|
+
match: {
|
|
610
|
+
ports: 443,
|
|
611
|
+
domains: 'example.com'
|
|
612
|
+
},
|
|
613
|
+
action: {
|
|
614
|
+
type: 'forward',
|
|
615
|
+
target: {
|
|
616
|
+
host: '127.0.0.1',
|
|
617
|
+
port: 3000
|
|
618
|
+
},
|
|
619
|
+
tls: {
|
|
620
|
+
mode: 'terminate',
|
|
621
|
+
certificate: {
|
|
622
|
+
cert: fs.readFileSync('cert.pem', 'utf8'),
|
|
623
|
+
key: fs.readFileSync('key.pem', 'utf8')
|
|
624
|
+
}
|
|
625
|
+
},
|
|
626
|
+
advanced: {
|
|
627
|
+
headers: {
|
|
628
|
+
'X-Forwarded-By': 'NetworkProxy'
|
|
629
|
+
},
|
|
630
|
+
urlRewrite: {
|
|
631
|
+
pattern: '^/old/(.*)$',
|
|
632
|
+
target: '/new/$1',
|
|
633
|
+
flags: 'g'
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
websocket: {
|
|
637
|
+
enabled: true,
|
|
638
|
+
pingInterval: 30000
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
]);
|
|
643
|
+
|
|
644
|
+
// Legacy configuration (for backward compatibility)
|
|
573
645
|
await proxy.updateProxyConfigs([
|
|
574
646
|
{
|
|
575
|
-
hostName: 'example.com',
|
|
647
|
+
hostName: 'legacy.example.com',
|
|
576
648
|
destinationIps: ['127.0.0.1'],
|
|
577
649
|
destinationPorts: [3000],
|
|
578
650
|
publicKey: fs.readFileSync('cert.pem', 'utf8'),
|
|
@@ -1084,18 +1156,34 @@ createRedirectRoute({
|
|
|
1084
1156
|
- Socket opts: `noDelay`, `keepAlive`, `enableKeepAliveProbes`
|
|
1085
1157
|
- `certProvisionFunction` (callback) - Custom certificate provisioning
|
|
1086
1158
|
|
|
1159
|
+
#### SmartProxy Dynamic Port Management Methods
|
|
1160
|
+
- `async addListeningPort(port: number)` - Add a new port listener without changing routes
|
|
1161
|
+
- `async removeListeningPort(port: number)` - Remove a port listener without changing routes
|
|
1162
|
+
- `getListeningPorts()` - Get all ports currently being listened on
|
|
1163
|
+
- `async updateRoutes(routes: IRouteConfig[])` - Update routes and automatically adjust port listeners
|
|
1164
|
+
|
|
1087
1165
|
### NetworkProxy (INetworkProxyOptions)
|
|
1088
|
-
- `port` (number, required)
|
|
1089
|
-
- `backendProtocol` ('http1'|'http2', default 'http1')
|
|
1090
|
-
- `maxConnections` (number, default 10000)
|
|
1091
|
-
- `keepAliveTimeout` (ms, default 120000)
|
|
1092
|
-
- `headersTimeout` (ms, default 60000)
|
|
1093
|
-
- `cors` (object)
|
|
1094
|
-
- `connectionPoolSize` (number, default 50)
|
|
1095
|
-
- `logLevel` ('error'|'warn'|'info'|'debug')
|
|
1096
|
-
- `acme` (IAcmeOptions)
|
|
1097
|
-
- `useExternalPort80Handler` (boolean)
|
|
1098
|
-
- `portProxyIntegration` (boolean)
|
|
1166
|
+
- `port` (number, required) - Main port to listen on
|
|
1167
|
+
- `backendProtocol` ('http1'|'http2', default 'http1') - Protocol to use with backend servers
|
|
1168
|
+
- `maxConnections` (number, default 10000) - Maximum concurrent connections
|
|
1169
|
+
- `keepAliveTimeout` (ms, default 120000) - Connection keep-alive timeout
|
|
1170
|
+
- `headersTimeout` (ms, default 60000) - Timeout for receiving complete headers
|
|
1171
|
+
- `cors` (object) - Cross-Origin Resource Sharing configuration
|
|
1172
|
+
- `connectionPoolSize` (number, default 50) - Size of the connection pool for backend servers
|
|
1173
|
+
- `logLevel` ('error'|'warn'|'info'|'debug') - Logging verbosity level
|
|
1174
|
+
- `acme` (IAcmeOptions) - ACME certificate configuration
|
|
1175
|
+
- `useExternalPort80Handler` (boolean) - Use external port 80 handler for ACME challenges
|
|
1176
|
+
- `portProxyIntegration` (boolean) - Integration with other proxies
|
|
1177
|
+
|
|
1178
|
+
#### NetworkProxy Enhanced Features
|
|
1179
|
+
NetworkProxy now supports full route-based configuration including:
|
|
1180
|
+
- Advanced request and response header manipulation
|
|
1181
|
+
- URL rewriting with RegExp pattern matching
|
|
1182
|
+
- Template variable resolution for dynamic values (e.g. `{domain}`, `{clientIp}`)
|
|
1183
|
+
- Function-based dynamic target resolution
|
|
1184
|
+
- Security features (IP filtering, rate limiting, authentication)
|
|
1185
|
+
- WebSocket configuration with path rewriting, custom headers, ping control, and size limits
|
|
1186
|
+
- Context-aware CORS configuration
|
|
1099
1187
|
|
|
1100
1188
|
### Port80Handler (IAcmeOptions)
|
|
1101
1189
|
- `enabled` (boolean, default true)
|
package/readme.plan.md
CHANGED
|
@@ -1,168 +1,103 @@
|
|
|
1
|
-
# SmartProxy
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
-
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
- [x] 5.9 Optimize route operations for large configurations
|
|
105
|
-
- [x] 5.10 Verify public API matches documentation
|
|
106
|
-
- [x] 5.11 Check for any backward compatibility issues
|
|
107
|
-
- [x] 5.12 Ensure all examples in README work correctly
|
|
108
|
-
- [x] 5.13 Run full test suite with new implementation
|
|
109
|
-
- [x] 5.14 Create a final PR with all changes
|
|
110
|
-
|
|
111
|
-
## Clean Break Approach
|
|
112
|
-
|
|
113
|
-
To keep our codebase as clean as possible, we are taking a clean break approach with NO migration or compatibility support for domain-based configuration. We will:
|
|
114
|
-
|
|
115
|
-
1. Completely remove all domain-based code
|
|
116
|
-
2. Not provide any migration utilities in the codebase
|
|
117
|
-
3. Focus solely on the route-based approach
|
|
118
|
-
4. Document the route-based API as the only supported method
|
|
119
|
-
|
|
120
|
-
This approach prioritizes codebase clarity over backward compatibility, which is appropriate since we've already made a clean break in the public API with v14.0.0.
|
|
121
|
-
|
|
122
|
-
## File Changes
|
|
123
|
-
|
|
124
|
-
### Files to Delete (Remove Completely)
|
|
125
|
-
- [x] `/ts/forwarding/config/domain-config.ts` - Deleted with no replacement
|
|
126
|
-
- [x] `/ts/forwarding/config/domain-manager.ts` - Deleted with no replacement
|
|
127
|
-
- [x] `/ts/forwarding/config/forwarding-types.ts` - Updated with pure route-based types
|
|
128
|
-
- [x] Any domain-config related tests have been updated to use route-based approach
|
|
129
|
-
|
|
130
|
-
### Files to Modify (Remove All Domain References)
|
|
131
|
-
- [x] `/ts/certificate/providers/cert-provisioner.ts` - Complete rewrite to use routes only ✅
|
|
132
|
-
- [x] `/ts/proxies/smart-proxy/network-proxy-bridge.ts` - Direct route processing implementation ✅
|
|
133
|
-
- [x] `/ts/certificate/models/certificate-types.ts` - Updated with route-based interfaces ✅
|
|
134
|
-
- [x] `/ts/certificate/index.ts` - Cleaned up domain-related types and exports
|
|
135
|
-
- [x] `/ts/http/port80/port80-handler.ts` - Updated to work exclusively with routes
|
|
136
|
-
- [x] `/ts/proxies/smart-proxy/smart-proxy.ts` - Removed domain references
|
|
137
|
-
- [x] `test/test.forwarding.ts` - Updated to use route-based approach
|
|
138
|
-
- [x] `test/test.forwarding.unit.ts` - Updated to use route-based approach
|
|
139
|
-
|
|
140
|
-
### New Files to Create (Route-Focused)
|
|
141
|
-
- [x] `/ts/proxies/smart-proxy/utils/route-helpers.ts` - Created with helper functions for common route configurations
|
|
142
|
-
- [x] `/ts/proxies/smart-proxy/utils/route-migration-utils.ts` - Added migration utilities from domains to routes
|
|
143
|
-
- [x] `/ts/proxies/smart-proxy/utils/route-validators.ts` - Validation utilities for route configurations
|
|
144
|
-
- [x] `/ts/proxies/smart-proxy/utils/route-utils.ts` - Additional route utility functions
|
|
145
|
-
- [x] `/ts/proxies/smart-proxy/utils/route-patterns.ts` - Common route patterns for easy configuration
|
|
146
|
-
- [x] `/ts/proxies/smart-proxy/utils/index.ts` - Central export point for all route utilities
|
|
147
|
-
|
|
148
|
-
## Benefits of Complete Refactoring
|
|
149
|
-
|
|
150
|
-
1. **Codebase Simplicity**:
|
|
151
|
-
- No dual implementation or conversion logic
|
|
152
|
-
- Simplified mental model for developers
|
|
153
|
-
- Easier to maintain and extend
|
|
154
|
-
|
|
155
|
-
2. **Performance Improvements**:
|
|
156
|
-
- Remove conversion overhead
|
|
157
|
-
- More efficient route matching
|
|
158
|
-
- Reduced memory footprint
|
|
159
|
-
|
|
160
|
-
3. **Better Developer Experience**:
|
|
161
|
-
- Consistent API throughout
|
|
162
|
-
- Cleaner documentation
|
|
163
|
-
- More intuitive configuration patterns
|
|
164
|
-
|
|
165
|
-
4. **Future-Proof Design**:
|
|
166
|
-
- Clear foundation for new features
|
|
167
|
-
- Easier to implement advanced routing capabilities
|
|
168
|
-
- Better integration with modern web patterns
|
|
1
|
+
# SmartProxy Configuration Troubleshooting
|
|
2
|
+
|
|
3
|
+
## IPv6/IPv4 Mapping Issue
|
|
4
|
+
|
|
5
|
+
### Problem Identified
|
|
6
|
+
The SmartProxy is failing to match connections for wildcard domains (like `*.lossless.digital`) when IP restrictions are in place. After extensive debugging, the root cause has been identified:
|
|
7
|
+
|
|
8
|
+
When a connection comes in from an IPv4 address (e.g., `212.95.99.130`), the Node.js server receives it as an IPv6-mapped IPv4 address with the format `::ffff:212.95.99.130`. However, the route configuration is expecting the exact string `212.95.99.130`, causing a mismatch.
|
|
9
|
+
|
|
10
|
+
From the debug logs:
|
|
11
|
+
```
|
|
12
|
+
[DEBUG] Route rejected: clientIp mismatch. Request: ::ffff:212.95.99.130, Route patterns: ["212.95.99.130"]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Solution
|
|
16
|
+
|
|
17
|
+
To fix this issue, update the route configurations to include both formats of the IP address. Here's how to modify the affected route:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// Wildcard domain route for *.lossless.digital
|
|
21
|
+
{
|
|
22
|
+
match: {
|
|
23
|
+
ports: 443,
|
|
24
|
+
domains: ['*.lossless.digital'],
|
|
25
|
+
clientIp: ['212.95.99.130', '::ffff:212.95.99.130'], // Include both formats
|
|
26
|
+
},
|
|
27
|
+
action: {
|
|
28
|
+
type: 'forward',
|
|
29
|
+
target: {
|
|
30
|
+
host: '212.95.99.130',
|
|
31
|
+
port: 443
|
|
32
|
+
},
|
|
33
|
+
tls: {
|
|
34
|
+
mode: 'passthrough'
|
|
35
|
+
},
|
|
36
|
+
security: {
|
|
37
|
+
allowedIps: ['212.95.99.130', '::ffff:212.95.99.130'] // Include both formats
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
name: 'Wildcard lossless.digital route (IP restricted)'
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Alternative Long-Term Fix
|
|
45
|
+
|
|
46
|
+
A more robust solution would be to modify the SmartProxy codebase to automatically handle IPv6-mapped IPv4 addresses by normalizing them before comparison. This would involve:
|
|
47
|
+
|
|
48
|
+
1. Modifying the `matchIpPattern` function in `route-manager.ts` to normalize IPv6-mapped IPv4 addresses:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
private matchIpPattern(pattern: string, ip: string): boolean {
|
|
52
|
+
// Normalize IPv6-mapped IPv4 addresses
|
|
53
|
+
const normalizedIp = ip.startsWith('::ffff:') ? ip.substring(7) : ip;
|
|
54
|
+
const normalizedPattern = pattern.startsWith('::ffff:') ? pattern.substring(7) : pattern;
|
|
55
|
+
|
|
56
|
+
// Handle exact match with normalized addresses
|
|
57
|
+
if (normalizedPattern === normalizedIp) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Rest of the existing function...
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
2. Making similar modifications to other IP-related functions in the codebase.
|
|
66
|
+
|
|
67
|
+
## Wild Card Domain Matching Issue
|
|
68
|
+
|
|
69
|
+
### Explanation
|
|
70
|
+
|
|
71
|
+
The wildcard domain matching in SmartProxy works as follows:
|
|
72
|
+
|
|
73
|
+
1. When a pattern like `*.lossless.digital` is specified, it's converted to a regex: `/^.*\.lossless\.digital$/i`
|
|
74
|
+
2. This correctly matches any subdomain like `my.lossless.digital`, `api.lossless.digital`, etc.
|
|
75
|
+
3. However, it does NOT match the apex domain `lossless.digital` (without a subdomain)
|
|
76
|
+
|
|
77
|
+
If you need to match both the apex domain and subdomains, use a list:
|
|
78
|
+
```typescript
|
|
79
|
+
domains: ['lossless.digital', '*.lossless.digital']
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Debugging SmartProxy
|
|
83
|
+
|
|
84
|
+
To debug routing issues in SmartProxy:
|
|
85
|
+
|
|
86
|
+
1. Add detailed logging to the `route-manager.js` file in the `dist_ts` directory:
|
|
87
|
+
- `findMatchingRoute` method - to see what criteria are being checked
|
|
88
|
+
- `matchRouteDomain` method - to see domain matching logic
|
|
89
|
+
- `matchDomain` method - to see pattern matching
|
|
90
|
+
- `matchIpPattern` method - to see IP matching logic
|
|
91
|
+
|
|
92
|
+
2. Run the proxy with debugging enabled:
|
|
93
|
+
```
|
|
94
|
+
pnpm run startNew
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
3. Monitor the logs for detailed information about the routing process and identify where matches are failing.
|
|
98
|
+
|
|
99
|
+
## Priority and Route Order
|
|
100
|
+
|
|
101
|
+
Remember that routes are evaluated in priority order (higher priority first). If multiple routes could match the same request, ensure that the more specific routes have higher priority.
|
|
102
|
+
|
|
103
|
+
When routes have the same priority (or none specified), they're evaluated in the order they're defined in the configuration.
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartproxy',
|
|
6
|
-
version: '16.0.
|
|
6
|
+
version: '16.0.3',
|
|
7
7
|
description: 'A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.'
|
|
8
8
|
}
|
package/ts/core/models/index.ts
CHANGED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared Route Context Interface
|
|
5
|
+
*
|
|
6
|
+
* This interface defines the route context object that is used by both
|
|
7
|
+
* SmartProxy and NetworkProxy, ensuring consistent context throughout the system.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Route context for route matching and function-based target resolution
|
|
12
|
+
*/
|
|
13
|
+
export interface IRouteContext {
|
|
14
|
+
// Connection basics
|
|
15
|
+
port: number; // The matched incoming port
|
|
16
|
+
domain?: string; // The domain from SNI or Host header
|
|
17
|
+
clientIp: string; // The client's IP address
|
|
18
|
+
serverIp: string; // The server's IP address
|
|
19
|
+
|
|
20
|
+
// HTTP specifics (NetworkProxy only)
|
|
21
|
+
path?: string; // URL path (for HTTP connections)
|
|
22
|
+
query?: string; // Query string (for HTTP connections)
|
|
23
|
+
headers?: Record<string, string>; // HTTP headers (for HTTP connections)
|
|
24
|
+
|
|
25
|
+
// TLS information
|
|
26
|
+
isTls: boolean; // Whether the connection is TLS
|
|
27
|
+
tlsVersion?: string; // TLS version if applicable
|
|
28
|
+
|
|
29
|
+
// Routing information
|
|
30
|
+
routeName?: string; // The name of the matched route
|
|
31
|
+
routeId?: string; // The ID of the matched route
|
|
32
|
+
|
|
33
|
+
// Resolved values
|
|
34
|
+
targetHost?: string | string[]; // The resolved target host
|
|
35
|
+
targetPort?: number; // The resolved target port
|
|
36
|
+
|
|
37
|
+
// Request metadata
|
|
38
|
+
timestamp: number; // The request timestamp
|
|
39
|
+
connectionId: string; // Unique connection identifier
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Extended context interface with HTTP-specific objects
|
|
44
|
+
* Used only in NetworkProxy for HTTP request handling
|
|
45
|
+
*/
|
|
46
|
+
export interface IHttpRouteContext extends IRouteContext {
|
|
47
|
+
req?: plugins.http.IncomingMessage;
|
|
48
|
+
res?: plugins.http.ServerResponse;
|
|
49
|
+
method?: string; // HTTP method (GET, POST, etc.)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Extended context interface with HTTP/2-specific objects
|
|
54
|
+
* Used only in NetworkProxy for HTTP/2 request handling
|
|
55
|
+
*/
|
|
56
|
+
export interface IHttp2RouteContext extends IHttpRouteContext {
|
|
57
|
+
stream?: plugins.http2.ServerHttp2Stream;
|
|
58
|
+
headers?: Record<string, string>; // HTTP/2 pseudo-headers like :method, :path
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Create a basic route context from connection information
|
|
63
|
+
*/
|
|
64
|
+
export function createBaseRouteContext(options: {
|
|
65
|
+
port: number;
|
|
66
|
+
clientIp: string;
|
|
67
|
+
serverIp: string;
|
|
68
|
+
domain?: string;
|
|
69
|
+
isTls: boolean;
|
|
70
|
+
tlsVersion?: string;
|
|
71
|
+
connectionId: string;
|
|
72
|
+
}): IRouteContext {
|
|
73
|
+
return {
|
|
74
|
+
...options,
|
|
75
|
+
timestamp: Date.now(),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Convert IHttpRouteContext to IRouteContext
|
|
81
|
+
* This is used to ensure type compatibility when passing HTTP-specific context
|
|
82
|
+
* to methods that require the base IRouteContext type
|
|
83
|
+
*/
|
|
84
|
+
export function toBaseContext(httpContext: IHttpRouteContext): IRouteContext {
|
|
85
|
+
// Create a new object with only the properties from IRouteContext
|
|
86
|
+
const baseContext: IRouteContext = {
|
|
87
|
+
port: httpContext.port,
|
|
88
|
+
domain: httpContext.domain,
|
|
89
|
+
clientIp: httpContext.clientIp,
|
|
90
|
+
serverIp: httpContext.serverIp,
|
|
91
|
+
path: httpContext.path,
|
|
92
|
+
query: httpContext.query,
|
|
93
|
+
headers: httpContext.headers,
|
|
94
|
+
isTls: httpContext.isTls,
|
|
95
|
+
tlsVersion: httpContext.tlsVersion,
|
|
96
|
+
routeName: httpContext.routeName,
|
|
97
|
+
routeId: httpContext.routeId,
|
|
98
|
+
timestamp: httpContext.timestamp,
|
|
99
|
+
connectionId: httpContext.connectionId
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// Only copy targetHost if it's a string
|
|
103
|
+
if (httpContext.targetHost) {
|
|
104
|
+
baseContext.targetHost = httpContext.targetHost;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Copy targetPort if it exists
|
|
108
|
+
if (httpContext.targetPort) {
|
|
109
|
+
baseContext.targetPort = httpContext.targetPort;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return baseContext;
|
|
113
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as plugins from '../../plugins.js';
|
|
2
|
+
|
|
3
|
+
// Augment the Node.js Socket type to include TLS-related properties
|
|
4
|
+
// This helps TypeScript understand properties that are dynamically added by Node.js
|
|
5
|
+
declare module 'net' {
|
|
6
|
+
interface Socket {
|
|
7
|
+
// TLS-related properties
|
|
8
|
+
encrypted?: boolean; // Indicates if the socket is encrypted (TLS/SSL)
|
|
9
|
+
authorizationError?: Error; // Authentication error if TLS handshake failed
|
|
10
|
+
|
|
11
|
+
// TLS-related methods
|
|
12
|
+
getTLSVersion?(): string; // Returns the TLS version (e.g., 'TLSv1.2', 'TLSv1.3')
|
|
13
|
+
getPeerCertificate?(detailed?: boolean): any; // Returns the peer's certificate
|
|
14
|
+
getSession?(): Buffer; // Returns the TLS session data
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Export a utility function to check if a socket is a TLS socket
|
|
19
|
+
export function isTLSSocket(socket: plugins.net.Socket): boolean {
|
|
20
|
+
return 'encrypted' in socket && !!socket.encrypted;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Export a utility function to safely get the TLS version
|
|
24
|
+
export function getTLSVersion(socket: plugins.net.Socket): string | null {
|
|
25
|
+
if (socket.getTLSVersion) {
|
|
26
|
+
try {
|
|
27
|
+
return socket.getTLSVersion();
|
|
28
|
+
} catch (e) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|