@push.rocks/smartproxy 21.1.3 → 21.1.6
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 +31 -0
- package/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/core/models/socket-augmentation.d.ts +3 -0
- package/dist_ts/core/models/socket-augmentation.js +1 -1
- package/dist_ts/core/utils/ip-utils.d.ts +16 -0
- package/dist_ts/core/utils/ip-utils.js +122 -5
- package/dist_ts/core/utils/socket-tracker.d.ts +16 -0
- package/dist_ts/core/utils/socket-tracker.js +49 -0
- package/dist_ts/detection/detectors/http-detector.js +14 -2
- package/dist_ts/detection/protocol-detector.js +2 -1
- package/dist_ts/proxies/http-proxy/http-proxy.d.ts +5 -1
- package/dist_ts/proxies/http-proxy/http-proxy.js +63 -39
- package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +5 -0
- package/dist_ts/proxies/smart-proxy/certificate-manager.js +20 -6
- package/dist_ts/proxies/smart-proxy/index.d.ts +1 -0
- package/dist_ts/proxies/smart-proxy/index.js +2 -1
- package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +4 -0
- package/dist_ts/proxies/smart-proxy/metrics-collector.js +52 -7
- package/dist_ts/proxies/smart-proxy/route-orchestrator.d.ts +56 -0
- package/dist_ts/proxies/smart-proxy/route-orchestrator.js +204 -0
- package/dist_ts/proxies/smart-proxy/security-manager.js +14 -3
- package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +1 -11
- package/dist_ts/proxies/smart-proxy/smart-proxy.js +48 -237
- package/dist_ts/proxies/smart-proxy/utils/route-helpers.js +42 -7
- package/dist_ts/proxies/smart-proxy/utils/route-validator.d.ts +58 -0
- package/dist_ts/proxies/smart-proxy/utils/route-validator.js +406 -0
- package/package.json +3 -2
- package/readme.md +321 -828
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/models/socket-augmentation.ts +5 -0
- package/ts/core/utils/ip-utils.ts +134 -6
- package/ts/core/utils/socket-tracker.ts +63 -0
- package/ts/detection/detectors/http-detector.ts +14 -1
- package/ts/detection/protocol-detector.ts +1 -0
- package/ts/proxies/http-proxy/http-proxy.ts +73 -48
- package/ts/proxies/smart-proxy/certificate-manager.ts +21 -5
- package/ts/proxies/smart-proxy/index.ts +1 -0
- package/ts/proxies/smart-proxy/metrics-collector.ts +58 -6
- package/ts/proxies/smart-proxy/route-orchestrator.ts +297 -0
- package/ts/proxies/smart-proxy/security-manager.ts +14 -2
- package/ts/proxies/smart-proxy/smart-proxy.ts +66 -270
- package/ts/proxies/smart-proxy/utils/route-helpers.ts +45 -6
- package/ts/proxies/smart-proxy/utils/route-validator.ts +454 -0
package/readme.md
CHANGED
|
@@ -1,475 +1,64 @@
|
|
|
1
|
-
# @push.rocks/smartproxy
|
|
1
|
+
# @push.rocks/smartproxy 🚀
|
|
2
2
|
|
|
3
|
-
A unified high-performance proxy toolkit
|
|
3
|
+
**The Swiss Army Knife of Node.js Proxies** - A unified, high-performance proxy toolkit that handles everything from simple HTTP forwarding to complex enterprise routing scenarios.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- **SSL/TLS Support**: Automatic HTTPS with Let's Encrypt certificate provisioning
|
|
7
|
-
- **Flexible Matching Patterns**: Route by port, domain, path, client IP, and TLS version
|
|
8
|
-
- **Advanced SNI Handling**: Smart TCP/SNI-based forwarding with IP filtering
|
|
9
|
-
- **Multiple Action Types**: Forward traffic or handle with custom socket handlers
|
|
10
|
-
- **Dynamic Port Management**: Add or remove listening ports at runtime without restart
|
|
11
|
-
- **Security Features**: Route-specific IP allowlists, blocklists, connection limits, and authentication
|
|
12
|
-
- **NFTables Integration**: High-performance kernel-level packet forwarding with Linux NFTables
|
|
13
|
-
- **Socket Handlers**: Custom socket handling for specialized protocols and use cases
|
|
14
|
-
- **Multiple Targets**: Load balancing and failover with support for multiple upstream targets
|
|
5
|
+
## 🎯 What is SmartProxy?
|
|
15
6
|
|
|
16
|
-
|
|
7
|
+
SmartProxy is a modern, production-ready proxy solution that brings order to the chaos of traffic management. Whether you're building microservices, deploying edge infrastructure, or need a battle-tested reverse proxy, SmartProxy has you covered.
|
|
17
8
|
|
|
18
|
-
|
|
9
|
+
### ⚡ Key Features
|
|
19
10
|
|
|
20
|
-
|
|
21
|
-
/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
│ │ └── ... # Other handlers
|
|
31
|
-
│ ├── /config # Configuration models
|
|
32
|
-
│ └── /factory # Factory for creating handlers
|
|
33
|
-
├── /proxies # Different proxy implementations
|
|
34
|
-
│ ├── /smart-proxy # SmartProxy implementation
|
|
35
|
-
│ │ ├── /models # SmartProxy-specific interfaces
|
|
36
|
-
│ │ │ ├── route-types.ts # Route-based configuration types
|
|
37
|
-
│ │ │ └── interfaces.ts # SmartProxy interfaces
|
|
38
|
-
│ │ ├── certificate-manager.ts # SmartCertManager
|
|
39
|
-
│ │ ├── cert-store.ts # Certificate file storage
|
|
40
|
-
│ │ ├── route-helpers.ts # Helper functions for creating routes
|
|
41
|
-
│ │ ├── route-manager.ts # Route management system
|
|
42
|
-
│ │ ├── smart-proxy.ts # Main SmartProxy class
|
|
43
|
-
│ │ └── ... # Supporting classes
|
|
44
|
-
│ ├── /http-proxy # HttpProxy implementation (HTTP/HTTPS handling)
|
|
45
|
-
│ └── /nftables-proxy # NfTablesProxy implementation
|
|
46
|
-
├── /tls # TLS-specific functionality
|
|
47
|
-
│ ├── /sni # SNI handling components
|
|
48
|
-
│ └── /alerts # TLS alerts system
|
|
49
|
-
└── /routing # Routing functionality
|
|
50
|
-
└── /router # HTTP routing system
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Main Components
|
|
11
|
+
- **🔀 Unified Route-Based Configuration** - Clean match/action patterns for intuitive traffic routing
|
|
12
|
+
- **🔒 Automatic SSL/TLS with Let's Encrypt** - Zero-config HTTPS with automatic certificate provisioning
|
|
13
|
+
- **🎯 Flexible Matching Patterns** - Route by port, domain, path, client IP, TLS version, or custom logic
|
|
14
|
+
- **🚄 High-Performance Forwarding** - Choose between user-space or kernel-level (NFTables) forwarding
|
|
15
|
+
- **⚖️ Built-in Load Balancing** - Distribute traffic across multiple backends with health checks
|
|
16
|
+
- **🛡️ Enterprise Security** - IP filtering, rate limiting, authentication, and connection limits
|
|
17
|
+
- **🔌 WebSocket Support** - First-class WebSocket proxying with ping/pong management
|
|
18
|
+
- **🎮 Custom Socket Handlers** - Implement any protocol with full socket control
|
|
19
|
+
- **📊 Dynamic Port Management** - Add/remove ports at runtime without restarts
|
|
20
|
+
- **🔧 Protocol Detection** - Smart protocol detection for mixed-mode operation
|
|
54
21
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
- **SmartProxy** (`ts/proxies/smart-proxy/smart-proxy.ts`)
|
|
58
|
-
The central unified API for all proxy needs, featuring:
|
|
59
|
-
- Route-based configuration with match/action pattern
|
|
60
|
-
- Flexible matching criteria (ports, domains, paths, client IPs)
|
|
61
|
-
- Multiple action types (forward, redirect, block, socket-handler)
|
|
62
|
-
- Automatic certificate management
|
|
63
|
-
- Advanced security controls
|
|
64
|
-
- Custom socket handling capabilities
|
|
65
|
-
- Load balancing with multiple targets
|
|
66
|
-
|
|
67
|
-
### Helper Functions
|
|
22
|
+
## 📦 Installation
|
|
68
23
|
|
|
69
|
-
- **createHttpRoute**, **createHttpsTerminateRoute**, **createHttpsPassthroughRoute**
|
|
70
|
-
Helper functions to create different route configurations with clean syntax
|
|
71
|
-
- **createHttpToHttpsRedirect**
|
|
72
|
-
Helper function for HTTP to HTTPS redirects using socket handlers
|
|
73
|
-
- **createLoadBalancerRoute**, **createCompleteHttpsServer**
|
|
74
|
-
Helper functions for complex configurations
|
|
75
|
-
- **createSocketHandlerRoute**, **SocketHandlers**
|
|
76
|
-
Helper functions for custom socket handling
|
|
77
|
-
- **createNfTablesRoute**, **createNfTablesTerminateRoute**, **createCompleteNfTablesHttpsServer**
|
|
78
|
-
Helper functions for NFTables-based high-performance kernel-level routing
|
|
79
|
-
- **createPortMappingRoute**, **createOffsetPortMappingRoute**, **createDynamicRoute**, **createSmartLoadBalancer**
|
|
80
|
-
Helper functions for dynamic routing and port mapping
|
|
81
|
-
- **createApiGatewayRoute**, **addRateLimiting**, **addBasicAuth**, **addJwtAuth**
|
|
82
|
-
Helper functions for API gateway features and authentication
|
|
83
|
-
|
|
84
|
-
### Specialized Components
|
|
85
|
-
|
|
86
|
-
- **HttpProxy** (`ts/proxies/http-proxy/http-proxy.ts`)
|
|
87
|
-
HTTP/HTTPS reverse proxy with TLS termination and WebSocket support
|
|
88
|
-
- **NfTablesProxy** (`ts/proxies/nftables-proxy/nftables-proxy.ts`)
|
|
89
|
-
Low-level port forwarding using nftables NAT rules
|
|
90
|
-
- **SniHandler** (`ts/tls/sni/sni-handler.ts`)
|
|
91
|
-
Utilities for SNI extraction from TLS handshakes
|
|
92
|
-
|
|
93
|
-
### Core Utilities
|
|
94
|
-
|
|
95
|
-
- **ValidationUtils** (`ts/core/utils/validation-utils.ts`)
|
|
96
|
-
Domain, port, and configuration validation
|
|
97
|
-
- **IpUtils** (`ts/core/utils/ip-utils.ts`)
|
|
98
|
-
IP address validation and filtering with glob patterns
|
|
99
|
-
|
|
100
|
-
### Interfaces and Types
|
|
101
|
-
|
|
102
|
-
- `IRouteConfig`, `IRouteMatch`, `IRouteAction` (`ts/proxies/smart-proxy/models/route-types.ts`)
|
|
103
|
-
- `IRoutedSmartProxyOptions` (`ts/proxies/smart-proxy/models/route-types.ts`)
|
|
104
|
-
- `IHttpProxyOptions` (`ts/proxies/http-proxy/models/types.ts`)
|
|
105
|
-
- `INfTableProxySettings` (`ts/proxies/nftables-proxy/models/interfaces.ts`)
|
|
106
|
-
|
|
107
|
-
## Installation
|
|
108
|
-
Install via npm:
|
|
109
24
|
```bash
|
|
110
25
|
npm install @push.rocks/smartproxy
|
|
111
26
|
```
|
|
112
27
|
|
|
113
|
-
## Quick Start
|
|
28
|
+
## 🚀 Quick Start
|
|
114
29
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
**⚠️ Breaking Change in v20.0.0**: The route action configuration has changed from single `target` to `targets` array to support multiple upstream targets for load balancing and failover.
|
|
30
|
+
Let's get you up and running in 30 seconds:
|
|
118
31
|
|
|
119
32
|
```typescript
|
|
120
|
-
import {
|
|
121
|
-
SmartProxy,
|
|
122
|
-
createHttpRoute,
|
|
123
|
-
createHttpsTerminateRoute,
|
|
124
|
-
createHttpsPassthroughRoute,
|
|
125
|
-
createHttpToHttpsRedirect,
|
|
126
|
-
createCompleteHttpsServer,
|
|
127
|
-
createLoadBalancerRoute,
|
|
128
|
-
createApiRoute,
|
|
129
|
-
createWebSocketRoute,
|
|
130
|
-
createSocketHandlerRoute,
|
|
131
|
-
createNfTablesRoute,
|
|
132
|
-
createNfTablesTerminateRoute,
|
|
133
|
-
createCompleteNfTablesHttpsServer,
|
|
134
|
-
createPortMappingRoute,
|
|
135
|
-
createOffsetPortMappingRoute,
|
|
136
|
-
createDynamicRoute,
|
|
137
|
-
createSmartLoadBalancer,
|
|
138
|
-
createApiGatewayRoute,
|
|
139
|
-
addRateLimiting,
|
|
140
|
-
addBasicAuth,
|
|
141
|
-
addJwtAuth,
|
|
142
|
-
SocketHandlers
|
|
143
|
-
} from '@push.rocks/smartproxy';
|
|
33
|
+
import { SmartProxy, createCompleteHttpsServer } from '@push.rocks/smartproxy';
|
|
144
34
|
|
|
145
|
-
// Create a
|
|
35
|
+
// Create a proxy with automatic HTTPS
|
|
146
36
|
const proxy = new SmartProxy({
|
|
147
|
-
// Global ACME settings for all routes with certificate: 'auto'
|
|
148
37
|
acme: {
|
|
149
|
-
email: 'ssl@example.com', //
|
|
150
|
-
useProduction:
|
|
151
|
-
renewThresholdDays: 30, // Renew 30 days before expiry
|
|
152
|
-
port: 80, // Port for HTTP-01 challenges (use 8080 for non-privileged)
|
|
153
|
-
autoRenew: true, // Enable automatic renewal
|
|
154
|
-
renewCheckIntervalHours: 24 // Check for renewals daily
|
|
38
|
+
email: 'ssl@example.com', // Your email for Let's Encrypt
|
|
39
|
+
useProduction: true // Use Let's Encrypt production servers
|
|
155
40
|
},
|
|
156
|
-
|
|
157
|
-
// Define all your routing rules in a single array
|
|
158
41
|
routes: [
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
certificate: 'auto' //
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
// HTTPS passthrough for legacy systems
|
|
168
|
-
createHttpsPassthroughRoute('legacy.example.com', { host: '192.168.1.10', port: 443 }),
|
|
169
|
-
|
|
170
|
-
// Redirect HTTP to HTTPS for all domains and subdomains
|
|
171
|
-
createHttpToHttpsRedirect(['example.com', '*.example.com']),
|
|
172
|
-
|
|
173
|
-
// Complete HTTPS server (creates both HTTPS route and HTTP redirect)
|
|
174
|
-
...createCompleteHttpsServer('complete.example.com', { host: 'localhost', port: 3000 }, {
|
|
175
|
-
certificate: 'auto'
|
|
176
|
-
}),
|
|
177
|
-
|
|
178
|
-
// API route with CORS headers
|
|
179
|
-
createApiRoute('api.service.com', '/v1', { host: 'api-backend', port: 8081 }, {
|
|
180
|
-
useTls: true,
|
|
181
|
-
certificate: 'auto',
|
|
182
|
-
addCorsHeaders: true
|
|
183
|
-
}),
|
|
184
|
-
|
|
185
|
-
// WebSocket route for real-time communication
|
|
186
|
-
createWebSocketRoute('ws.example.com', '/socket', { host: 'socket-server', port: 8082 }, {
|
|
187
|
-
useTls: true,
|
|
188
|
-
certificate: 'auto',
|
|
189
|
-
pingInterval: 30000
|
|
190
|
-
}),
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
// Load balancer with multiple backend servers
|
|
194
|
-
createLoadBalancerRoute(
|
|
195
|
-
'app.example.com',
|
|
196
|
-
['192.168.1.10', '192.168.1.11', '192.168.1.12'],
|
|
197
|
-
8080,
|
|
198
|
-
{
|
|
199
|
-
tls: {
|
|
200
|
-
mode: 'terminate',
|
|
201
|
-
certificate: 'auto'
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
),
|
|
205
|
-
|
|
206
|
-
// Custom socket handler for specialized protocols
|
|
207
|
-
createSocketHandlerRoute('telnet.example.com', 23, SocketHandlers.lineProtocol((line, socket) => {
|
|
208
|
-
console.log('Received:', line);
|
|
209
|
-
socket.write(`Echo: ${line}\n`);
|
|
210
|
-
})),
|
|
211
|
-
|
|
212
|
-
// High-performance NFTables route (requires root/sudo)
|
|
213
|
-
createNfTablesRoute('fast.example.com', { host: 'backend-server', port: 8080 }, {
|
|
214
|
-
ports: 80,
|
|
215
|
-
protocol: 'tcp',
|
|
216
|
-
preserveSourceIP: true,
|
|
217
|
-
ipAllowList: ['10.0.0.*']
|
|
218
|
-
}),
|
|
219
|
-
|
|
220
|
-
// NFTables HTTPS termination for ultra-fast TLS handling
|
|
221
|
-
createNfTablesTerminateRoute('secure-fast.example.com', { host: 'backend-ssl', port: 443 }, {
|
|
222
|
-
ports: 443,
|
|
223
|
-
certificate: 'auto',
|
|
224
|
-
maxRate: '100mbps'
|
|
225
|
-
}),
|
|
226
|
-
|
|
227
|
-
// Route with security configuration
|
|
228
|
-
{
|
|
229
|
-
name: 'secure-admin',
|
|
230
|
-
match: {
|
|
231
|
-
ports: 443,
|
|
232
|
-
domains: 'admin.example.com'
|
|
233
|
-
},
|
|
234
|
-
action: {
|
|
235
|
-
type: 'forward',
|
|
236
|
-
targets: [{ host: 'localhost', port: 8080 }], // Note: targets is an array
|
|
237
|
-
tls: {
|
|
238
|
-
mode: 'terminate',
|
|
239
|
-
certificate: 'auto'
|
|
240
|
-
}
|
|
241
|
-
},
|
|
242
|
-
security: {
|
|
243
|
-
ipAllowList: ['10.0.0.*', '192.168.1.*'],
|
|
244
|
-
ipBlockList: ['192.168.1.100'],
|
|
245
|
-
maxConnections: 100
|
|
246
|
-
}
|
|
247
|
-
}
|
|
42
|
+
// Complete HTTPS setup with one line
|
|
43
|
+
...createCompleteHttpsServer('app.example.com', {
|
|
44
|
+
host: 'localhost',
|
|
45
|
+
port: 3000
|
|
46
|
+
}, {
|
|
47
|
+
certificate: 'auto' // Magic! 🎩
|
|
48
|
+
})
|
|
248
49
|
]
|
|
249
50
|
});
|
|
250
51
|
|
|
251
|
-
// Start the proxy
|
|
252
52
|
await proxy.start();
|
|
253
|
-
|
|
254
|
-
// Dynamically add new routes later
|
|
255
|
-
await proxy.updateRoutes([
|
|
256
|
-
...proxy.settings.routes,
|
|
257
|
-
createHttpsTerminateRoute('new-domain.com', { host: 'localhost', port: 9000 }, {
|
|
258
|
-
certificate: 'auto'
|
|
259
|
-
})
|
|
260
|
-
]);
|
|
261
|
-
|
|
262
|
-
// Dynamically add or remove port listeners
|
|
263
|
-
await proxy.addListeningPort(8081);
|
|
264
|
-
await proxy.removeListeningPort(8081);
|
|
265
|
-
console.log('Currently listening on ports:', proxy.getListeningPorts());
|
|
266
|
-
|
|
267
|
-
// Later, gracefully shut down
|
|
268
|
-
await proxy.stop();
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
## Route-Based Configuration System
|
|
272
|
-
|
|
273
|
-
SmartProxy uses a unified route configuration system based on the `IRouteConfig` interface. This system follows a match/action pattern that makes routing more powerful, flexible, and declarative.
|
|
274
|
-
|
|
275
|
-
### IRouteConfig Interface
|
|
276
|
-
|
|
277
|
-
The `IRouteConfig` interface is the core building block of SmartProxy's configuration system. Each route definition consists of match criteria and an action to perform on matched traffic:
|
|
278
|
-
|
|
279
|
-
```typescript
|
|
280
|
-
interface IRouteConfig {
|
|
281
|
-
// What traffic to match (required)
|
|
282
|
-
match: IRouteMatch;
|
|
283
|
-
|
|
284
|
-
// What to do with matched traffic (required)
|
|
285
|
-
action: IRouteAction;
|
|
286
|
-
|
|
287
|
-
// Security configuration (optional)
|
|
288
|
-
security?: IRouteSecurity;
|
|
289
|
-
|
|
290
|
-
// Metadata (all optional)
|
|
291
|
-
name?: string; // Human-readable name for this route
|
|
292
|
-
description?: string; // Description of the route's purpose
|
|
293
|
-
priority?: number; // Controls matching order (higher = matched first)
|
|
294
|
-
tags?: string[]; // Arbitrary tags for categorization
|
|
295
|
-
enabled?: boolean; // Whether the route is active (default: true)
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
#### Match Criteria (IRouteMatch)
|
|
300
|
-
|
|
301
|
-
The `match` property defines criteria for identifying which incoming traffic should be handled by this route:
|
|
302
|
-
|
|
303
|
-
```typescript
|
|
304
|
-
interface IRouteMatch {
|
|
305
|
-
// Port(s) to match
|
|
306
|
-
ports: number | number[] | string; // Single port, array, or range like '8000-8999'
|
|
307
|
-
|
|
308
|
-
// Domain matching (optional - if not specified, matches all domains)
|
|
309
|
-
domains?: string | string[]; // Exact domains or patterns with wildcards
|
|
310
|
-
|
|
311
|
-
// Path matching (optional)
|
|
312
|
-
path?: string; // URL path pattern (supports wildcards)
|
|
313
|
-
|
|
314
|
-
// Client IP matching (optional)
|
|
315
|
-
clientIp?: string | string[]; // IP addresses or CIDR ranges
|
|
316
|
-
|
|
317
|
-
// Protocol matching (optional)
|
|
318
|
-
protocol?: 'tcp' | 'udp' | 'http' | 'https' | 'ws' | 'wss';
|
|
319
|
-
|
|
320
|
-
// TLS version matching (optional)
|
|
321
|
-
tlsVersion?: string | string[]; // e.g., ['TLSv1.2', 'TLSv1.3']
|
|
322
|
-
|
|
323
|
-
// Custom matcher function (optional)
|
|
324
|
-
customMatcher?: (context: IRouteContext) => boolean | Promise<boolean>;
|
|
325
|
-
}
|
|
53
|
+
console.log('🚀 Proxy running with automatic HTTPS!');
|
|
326
54
|
```
|
|
327
55
|
|
|
328
|
-
|
|
329
|
-
- Exact match: `example.com`
|
|
330
|
-
- Wildcard subdomain: `*.example.com`
|
|
331
|
-
- Multiple domains: `['example.com', '*.example.com', 'example.org']`
|
|
332
|
-
- All domains: omit the `domains` field
|
|
333
|
-
|
|
334
|
-
**Path Matching Patterns:**
|
|
335
|
-
- Exact path: `/api/users`
|
|
336
|
-
- Path prefix with wildcard: `/api/*`
|
|
337
|
-
- Path with parameter: `/api/users/:id`
|
|
338
|
-
- Multiple path segments: `/api/*/details`
|
|
56
|
+
## 📚 Core Concepts
|
|
339
57
|
|
|
340
|
-
|
|
58
|
+
### 🏗️ Route-Based Architecture
|
|
341
59
|
|
|
342
|
-
|
|
60
|
+
SmartProxy uses a powerful match/action pattern that makes routing predictable and maintainable:
|
|
343
61
|
|
|
344
|
-
```typescript
|
|
345
|
-
interface IRouteAction {
|
|
346
|
-
// Action type (required)
|
|
347
|
-
type: 'forward' | 'redirect' | 'block' | 'socket-handler';
|
|
348
|
-
|
|
349
|
-
// For 'forward' type - array of upstream targets
|
|
350
|
-
targets?: IRouteTarget[];
|
|
351
|
-
|
|
352
|
-
// For 'redirect' type
|
|
353
|
-
redirectUrl?: string; // URL template with placeholders
|
|
354
|
-
redirectCode?: number; // HTTP status code (301, 302, etc.)
|
|
355
|
-
|
|
356
|
-
// For 'socket-handler' type
|
|
357
|
-
socketHandler?: (socket: net.Socket, context: IRouteContext) => void | Promise<void>;
|
|
358
|
-
|
|
359
|
-
// TLS configuration (optional)
|
|
360
|
-
tls?: IRouteTls;
|
|
361
|
-
|
|
362
|
-
// WebSocket configuration (optional)
|
|
363
|
-
websocket?: {
|
|
364
|
-
enabled: boolean;
|
|
365
|
-
pingInterval?: number; // Milliseconds between pings
|
|
366
|
-
pingTimeout?: number; // Milliseconds to wait for pong
|
|
367
|
-
};
|
|
368
|
-
|
|
369
|
-
// Headers manipulation (optional)
|
|
370
|
-
headers?: {
|
|
371
|
-
request?: Record<string, string>; // Headers to add to requests
|
|
372
|
-
response?: Record<string, string>; // Headers to add to responses
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
**Forward Action with Multiple Targets:**
|
|
378
|
-
```typescript
|
|
379
|
-
{
|
|
380
|
-
type: 'forward',
|
|
381
|
-
targets: [
|
|
382
|
-
{ host: 'backend1.example.com', port: 8080 },
|
|
383
|
-
{ host: 'backend2.example.com', port: 8080 },
|
|
384
|
-
{ host: 'backend3.example.com', port: 8080 }
|
|
385
|
-
]
|
|
386
|
-
}
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
**Redirect Action:**
|
|
390
|
-
```typescript
|
|
391
|
-
{
|
|
392
|
-
type: 'redirect',
|
|
393
|
-
redirectUrl: 'https://{domain}/{path}', // Placeholders: {domain}, {path}, {clientIp}
|
|
394
|
-
redirectCode: 301
|
|
395
|
-
}
|
|
396
|
-
```
|
|
397
|
-
|
|
398
|
-
**Socket Handler Action:**
|
|
399
|
-
```typescript
|
|
400
|
-
{
|
|
401
|
-
type: 'socket-handler',
|
|
402
|
-
socketHandler: (socket, context) => {
|
|
403
|
-
// Custom logic for handling the socket
|
|
404
|
-
socket.write('Hello from custom handler\n');
|
|
405
|
-
socket.end();
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
### Route Examples
|
|
411
|
-
|
|
412
|
-
#### Basic HTTP Forwarding
|
|
413
|
-
```typescript
|
|
414
|
-
{
|
|
415
|
-
match: {
|
|
416
|
-
ports: 80,
|
|
417
|
-
domains: 'api.example.com'
|
|
418
|
-
},
|
|
419
|
-
action: {
|
|
420
|
-
type: 'forward',
|
|
421
|
-
targets: [{ host: 'localhost', port: 3000 }]
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
#### HTTPS with TLS Termination and Load Balancing
|
|
427
|
-
```typescript
|
|
428
|
-
{
|
|
429
|
-
match: {
|
|
430
|
-
ports: 443,
|
|
431
|
-
domains: ['secure.example.com', '*.secure.example.com']
|
|
432
|
-
},
|
|
433
|
-
action: {
|
|
434
|
-
type: 'forward',
|
|
435
|
-
targets: [
|
|
436
|
-
{ host: '10.0.0.10', port: 8080 },
|
|
437
|
-
{ host: '10.0.0.11', port: 8080 },
|
|
438
|
-
{ host: '10.0.0.12', port: 8080 }
|
|
439
|
-
],
|
|
440
|
-
tls: {
|
|
441
|
-
mode: 'terminate',
|
|
442
|
-
certificate: 'auto' // Automatic Let's Encrypt certificate
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
#### WebSocket Route
|
|
449
|
-
```typescript
|
|
450
|
-
{
|
|
451
|
-
match: {
|
|
452
|
-
ports: 443,
|
|
453
|
-
domains: 'ws.example.com',
|
|
454
|
-
path: '/socket/*'
|
|
455
|
-
},
|
|
456
|
-
action: {
|
|
457
|
-
type: 'forward',
|
|
458
|
-
targets: [{ host: 'websocket-server', port: 8080 }],
|
|
459
|
-
tls: {
|
|
460
|
-
mode: 'terminate',
|
|
461
|
-
certificate: 'auto'
|
|
462
|
-
},
|
|
463
|
-
websocket: {
|
|
464
|
-
enabled: true,
|
|
465
|
-
pingInterval: 30000,
|
|
466
|
-
pingTimeout: 5000
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
#### API Gateway with Security
|
|
473
62
|
```typescript
|
|
474
63
|
{
|
|
475
64
|
match: {
|
|
@@ -479,473 +68,367 @@ interface IRouteAction {
|
|
|
479
68
|
},
|
|
480
69
|
action: {
|
|
481
70
|
type: 'forward',
|
|
482
|
-
targets: [{ host: '
|
|
483
|
-
tls: {
|
|
484
|
-
mode: 'terminate',
|
|
485
|
-
certificate: 'auto'
|
|
486
|
-
},
|
|
487
|
-
headers: {
|
|
488
|
-
request: {
|
|
489
|
-
'X-API-Version': 'v1',
|
|
490
|
-
'X-Real-IP': '{clientIp}'
|
|
491
|
-
},
|
|
492
|
-
response: {
|
|
493
|
-
'Access-Control-Allow-Origin': '*',
|
|
494
|
-
'X-Powered-By': 'SmartProxy'
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
},
|
|
498
|
-
security: {
|
|
499
|
-
ipAllowList: ['10.0.0.0/8', '172.16.0.0/12'],
|
|
500
|
-
rateLimit: {
|
|
501
|
-
maxRequests: 100,
|
|
502
|
-
windowMs: 60000
|
|
503
|
-
},
|
|
504
|
-
authentication: {
|
|
505
|
-
type: 'basic',
|
|
506
|
-
realm: 'API Access',
|
|
507
|
-
users: {
|
|
508
|
-
'apiuser': 'hashedpassword'
|
|
509
|
-
}
|
|
510
|
-
}
|
|
71
|
+
targets: [{ host: 'backend', port: 8080 }],
|
|
72
|
+
tls: { mode: 'terminate', certificate: 'auto' }
|
|
511
73
|
}
|
|
512
74
|
}
|
|
513
75
|
```
|
|
514
76
|
|
|
515
|
-
|
|
77
|
+
Every route has:
|
|
78
|
+
- **Match criteria** - What traffic to capture
|
|
79
|
+
- **Action** - What to do with it
|
|
80
|
+
- **Security** (optional) - Access controls and limits
|
|
81
|
+
- **Metadata** (optional) - Name, priority, tags
|
|
516
82
|
|
|
517
|
-
|
|
83
|
+
## 💡 Common Use Cases
|
|
518
84
|
|
|
519
|
-
###
|
|
520
|
-
- Linux kernel with NFTables support
|
|
521
|
-
- Root/sudo privileges
|
|
522
|
-
- `nft` command-line tool installed
|
|
85
|
+
### 🌐 Simple HTTP to HTTPS Redirect
|
|
523
86
|
|
|
524
|
-
### NFTables Route Example
|
|
525
87
|
```typescript
|
|
526
|
-
|
|
527
|
-
createNfTablesRoute('fast.example.com', { host: 'backend', port: 8080 }, {
|
|
528
|
-
ports: 80,
|
|
529
|
-
protocol: 'tcp',
|
|
530
|
-
preserveSourceIP: true
|
|
531
|
-
})
|
|
532
|
-
|
|
533
|
-
// NFTables with TLS termination
|
|
534
|
-
createNfTablesTerminateRoute('secure-fast.example.com', { host: 'backend', port: 8080 }, {
|
|
535
|
-
ports: 443,
|
|
536
|
-
certificate: 'auto',
|
|
537
|
-
maxRate: '100mbps'
|
|
538
|
-
})
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
## Socket Handlers
|
|
88
|
+
import { SmartProxy, createHttpToHttpsRedirect } from '@push.rocks/smartproxy';
|
|
542
89
|
|
|
543
|
-
|
|
90
|
+
const proxy = new SmartProxy({
|
|
91
|
+
routes: [
|
|
92
|
+
// Redirect all HTTP traffic to HTTPS
|
|
93
|
+
createHttpToHttpsRedirect(['example.com', '*.example.com'])
|
|
94
|
+
]
|
|
95
|
+
});
|
|
96
|
+
```
|
|
544
97
|
|
|
545
|
-
###
|
|
98
|
+
### ⚖️ Load Balancer with Health Checks
|
|
546
99
|
|
|
547
100
|
```typescript
|
|
548
|
-
|
|
549
|
-
createSocketHandlerRoute('echo.example.com', 7, SocketHandlers.echo)
|
|
550
|
-
|
|
551
|
-
// HTTP redirect
|
|
552
|
-
createHttpToHttpsRedirect('example.com')
|
|
553
|
-
|
|
554
|
-
// Line-based protocol
|
|
555
|
-
createSocketHandlerRoute('telnet.example.com', 23, SocketHandlers.lineProtocol((line, socket) => {
|
|
556
|
-
socket.write(`You said: ${line}\n`);
|
|
557
|
-
}))
|
|
558
|
-
|
|
559
|
-
// HTTP server for custom logic
|
|
560
|
-
createSocketHandlerRoute('custom.example.com', 8080, SocketHandlers.httpServer((req, res) => {
|
|
561
|
-
if (req.url === '/health') {
|
|
562
|
-
res.status(200);
|
|
563
|
-
res.send('OK');
|
|
564
|
-
} else {
|
|
565
|
-
res.status(404);
|
|
566
|
-
res.send('Not Found');
|
|
567
|
-
}
|
|
568
|
-
res.end();
|
|
569
|
-
}))
|
|
101
|
+
import { createLoadBalancerRoute } from '@push.rocks/smartproxy';
|
|
570
102
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
103
|
+
const route = createLoadBalancerRoute(
|
|
104
|
+
'app.example.com',
|
|
105
|
+
[
|
|
106
|
+
{ host: 'server1.internal', port: 8080 },
|
|
107
|
+
{ host: 'server2.internal', port: 8080 },
|
|
108
|
+
{ host: 'server3.internal', port: 8080 }
|
|
109
|
+
],
|
|
110
|
+
{
|
|
111
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
112
|
+
loadBalancing: {
|
|
113
|
+
algorithm: 'round-robin',
|
|
114
|
+
healthCheck: {
|
|
115
|
+
path: '/health',
|
|
116
|
+
interval: 30000,
|
|
117
|
+
timeout: 5000
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
);
|
|
576
122
|
```
|
|
577
123
|
|
|
578
|
-
###
|
|
124
|
+
### 🔌 WebSocket Proxy
|
|
579
125
|
|
|
580
126
|
```typescript
|
|
581
|
-
{
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
},
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
socket.write('Welcome to the custom protocol server\n');
|
|
592
|
-
|
|
593
|
-
socket.on('data', (data) => {
|
|
594
|
-
// Process incoming data
|
|
595
|
-
const command = data.toString().trim();
|
|
596
|
-
|
|
597
|
-
if (command === 'QUIT') {
|
|
598
|
-
socket.end('Goodbye\n');
|
|
599
|
-
} else {
|
|
600
|
-
socket.write(`Unknown command: ${command}\n`);
|
|
601
|
-
}
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
socket.on('error', (err) => {
|
|
605
|
-
console.error('Socket error:', err);
|
|
606
|
-
});
|
|
607
|
-
}
|
|
127
|
+
import { createWebSocketRoute } from '@push.rocks/smartproxy';
|
|
128
|
+
|
|
129
|
+
const route = createWebSocketRoute(
|
|
130
|
+
'ws.example.com',
|
|
131
|
+
{ host: 'websocket-server', port: 8080 },
|
|
132
|
+
{
|
|
133
|
+
path: '/socket',
|
|
134
|
+
useTls: true,
|
|
135
|
+
certificate: 'auto',
|
|
136
|
+
pingInterval: 30000 // Keep connections alive
|
|
608
137
|
}
|
|
609
|
-
|
|
138
|
+
);
|
|
610
139
|
```
|
|
611
140
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
SmartProxy allows you to dynamically add or remove listening ports without restarting:
|
|
141
|
+
### 🚦 API Gateway with Rate Limiting
|
|
615
142
|
|
|
616
143
|
```typescript
|
|
617
|
-
|
|
618
|
-
await proxy.addListeningPort(8443);
|
|
144
|
+
import { createApiGatewayRoute, addRateLimiting } from '@push.rocks/smartproxy';
|
|
619
145
|
|
|
620
|
-
|
|
621
|
-
|
|
146
|
+
let route = createApiGatewayRoute(
|
|
147
|
+
'api.example.com',
|
|
148
|
+
'/api',
|
|
149
|
+
{ host: 'api-backend', port: 8080 },
|
|
150
|
+
{
|
|
151
|
+
useTls: true,
|
|
152
|
+
certificate: 'auto',
|
|
153
|
+
addCorsHeaders: true
|
|
154
|
+
}
|
|
155
|
+
);
|
|
622
156
|
|
|
623
|
-
//
|
|
624
|
-
|
|
157
|
+
// Add rate limiting
|
|
158
|
+
route = addRateLimiting(route, {
|
|
159
|
+
maxRequests: 100,
|
|
160
|
+
window: 60, // seconds
|
|
161
|
+
keyBy: 'ip'
|
|
162
|
+
});
|
|
625
163
|
```
|
|
626
164
|
|
|
627
|
-
|
|
165
|
+
### 🎮 Custom Protocol Handler
|
|
628
166
|
|
|
629
|
-
SmartProxy includes automatic certificate management with Let's Encrypt support:
|
|
630
|
-
|
|
631
|
-
### Automatic Certificates (Let's Encrypt)
|
|
632
167
|
```typescript
|
|
633
|
-
{
|
|
634
|
-
action: {
|
|
635
|
-
tls: {
|
|
636
|
-
mode: 'terminate',
|
|
637
|
-
certificate: 'auto' // Automatic Let's Encrypt certificate
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
```
|
|
168
|
+
import { createSocketHandlerRoute, SocketHandlers } from '@push.rocks/smartproxy';
|
|
642
169
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
170
|
+
// Pre-built handlers
|
|
171
|
+
const echoRoute = createSocketHandlerRoute(
|
|
172
|
+
'echo.example.com',
|
|
173
|
+
7777,
|
|
174
|
+
SocketHandlers.echo
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
// Custom handler
|
|
178
|
+
const customRoute = createSocketHandlerRoute(
|
|
179
|
+
'custom.example.com',
|
|
180
|
+
9999,
|
|
181
|
+
async (socket, context) => {
|
|
182
|
+
console.log(`Connection from ${context.clientIp}`);
|
|
183
|
+
|
|
184
|
+
socket.write('Welcome to my custom protocol!\n');
|
|
185
|
+
|
|
186
|
+
socket.on('data', (data) => {
|
|
187
|
+
const command = data.toString().trim();
|
|
188
|
+
|
|
189
|
+
if (command === 'HELLO') {
|
|
190
|
+
socket.write('World!\n');
|
|
191
|
+
} else if (command === 'EXIT') {
|
|
192
|
+
socket.end('Goodbye!\n');
|
|
652
193
|
}
|
|
653
|
-
}
|
|
194
|
+
});
|
|
654
195
|
}
|
|
655
|
-
|
|
196
|
+
);
|
|
656
197
|
```
|
|
657
198
|
|
|
658
|
-
###
|
|
659
|
-
Certificates are automatically stored and managed:
|
|
660
|
-
- Auto certificates: `./certificates/{domain}/`
|
|
661
|
-
- Manual certificates: In-memory only
|
|
199
|
+
### ⚡ High-Performance NFTables Forwarding
|
|
662
200
|
|
|
663
|
-
|
|
201
|
+
For ultra-low latency, use kernel-level forwarding (Linux only, requires root):
|
|
664
202
|
|
|
665
|
-
### IP-Based Access Control
|
|
666
203
|
```typescript
|
|
667
|
-
{
|
|
668
|
-
security: {
|
|
669
|
-
ipAllowList: ['10.0.0.0/8', '192.168.*', '::1'],
|
|
670
|
-
ipBlockList: ['192.168.1.100', '10.0.0.0/24']
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
```
|
|
204
|
+
import { createNfTablesTerminateRoute } from '@push.rocks/smartproxy';
|
|
674
205
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
{
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
206
|
+
const route = createNfTablesTerminateRoute(
|
|
207
|
+
'fast.example.com',
|
|
208
|
+
{ host: 'backend', port: 8080 },
|
|
209
|
+
{
|
|
210
|
+
ports: 443,
|
|
211
|
+
certificate: 'auto',
|
|
212
|
+
preserveSourceIP: true,
|
|
213
|
+
maxRate: '1gbps'
|
|
681
214
|
}
|
|
682
|
-
|
|
215
|
+
);
|
|
683
216
|
```
|
|
684
217
|
|
|
685
|
-
|
|
218
|
+
## 🔧 Advanced Features
|
|
219
|
+
|
|
220
|
+
### 🎯 Dynamic Routing
|
|
221
|
+
|
|
222
|
+
Route traffic based on runtime conditions:
|
|
223
|
+
|
|
686
224
|
```typescript
|
|
687
225
|
{
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
226
|
+
match: {
|
|
227
|
+
ports: 443,
|
|
228
|
+
customMatcher: async (context) => {
|
|
229
|
+
// Route based on time of day
|
|
230
|
+
const hour = new Date().getHours();
|
|
231
|
+
return hour >= 9 && hour < 17; // Business hours only
|
|
692
232
|
}
|
|
233
|
+
},
|
|
234
|
+
action: {
|
|
235
|
+
type: 'forward',
|
|
236
|
+
targets: [{
|
|
237
|
+
host: (context) => {
|
|
238
|
+
// Dynamic host selection
|
|
239
|
+
return context.path.startsWith('/premium')
|
|
240
|
+
? 'premium-backend'
|
|
241
|
+
: 'standard-backend';
|
|
242
|
+
},
|
|
243
|
+
port: 8080
|
|
244
|
+
}]
|
|
693
245
|
}
|
|
694
246
|
}
|
|
695
247
|
```
|
|
696
248
|
|
|
697
|
-
###
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
{
|
|
701
|
-
security: {
|
|
702
|
-
authentication: {
|
|
703
|
-
type: 'basic',
|
|
704
|
-
realm: 'Protected Area',
|
|
705
|
-
users: {
|
|
706
|
-
'admin': 'hashedpassword'
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
}
|
|
249
|
+
### 🔒 Security Controls
|
|
250
|
+
|
|
251
|
+
Comprehensive security options per route:
|
|
711
252
|
|
|
712
|
-
|
|
253
|
+
```typescript
|
|
713
254
|
{
|
|
714
255
|
security: {
|
|
256
|
+
// IP-based access control
|
|
257
|
+
ipAllowList: ['10.0.0.0/8', '192.168.*'],
|
|
258
|
+
ipBlockList: ['192.168.1.100'],
|
|
259
|
+
|
|
260
|
+
// Connection limits
|
|
261
|
+
maxConnections: 1000,
|
|
262
|
+
maxConnectionsPerIp: 10,
|
|
263
|
+
|
|
264
|
+
// Rate limiting
|
|
265
|
+
rateLimit: {
|
|
266
|
+
maxRequests: 100,
|
|
267
|
+
windowMs: 60000
|
|
268
|
+
},
|
|
269
|
+
|
|
270
|
+
// Authentication
|
|
715
271
|
authentication: {
|
|
716
272
|
type: 'jwt',
|
|
717
|
-
secret:
|
|
273
|
+
secret: process.env.JWT_SECRET,
|
|
718
274
|
algorithms: ['HS256']
|
|
719
275
|
}
|
|
720
276
|
}
|
|
721
277
|
}
|
|
722
278
|
```
|
|
723
279
|
|
|
724
|
-
|
|
280
|
+
### 📊 Runtime Management
|
|
281
|
+
|
|
282
|
+
Control your proxy without restarts:
|
|
725
283
|
|
|
726
|
-
### Custom Route Matching
|
|
727
284
|
```typescript
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
285
|
+
// Add/remove ports dynamically
|
|
286
|
+
await proxy.addListeningPort(8443);
|
|
287
|
+
await proxy.removeListeningPort(8080);
|
|
288
|
+
|
|
289
|
+
// Update routes on the fly
|
|
290
|
+
await proxy.updateRoutes([...newRoutes]);
|
|
291
|
+
|
|
292
|
+
// Monitor status
|
|
293
|
+
const status = proxy.getStatus();
|
|
294
|
+
const metrics = proxy.getMetrics();
|
|
295
|
+
|
|
296
|
+
// Certificate management
|
|
297
|
+
await proxy.renewCertificate('example.com');
|
|
298
|
+
const certInfo = proxy.getCertificateInfo('example.com');
|
|
738
299
|
```
|
|
739
300
|
|
|
740
|
-
### Header Manipulation
|
|
301
|
+
### 🔄 Header Manipulation
|
|
302
|
+
|
|
303
|
+
Transform requests and responses:
|
|
304
|
+
|
|
741
305
|
```typescript
|
|
742
306
|
{
|
|
743
307
|
action: {
|
|
744
308
|
headers: {
|
|
745
309
|
request: {
|
|
746
|
-
'X-Real-IP': '{clientIp}',
|
|
747
|
-
'X-
|
|
748
|
-
'X-Custom
|
|
310
|
+
'X-Real-IP': '{clientIp}', // Template variables
|
|
311
|
+
'X-Request-ID': '{uuid}',
|
|
312
|
+
'X-Custom': 'value'
|
|
749
313
|
},
|
|
750
314
|
response: {
|
|
751
315
|
'X-Powered-By': 'SmartProxy',
|
|
752
|
-
'Strict-Transport-Security': 'max-age=31536000'
|
|
316
|
+
'Strict-Transport-Security': 'max-age=31536000',
|
|
317
|
+
'X-Frame-Options': 'DENY'
|
|
753
318
|
}
|
|
754
319
|
}
|
|
755
320
|
}
|
|
756
321
|
}
|
|
757
322
|
```
|
|
758
323
|
|
|
759
|
-
|
|
760
|
-
```typescript
|
|
761
|
-
{
|
|
762
|
-
action: {
|
|
763
|
-
type: 'forward',
|
|
764
|
-
targets: [
|
|
765
|
-
{
|
|
766
|
-
host: ['backend1.example.com', 'backend2.example.com'], // Round-robin
|
|
767
|
-
port: (context) => {
|
|
768
|
-
// Dynamic port based on path
|
|
769
|
-
return context.path.startsWith('/api/v1') ? 8081 : 8080;
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
]
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
```
|
|
324
|
+
## 🏛️ Architecture
|
|
776
325
|
|
|
777
|
-
|
|
326
|
+
SmartProxy is built with a modular, extensible architecture:
|
|
778
327
|
|
|
779
|
-
### Multi-Domain HTTPS Server with Redirects
|
|
780
|
-
```typescript
|
|
781
|
-
const proxy = new SmartProxy({
|
|
782
|
-
acme: {
|
|
783
|
-
email: 'admin@example.com',
|
|
784
|
-
useProduction: true
|
|
785
|
-
},
|
|
786
|
-
routes: [
|
|
787
|
-
// HTTPS routes
|
|
788
|
-
...['example.com', 'app.example.com', 'api.example.com'].map(domain =>
|
|
789
|
-
createHttpsTerminateRoute(domain, { host: 'localhost', port: 3000 }, {
|
|
790
|
-
certificate: 'auto'
|
|
791
|
-
})
|
|
792
|
-
),
|
|
793
|
-
|
|
794
|
-
// HTTP to HTTPS redirects
|
|
795
|
-
createHttpToHttpsRedirect(['example.com', '*.example.com'])
|
|
796
|
-
]
|
|
797
|
-
});
|
|
798
328
|
```
|
|
329
|
+
SmartProxy
|
|
330
|
+
├── 📋 Route Manager # Route matching and prioritization
|
|
331
|
+
├── 🔌 Port Manager # Dynamic port lifecycle
|
|
332
|
+
├── 🔒 Certificate Manager # ACME/Let's Encrypt automation
|
|
333
|
+
├── 🚦 Connection Manager # Connection pooling and limits
|
|
334
|
+
├── 📊 Metrics Collector # Performance monitoring
|
|
335
|
+
├── 🛡️ Security Manager # Access control and rate limiting
|
|
336
|
+
└── 🔧 Protocol Detectors # Smart protocol identification
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## 🎯 Route Configuration Reference
|
|
340
|
+
|
|
341
|
+
### Match Criteria
|
|
799
342
|
|
|
800
|
-
### API Gateway with Multiple Services
|
|
801
343
|
```typescript
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
{
|
|
812
|
-
match: {
|
|
813
|
-
ports: 443,
|
|
814
|
-
domains: 'api.example.com',
|
|
815
|
-
path: '/orders/*'
|
|
816
|
-
},
|
|
817
|
-
action: {
|
|
818
|
-
type: 'forward',
|
|
819
|
-
targets: [{ host: 'order-service', port: 8083 }],
|
|
820
|
-
tls: {
|
|
821
|
-
mode: 'terminate',
|
|
822
|
-
certificate: 'auto'
|
|
823
|
-
}
|
|
824
|
-
},
|
|
825
|
-
security: {
|
|
826
|
-
authentication: {
|
|
827
|
-
type: 'jwt',
|
|
828
|
-
secret: process.env.JWT_SECRET
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
]
|
|
833
|
-
});
|
|
344
|
+
interface IRouteMatch {
|
|
345
|
+
ports: number | number[] | string; // 80, [80, 443], '8000-8999'
|
|
346
|
+
domains?: string | string[]; // 'example.com', '*.example.com'
|
|
347
|
+
path?: string; // '/api/*', '/users/:id'
|
|
348
|
+
clientIp?: string | string[]; // '10.0.0.0/8', ['192.168.*']
|
|
349
|
+
protocol?: 'tcp' | 'udp' | 'http' | 'https' | 'ws' | 'wss';
|
|
350
|
+
tlsVersion?: string | string[]; // ['TLSv1.2', 'TLSv1.3']
|
|
351
|
+
customMatcher?: (context) => boolean; // Custom logic
|
|
352
|
+
}
|
|
834
353
|
```
|
|
835
354
|
|
|
836
|
-
###
|
|
355
|
+
### Action Types
|
|
356
|
+
|
|
837
357
|
```typescript
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
358
|
+
interface IRouteAction {
|
|
359
|
+
type: 'forward' | 'redirect' | 'block' | 'socket-handler';
|
|
360
|
+
|
|
361
|
+
// For 'forward'
|
|
362
|
+
targets?: Array<{
|
|
363
|
+
host: string | string[] | ((context) => string);
|
|
364
|
+
port: number | ((context) => number);
|
|
365
|
+
}>;
|
|
366
|
+
|
|
367
|
+
// For 'redirect'
|
|
368
|
+
redirectUrl?: string; // With {domain}, {path}, {clientIp} templates
|
|
369
|
+
redirectCode?: number; // 301, 302, etc.
|
|
370
|
+
|
|
371
|
+
// For 'socket-handler'
|
|
372
|
+
socketHandler?: (socket, context) => void | Promise<void>;
|
|
373
|
+
|
|
374
|
+
// TLS options
|
|
375
|
+
tls?: {
|
|
376
|
+
mode: 'terminate' | 'passthrough' | 'terminate-and-reencrypt';
|
|
377
|
+
certificate: 'auto' | { key: string; cert: string };
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
// WebSocket options
|
|
381
|
+
websocket?: {
|
|
382
|
+
enabled: boolean;
|
|
383
|
+
pingInterval?: number;
|
|
384
|
+
pingTimeout?: number;
|
|
385
|
+
};
|
|
386
|
+
}
|
|
864
387
|
```
|
|
865
388
|
|
|
866
|
-
## Troubleshooting
|
|
867
|
-
|
|
868
|
-
### Common Issues
|
|
389
|
+
## 🐛 Troubleshooting
|
|
869
390
|
|
|
870
|
-
|
|
871
|
-
- Ensure
|
|
872
|
-
-
|
|
873
|
-
-
|
|
874
|
-
-
|
|
391
|
+
### Certificate Issues
|
|
392
|
+
- ✅ Ensure domain points to your server
|
|
393
|
+
- ✅ Port 80 must be accessible for ACME challenges
|
|
394
|
+
- ✅ Check DNS propagation with `nslookup`
|
|
395
|
+
- ✅ Verify email in ACME configuration
|
|
875
396
|
|
|
876
|
-
|
|
877
|
-
-
|
|
878
|
-
-
|
|
879
|
-
-
|
|
880
|
-
-
|
|
397
|
+
### Connection Problems
|
|
398
|
+
- ✅ Check route priorities (higher = matched first)
|
|
399
|
+
- ✅ Verify security rules aren't blocking
|
|
400
|
+
- ✅ Test with `curl -v` for detailed output
|
|
401
|
+
- ✅ Enable debug mode for verbose logging
|
|
881
402
|
|
|
882
|
-
|
|
883
|
-
-
|
|
884
|
-
-
|
|
885
|
-
-
|
|
886
|
-
- Monitor
|
|
403
|
+
### Performance Tuning
|
|
404
|
+
- ✅ Use NFTables for high-traffic routes
|
|
405
|
+
- ✅ Enable connection pooling
|
|
406
|
+
- ✅ Adjust keep-alive settings
|
|
407
|
+
- ✅ Monitor with built-in metrics
|
|
887
408
|
|
|
888
409
|
### Debug Mode
|
|
889
|
-
Enable detailed logging:
|
|
890
410
|
```typescript
|
|
891
411
|
const proxy = new SmartProxy({
|
|
892
|
-
debug: true,
|
|
412
|
+
debug: true, // Enable verbose logging
|
|
893
413
|
routes: [...]
|
|
894
414
|
});
|
|
895
415
|
```
|
|
896
416
|
|
|
897
|
-
|
|
898
|
-
Test route matching:
|
|
899
|
-
```typescript
|
|
900
|
-
const matchedRoute = proxy.findMatchingRoute({
|
|
901
|
-
port: 443,
|
|
902
|
-
domain: 'example.com',
|
|
903
|
-
path: '/api/users',
|
|
904
|
-
clientIp: '192.168.1.100'
|
|
905
|
-
});
|
|
417
|
+
## 🚀 Migration from v20.x to v21.x
|
|
906
418
|
|
|
907
|
-
|
|
908
|
-
```
|
|
419
|
+
No breaking changes! v21.x adds enhanced socket cleanup, improved connection tracking, and better process exit handling.
|
|
909
420
|
|
|
910
|
-
##
|
|
421
|
+
## 🏆 Best Practices
|
|
911
422
|
|
|
912
|
-
|
|
423
|
+
1. **📝 Use Helper Functions** - They provide sensible defaults and prevent errors
|
|
424
|
+
2. **🎯 Set Route Priorities** - More specific routes should have higher priority
|
|
425
|
+
3. **🔒 Always Enable Security** - Use IP filtering and rate limiting for public services
|
|
426
|
+
4. **📊 Monitor Performance** - Use metrics to identify bottlenecks
|
|
427
|
+
5. **🔄 Regular Certificate Checks** - Monitor expiration and renewal status
|
|
428
|
+
6. **🛑 Graceful Shutdown** - Always call `proxy.stop()` for clean shutdown
|
|
429
|
+
7. **🎮 Test Your Routes** - Use the route testing utilities before production
|
|
913
430
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
**Before (v19.x):**
|
|
917
|
-
```typescript
|
|
918
|
-
{
|
|
919
|
-
action: {
|
|
920
|
-
type: 'forward',
|
|
921
|
-
target: { host: 'localhost', port: 8080 } // Single target
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
```
|
|
925
|
-
|
|
926
|
-
**After (v20.x):**
|
|
927
|
-
```typescript
|
|
928
|
-
{
|
|
929
|
-
action: {
|
|
930
|
-
type: 'forward',
|
|
931
|
-
targets: [{ host: 'localhost', port: 8080 }] // Array of targets
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
```
|
|
935
|
-
|
|
936
|
-
Helper functions have been updated to use the new format automatically.
|
|
937
|
-
|
|
938
|
-
## Best Practices
|
|
939
|
-
|
|
940
|
-
1. **Use Helper Functions**: They provide sensible defaults and reduce configuration errors
|
|
941
|
-
2. **Set Route Priorities**: Higher priority routes are matched first
|
|
942
|
-
3. **Use Specific Matches**: More specific routes should have higher priorities
|
|
943
|
-
4. **Enable Security Features**: Always use IP filtering and rate limiting for public services
|
|
944
|
-
5. **Monitor Performance**: Use debug logging and metrics to identify bottlenecks
|
|
945
|
-
6. **Regular Certificate Checks**: Monitor certificate expiration and renewal
|
|
946
|
-
7. **Graceful Shutdown**: Always call `proxy.stop()` for clean shutdown
|
|
947
|
-
|
|
948
|
-
## API Reference
|
|
431
|
+
## 📖 API Documentation
|
|
949
432
|
|
|
950
433
|
### SmartProxy Class
|
|
951
434
|
|
|
@@ -953,46 +436,56 @@ Helper functions have been updated to use the new format automatically.
|
|
|
953
436
|
class SmartProxy {
|
|
954
437
|
constructor(options: IRoutedSmartProxyOptions);
|
|
955
438
|
|
|
956
|
-
// Lifecycle
|
|
439
|
+
// Lifecycle
|
|
957
440
|
start(): Promise<void>;
|
|
958
441
|
stop(): Promise<void>;
|
|
959
442
|
|
|
960
|
-
// Route
|
|
443
|
+
// Route Management
|
|
961
444
|
updateRoutes(routes: IRouteConfig[]): Promise<void>;
|
|
962
445
|
addRoute(route: IRouteConfig): Promise<void>;
|
|
963
446
|
removeRoute(routeName: string): Promise<void>;
|
|
964
447
|
findMatchingRoute(context: Partial<IRouteContext>): IRouteConfig | null;
|
|
965
448
|
|
|
966
|
-
// Port
|
|
449
|
+
// Port Management
|
|
967
450
|
addListeningPort(port: number): Promise<void>;
|
|
968
451
|
removeListeningPort(port: number): Promise<void>;
|
|
969
452
|
getListeningPorts(): number[];
|
|
970
453
|
|
|
971
|
-
// Certificate
|
|
454
|
+
// Certificate Management
|
|
972
455
|
getCertificateInfo(domain: string): ICertificateInfo | null;
|
|
973
456
|
renewCertificate(domain: string): Promise<void>;
|
|
974
457
|
|
|
975
|
-
//
|
|
458
|
+
// Monitoring
|
|
976
459
|
getStatus(): IProxyStatus;
|
|
977
460
|
getMetrics(): IProxyMetrics;
|
|
978
461
|
}
|
|
979
462
|
```
|
|
980
463
|
|
|
981
|
-
###
|
|
982
|
-
|
|
983
|
-
See the TypeScript definitions in:
|
|
984
|
-
- `ts/proxies/smart-proxy/models/route-types.ts`
|
|
985
|
-
- `ts/proxies/smart-proxy/models/interfaces.ts`
|
|
986
|
-
|
|
987
|
-
## Contributing
|
|
464
|
+
### Helper Functions
|
|
988
465
|
|
|
989
|
-
|
|
466
|
+
All helper functions are fully typed and documented. Import them from the main package:
|
|
990
467
|
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
468
|
+
```typescript
|
|
469
|
+
import {
|
|
470
|
+
createHttpRoute,
|
|
471
|
+
createHttpsTerminateRoute,
|
|
472
|
+
createHttpsPassthroughRoute,
|
|
473
|
+
createHttpToHttpsRedirect,
|
|
474
|
+
createCompleteHttpsServer,
|
|
475
|
+
createLoadBalancerRoute,
|
|
476
|
+
createApiRoute,
|
|
477
|
+
createWebSocketRoute,
|
|
478
|
+
createSocketHandlerRoute,
|
|
479
|
+
createNfTablesRoute,
|
|
480
|
+
createPortMappingRoute,
|
|
481
|
+
createDynamicRoute,
|
|
482
|
+
createApiGatewayRoute,
|
|
483
|
+
addRateLimiting,
|
|
484
|
+
addBasicAuth,
|
|
485
|
+
addJwtAuth,
|
|
486
|
+
SocketHandlers
|
|
487
|
+
} from '@push.rocks/smartproxy';
|
|
488
|
+
```
|
|
996
489
|
|
|
997
490
|
## License and Legal Information
|
|
998
491
|
|