@push.rocks/smartproxy 17.0.0 → 18.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/core/utils/shared-security-manager.js +3 -3
- package/dist_ts/forwarding/handlers/base-handler.d.ts +5 -2
- package/dist_ts/forwarding/handlers/base-handler.js +12 -9
- package/dist_ts/forwarding/handlers/http-handler.js +8 -4
- package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +2 -2
- package/dist_ts/proxies/smart-proxy/models/route-types.d.ts +22 -29
- package/dist_ts/proxies/smart-proxy/models/route-types.js +1 -1
- package/dist_ts/proxies/smart-proxy/route-connection-handler.js +3 -3
- package/dist_ts/proxies/smart-proxy/route-manager.js +5 -5
- package/dist_ts/proxies/smart-proxy/security-manager.d.ts +7 -8
- package/dist_ts/proxies/smart-proxy/security-manager.js +8 -9
- package/package.json +1 -1
- package/readme.plan.md +133 -188
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/core/utils/shared-security-manager.ts +2 -2
- package/ts/forwarding/handlers/base-handler.ts +14 -8
- package/ts/forwarding/handlers/http-handler.ts +8 -3
- package/ts/proxies/smart-proxy/models/interfaces.ts +2 -2
- package/ts/proxies/smart-proxy/models/route-types.ts +31 -27
- package/ts/proxies/smart-proxy/route-connection-handler.ts +3 -3
- package/ts/proxies/smart-proxy/route-manager.ts +4 -4
- package/ts/proxies/smart-proxy/security-manager.ts +7 -8
|
@@ -25,16 +25,15 @@ export declare class SecurityManager {
|
|
|
25
25
|
*/
|
|
26
26
|
removeConnectionByIP(ip: string, connectionId: string): void;
|
|
27
27
|
/**
|
|
28
|
-
* Check if an IP is authorized using
|
|
28
|
+
* Check if an IP is authorized using security rules
|
|
29
29
|
*
|
|
30
30
|
* This method is used to determine if an IP is allowed to connect, based on security
|
|
31
|
-
* rules configured in the
|
|
32
|
-
* typically derived from
|
|
33
|
-
* DomainConfigManager.getEffectiveIPRules().
|
|
31
|
+
* rules configured in the route configuration. The allowed and blocked IPs are
|
|
32
|
+
* typically derived from route.security.ipAllowList and ipBlockList.
|
|
34
33
|
*
|
|
35
34
|
* @param ip - The IP address to check
|
|
36
|
-
* @param allowedIPs - Array of allowed IP patterns from
|
|
37
|
-
* @param blockedIPs - Array of blocked IP patterns from
|
|
35
|
+
* @param allowedIPs - Array of allowed IP patterns from security.ipAllowList
|
|
36
|
+
* @param blockedIPs - Array of blocked IP patterns from security.ipBlockList
|
|
38
37
|
* @returns true if IP is authorized, false if blocked
|
|
39
38
|
*/
|
|
40
39
|
isIPAuthorized(ip: string, allowedIPs: string[], blockedIPs?: string[]): boolean;
|
|
@@ -42,10 +41,10 @@ export declare class SecurityManager {
|
|
|
42
41
|
* Check if the IP matches any of the glob patterns from security configuration
|
|
43
42
|
*
|
|
44
43
|
* This method checks IP addresses against glob patterns and handles IPv4/IPv6 normalization.
|
|
45
|
-
* It's used to implement IP filtering based on the
|
|
44
|
+
* It's used to implement IP filtering based on the route.security configuration.
|
|
46
45
|
*
|
|
47
46
|
* @param ip - The IP address to check
|
|
48
|
-
* @param patterns - Array of glob patterns from
|
|
47
|
+
* @param patterns - Array of glob patterns from security.ipAllowList or ipBlockList
|
|
49
48
|
* @returns true if IP matches any pattern, false otherwise
|
|
50
49
|
*/
|
|
51
50
|
private isGlobIPMatch;
|
|
@@ -54,16 +54,15 @@ export class SecurityManager {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
|
-
* Check if an IP is authorized using
|
|
57
|
+
* Check if an IP is authorized using security rules
|
|
58
58
|
*
|
|
59
59
|
* This method is used to determine if an IP is allowed to connect, based on security
|
|
60
|
-
* rules configured in the
|
|
61
|
-
* typically derived from
|
|
62
|
-
* DomainConfigManager.getEffectiveIPRules().
|
|
60
|
+
* rules configured in the route configuration. The allowed and blocked IPs are
|
|
61
|
+
* typically derived from route.security.ipAllowList and ipBlockList.
|
|
63
62
|
*
|
|
64
63
|
* @param ip - The IP address to check
|
|
65
|
-
* @param allowedIPs - Array of allowed IP patterns from
|
|
66
|
-
* @param blockedIPs - Array of blocked IP patterns from
|
|
64
|
+
* @param allowedIPs - Array of allowed IP patterns from security.ipAllowList
|
|
65
|
+
* @param blockedIPs - Array of blocked IP patterns from security.ipBlockList
|
|
67
66
|
* @returns true if IP is authorized, false if blocked
|
|
68
67
|
*/
|
|
69
68
|
isIPAuthorized(ip, allowedIPs, blockedIPs = []) {
|
|
@@ -82,10 +81,10 @@ export class SecurityManager {
|
|
|
82
81
|
* Check if the IP matches any of the glob patterns from security configuration
|
|
83
82
|
*
|
|
84
83
|
* This method checks IP addresses against glob patterns and handles IPv4/IPv6 normalization.
|
|
85
|
-
* It's used to implement IP filtering based on the
|
|
84
|
+
* It's used to implement IP filtering based on the route.security configuration.
|
|
86
85
|
*
|
|
87
86
|
* @param ip - The IP address to check
|
|
88
|
-
* @param patterns - Array of glob patterns from
|
|
87
|
+
* @param patterns - Array of glob patterns from security.ipAllowList or ipBlockList
|
|
89
88
|
* @returns true if IP matches any pattern, false otherwise
|
|
90
89
|
*/
|
|
91
90
|
isGlobIPMatch(ip, patterns) {
|
|
@@ -146,4 +145,4 @@ export class SecurityManager {
|
|
|
146
145
|
this.connectionRateByIP.clear();
|
|
147
146
|
}
|
|
148
147
|
}
|
|
149
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
148
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHktbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Byb3hpZXMvc21hcnQtcHJveHkvc2VjdXJpdHktbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBRzVDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFJMUIsWUFBb0IsUUFBNEI7UUFBNUIsYUFBUSxHQUFSLFFBQVEsQ0FBb0I7UUFIeEMsb0JBQWUsR0FBNkIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUN0RCx1QkFBa0IsR0FBMEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUVYLENBQUM7SUFFcEQ7O09BRUc7SUFDSSxzQkFBc0IsQ0FBQyxFQUFVO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksbUJBQW1CLENBQUMsRUFBVTtRQUNuQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdkIsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztRQUV6QixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN2QyxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCw0REFBNEQ7UUFDNUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxJQUFJLEdBQUcsTUFB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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartproxy",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "18.0.0",
|
|
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.plan.md
CHANGED
|
@@ -1,201 +1,146 @@
|
|
|
1
|
-
# SmartProxy
|
|
1
|
+
# SmartProxy Interface Consolidation Plan
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
This document outlines a
|
|
5
|
+
This document outlines a plan to consolidate duplicate and inconsistent interfaces in the SmartProxy codebase, specifically the `IRouteSecurity` interface which is defined twice with different properties. This inconsistency caused issues with security checks for port forwarding. The goal is to unify these interfaces, use consistent property naming, and improve code maintainability.
|
|
6
|
+
|
|
7
|
+
## Problem Description
|
|
8
|
+
|
|
9
|
+
We currently have two separate `IRouteSecurity` interfaces defined in `ts/proxies/smart-proxy/models/route-types.ts`:
|
|
10
|
+
|
|
11
|
+
1. **First definition** (lines 116-122) - Used in IRouteAction:
|
|
12
|
+
```typescript
|
|
13
|
+
export interface IRouteSecurity {
|
|
14
|
+
allowedIps?: string[];
|
|
15
|
+
blockedIps?: string[];
|
|
16
|
+
maxConnections?: number;
|
|
17
|
+
authentication?: IRouteAuthentication;
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
2. **Second definition** (lines 253-272) - Used directly in IRouteConfig:
|
|
22
|
+
```typescript
|
|
23
|
+
export interface IRouteSecurity {
|
|
24
|
+
rateLimit?: IRouteRateLimit;
|
|
25
|
+
basicAuth?: {...};
|
|
26
|
+
jwtAuth?: {...};
|
|
27
|
+
ipAllowList?: string[];
|
|
28
|
+
ipBlockList?: string[];
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
This duplication with inconsistent naming (`allowedIps` vs `ipAllowList` and `blockedIps` vs `ipBlockList`) caused routing issues when IP security checks were used, as we had to implement a workaround to check both property names.
|
|
33
|
+
|
|
34
|
+
## Implementation Plan
|
|
35
|
+
|
|
36
|
+
### Phase 1: Interface Consolidation
|
|
37
|
+
|
|
38
|
+
1. **Create a unified interface definition:**
|
|
39
|
+
- Create one comprehensive `IRouteSecurity` interface that includes all properties
|
|
40
|
+
- Use consistent property naming (standardize on `ipAllowList` and `ipBlockList`)
|
|
41
|
+
- Add proper documentation for each property
|
|
42
|
+
- Remove the duplicate interface definition
|
|
43
|
+
|
|
44
|
+
2. **Update references to use the unified interface:**
|
|
45
|
+
- Update all code that references the old interface properties
|
|
46
|
+
- Update all configurations to use the new property names
|
|
47
|
+
- Ensure implementation in `route-manager.ts` uses the correct property names
|
|
48
|
+
|
|
49
|
+
### Phase 2: Code and Documentation Updates
|
|
50
|
+
|
|
51
|
+
1. **Update type usages and documentation:**
|
|
52
|
+
- Update all code that creates or uses security configurations
|
|
53
|
+
- Update documentation to reflect the new interface structure
|
|
54
|
+
- Add examples of the correct property usage
|
|
55
|
+
- Document the breaking change in changelog.md
|
|
56
|
+
|
|
57
|
+
2. **Add tests:**
|
|
58
|
+
- Update existing tests to use the new property names
|
|
59
|
+
- Add test cases for all security configuration scenarios
|
|
60
|
+
- Verify that port range configurations with security settings work correctly
|
|
61
|
+
|
|
62
|
+
## Implementation Steps
|
|
6
63
|
|
|
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
|
-
There are several redundant interfaces that could be simplified.
|
|
43
|
-
|
|
44
|
-
- **Action:** ✅
|
|
45
|
-
- ✅ Remove legacy type checking functions (`isLegacyOptions`, `isRoutedOptions`) in `/ts/proxies/smart-proxy/models/interfaces.ts`
|
|
46
|
-
- ✅ Update `ISmartProxyOptions` interface to remove obsolete properties
|
|
47
|
-
- ✅ Remove backward compatibility aliases like `IRoutedSmartProxyOptions`
|
|
48
|
-
- **Impact:** Medium - May break code that relies on these interfaces
|
|
49
|
-
- **Dependencies:** ✅ Update any code that references these interfaces
|
|
50
|
-
|
|
51
|
-
### 2.2 Consolidate Route Utilities
|
|
52
|
-
|
|
53
|
-
The route utilities are spread across multiple files with some overlapping functionality.
|
|
54
|
-
|
|
55
|
-
- **Action:**
|
|
56
|
-
- Consolidate route utilities into a single coherent structure
|
|
57
|
-
- Move common functions from route-utils.ts, route-patterns.ts into a single location
|
|
58
|
-
- Ensure consistent naming conventions for route utility functions
|
|
59
|
-
- **Impact:** Medium - Requires careful refactoring
|
|
60
|
-
- **Dependencies:** Update all references to these utilities
|
|
61
|
-
|
|
62
|
-
### 2.3 Clean Up Legacy Connection Handling ✅
|
|
63
|
-
|
|
64
|
-
The route-connection-handler.ts file contains legacy code and parameters kept for backward compatibility.
|
|
65
|
-
|
|
66
|
-
- **Action:** ✅
|
|
67
|
-
- ✅ Remove unused parameters and legacy comments from `setupDirectConnection` method
|
|
68
|
-
- ✅ Simplify connection handling logic by removing special cases for legacy configurations
|
|
69
|
-
- **Impact:** Medium - Requires careful testing to ensure no regressions
|
|
70
|
-
- **Dependencies:** ✅ Test with all current route configurations
|
|
71
|
-
|
|
72
|
-
## Phase 3: Code Modernization
|
|
73
|
-
|
|
74
|
-
### 3.1 Standardize on 'preserve' Port Handling ✅
|
|
75
|
-
|
|
76
|
-
Previously implemented changes to use `port: 'preserve'` instead of `preservePort: true` should be consistently applied.
|
|
77
|
-
|
|
78
|
-
- **Action:** ✅
|
|
79
|
-
- ✅ Ensure all code paths handle the 'preserve' value for port
|
|
80
|
-
- ✅ Remove any remaining references to preservePort in code and documentation
|
|
81
|
-
- **Impact:** Low - Already implemented in most places
|
|
82
|
-
- **Dependencies:** None
|
|
83
|
-
|
|
84
|
-
### 3.2 Normalize IPv6-Mapped IPv4 Addresses ✅
|
|
85
|
-
|
|
86
|
-
Implement consistent handling of IPv6-mapped IPv4 addresses throughout the codebase.
|
|
87
|
-
|
|
88
|
-
- **Action:** ✅
|
|
89
|
-
- ✅ Ensure any IP address comparisons consistently handle IPv6-mapped IPv4 addresses
|
|
90
|
-
- ✅ Standardize on a single approach to IP normalization
|
|
91
|
-
- **Impact:** Low - Already partially implemented
|
|
92
|
-
- **Dependencies:** None
|
|
93
|
-
|
|
94
|
-
### 3.3 Improve Type Safety ✅
|
|
95
|
-
|
|
96
|
-
Enhance type safety throughout the codebase to catch errors at compile time.
|
|
97
|
-
|
|
98
|
-
- **Action:** ✅
|
|
99
|
-
- ✅ Add stronger types where appropriate
|
|
100
|
-
- ✅ Remove any `any` types that could be replaced with more specific types
|
|
101
|
-
- ✅ Add explicit return types to functions
|
|
102
|
-
- **Impact:** Medium - May uncover existing issues
|
|
103
|
-
- **Dependencies:** None
|
|
104
|
-
|
|
105
|
-
## Phase 4: Documentation and Tests
|
|
106
|
-
|
|
107
|
-
### 4.1 Update API Documentation ✅
|
|
108
|
-
|
|
109
|
-
Ensure documentation is current and accurately reflects the cleaned-up API.
|
|
110
|
-
|
|
111
|
-
- **Action:** ✅
|
|
112
|
-
- ✅ Update comments and JSDoc throughout the codebase
|
|
113
|
-
- ✅ Ensure porthandling.md and other documentation reflect current implementation
|
|
114
|
-
- ✅ Remove references to deprecated functionality
|
|
115
|
-
- **Impact:** Low
|
|
116
|
-
- **Dependencies:** None
|
|
117
|
-
|
|
118
|
-
### 4.2 Add or Update Tests ✅
|
|
119
|
-
|
|
120
|
-
Ensure test coverage for the cleaned-up codebase.
|
|
121
|
-
|
|
122
|
-
- **Action:** ✅
|
|
123
|
-
- ✅ Update existing tests to remove references to deprecated functionality
|
|
124
|
-
- ✅ Add tests for edge cases in IP normalization
|
|
125
|
-
- ✅ Add tests for the updated route utility functions
|
|
126
|
-
- **Impact:** Medium
|
|
127
|
-
- **Dependencies:** None
|
|
128
|
-
|
|
129
|
-
## Implementation Sequence ✅
|
|
130
|
-
|
|
131
|
-
The changes were implemented in this order:
|
|
132
|
-
|
|
133
|
-
1. ✅ **Phase 1.1**: Remove Legacy Migration Utilities
|
|
134
|
-
2. ✅ **Phase 1.2**: Clean Up References to Deleted Files
|
|
135
|
-
3. ✅ **Phase 1.3**: Remove Deprecated Forwarding Types and Helpers
|
|
136
|
-
4. ✅ **Phase 2.1**: Streamline Interface Definitions
|
|
137
|
-
5. ✅ **Phase 3.1**: Standardize on 'preserve' Port Handling
|
|
138
|
-
6. ✅ **Phase 3.2**: Normalize IPv6-Mapped IPv4 Addresses
|
|
139
|
-
7. ⏸️ **Phase 2.2**: Consolidate Route Utilities (Postponed - Low priority)
|
|
140
|
-
8. ✅ **Phase 2.3**: Clean Up Legacy Connection Handling
|
|
141
|
-
9. ✅ **Phase 3.3**: Improve Type Safety
|
|
142
|
-
10. ✅ **Phase 4.1**: Update API Documentation
|
|
143
|
-
11. ✅ **Phase 4.2**: Add or Update Tests
|
|
144
|
-
|
|
145
|
-
## Detailed Implementation Steps
|
|
146
|
-
|
|
147
|
-
### 1. Remove Legacy Migration Utilities
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
# Delete the file
|
|
151
|
-
git rm ts/proxies/smart-proxy/utils/route-migration-utils.ts
|
|
152
|
-
|
|
153
|
-
# Remove the export from the index file
|
|
154
|
-
# Edit ts/proxies/smart-proxy/utils/index.ts to remove the export line
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### 2. Clean Up References to Deleted Files
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
# Update forwarding-types.ts to remove imports from route-helpers.js
|
|
161
|
-
# Edit ts/forwarding/config/forwarding-types.ts
|
|
162
|
-
|
|
163
|
-
# Remove or update imports in index.ts
|
|
164
|
-
# Edit ts/proxies/smart-proxy/utils/index.ts
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### 3. Remove Deprecated Forwarding Types
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
# Edit ts/forwarding/config/forwarding-types.ts to remove deprecated helpers and interfaces
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### 4. Streamline Interface Definitions
|
|
174
|
-
|
|
175
|
-
```bash
|
|
176
|
-
# Edit ts/proxies/smart-proxy/models/interfaces.ts to remove legacy functions and aliases
|
|
64
|
+
```typescript
|
|
65
|
+
// Step 1: Define the unified interface
|
|
66
|
+
export interface IRouteSecurity {
|
|
67
|
+
// Access control lists
|
|
68
|
+
ipAllowList?: string[]; // IP addresses that are allowed to connect
|
|
69
|
+
ipBlockList?: string[]; // IP addresses that are blocked from connecting
|
|
70
|
+
|
|
71
|
+
// Connection limits
|
|
72
|
+
maxConnections?: number; // Maximum concurrent connections
|
|
73
|
+
|
|
74
|
+
// Authentication
|
|
75
|
+
authentication?: IRouteAuthentication;
|
|
76
|
+
|
|
77
|
+
// Rate limiting
|
|
78
|
+
rateLimit?: IRouteRateLimit;
|
|
79
|
+
|
|
80
|
+
// Authentication methods
|
|
81
|
+
basicAuth?: {
|
|
82
|
+
enabled: boolean;
|
|
83
|
+
users: Array<{ username: string; password: string }>;
|
|
84
|
+
realm?: string;
|
|
85
|
+
excludePaths?: string[];
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
jwtAuth?: {
|
|
89
|
+
enabled: boolean;
|
|
90
|
+
secret: string;
|
|
91
|
+
algorithm?: string;
|
|
92
|
+
issuer?: string;
|
|
93
|
+
audience?: string;
|
|
94
|
+
expiresIn?: number;
|
|
95
|
+
excludePaths?: string[];
|
|
96
|
+
};
|
|
97
|
+
}
|
|
177
98
|
```
|
|
178
99
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
Ensure all IP matching functions consistently handle IPv6-mapped IPv4 addresses:
|
|
100
|
+
Update `isClientIpAllowed` method to use only the new property names:
|
|
182
101
|
|
|
183
102
|
```typescript
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
103
|
+
private isClientIpAllowed(route: IRouteConfig, clientIp: string): boolean {
|
|
104
|
+
const security = route.action.security;
|
|
105
|
+
|
|
106
|
+
if (!security) {
|
|
107
|
+
return true; // No security settings means allowed
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Check blocked IPs first
|
|
111
|
+
if (security.ipBlockList && security.ipBlockList.length > 0) {
|
|
112
|
+
for (const pattern of security.ipBlockList) {
|
|
113
|
+
if (this.matchIpPattern(pattern, clientIp)) {
|
|
114
|
+
return false; // IP is blocked
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// If there are allowed IPs, check them
|
|
120
|
+
if (security.ipAllowList && security.ipAllowList.length > 0) {
|
|
121
|
+
for (const pattern of security.ipAllowList) {
|
|
122
|
+
if (this.matchIpPattern(pattern, clientIp)) {
|
|
123
|
+
return true; // IP is allowed
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return false; // IP not in allowed list
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// No allowed IPs specified, so IP is allowed
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
188
132
|
```
|
|
189
133
|
|
|
190
|
-
##
|
|
134
|
+
## Expected Benefits
|
|
191
135
|
|
|
192
|
-
|
|
136
|
+
- **Improved Consistency**: Single, unified interface with consistent property naming
|
|
137
|
+
- **Better Type Safety**: Eliminating confusing duplicate interface definitions
|
|
138
|
+
- **Reduced Errors**: Prevent misunderstandings about which property names to use
|
|
139
|
+
- **Forward Compatibility**: Clearer path for future security enhancements
|
|
140
|
+
- **Better Developer Experience**: Simplified interface with comprehensive documentation
|
|
193
141
|
|
|
194
|
-
|
|
195
|
-
- **Improved Maintainability**: Cleaner, more focused code without legacy compatibility layers
|
|
196
|
-
- **Reduced Complexity**: Eliminated special cases for legacy config formats
|
|
197
|
-
- **Better Developer Experience**: Standardized on consistent patterns for port handling
|
|
198
|
-
- **Future-Proofing**: Removed deprecated code that would complicate future upgrades
|
|
199
|
-
- **Type Safety**: Fixed multiple TypeScript errors and improved type checking
|
|
142
|
+
## Testing Plan
|
|
200
143
|
|
|
201
|
-
|
|
144
|
+
1. Test with existing configurations using both old and new property names
|
|
145
|
+
2. Create specific test cases for port ranges with different security configurations
|
|
146
|
+
3. Verify that port forwarding with IP allow lists works correctly with the unified interface
|
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: '
|
|
6
|
+
version: '18.0.0',
|
|
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
|
}
|
|
@@ -199,8 +199,8 @@ export class SharedSecurityManager {
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
// Check IP against route security settings
|
|
202
|
-
const ipAllowList = route.security.ipAllowList
|
|
203
|
-
const ipBlockList = route.security.ipBlockList
|
|
202
|
+
const ipAllowList = route.security.ipAllowList;
|
|
203
|
+
const ipBlockList = route.security.ipBlockList;
|
|
204
204
|
|
|
205
205
|
const allowed = this.isIPAuthorized(clientIp, ipAllowList, ipBlockList);
|
|
206
206
|
|
|
@@ -40,9 +40,10 @@ export abstract class ForwardingHandler extends plugins.EventEmitter implements
|
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* Get a target from the configuration, supporting round-robin selection
|
|
43
|
+
* @param incomingPort Optional incoming port for 'preserve' mode
|
|
43
44
|
* @returns A resolved target object with host and port
|
|
44
45
|
*/
|
|
45
|
-
protected getTargetFromConfig(): { host: string, port: number } {
|
|
46
|
+
protected getTargetFromConfig(incomingPort: number = 80): { host: string, port: number } {
|
|
46
47
|
const { target } = this.config;
|
|
47
48
|
|
|
48
49
|
// Handle round-robin host selection
|
|
@@ -55,32 +56,37 @@ export abstract class ForwardingHandler extends plugins.EventEmitter implements
|
|
|
55
56
|
const randomIndex = Math.floor(Math.random() * target.host.length);
|
|
56
57
|
return {
|
|
57
58
|
host: target.host[randomIndex],
|
|
58
|
-
port: this.resolvePort(target.port)
|
|
59
|
+
port: this.resolvePort(target.port, incomingPort)
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
// Single host
|
|
63
64
|
return {
|
|
64
65
|
host: target.host,
|
|
65
|
-
port: this.resolvePort(target.port)
|
|
66
|
+
port: this.resolvePort(target.port, incomingPort)
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
/**
|
|
70
71
|
* Resolves a port value, handling 'preserve' and function ports
|
|
72
|
+
* @param port The port value to resolve
|
|
73
|
+
* @param incomingPort Optional incoming port to use for 'preserve' mode
|
|
71
74
|
*/
|
|
72
|
-
protected resolvePort(
|
|
75
|
+
protected resolvePort(
|
|
76
|
+
port: number | 'preserve' | ((ctx: any) => number),
|
|
77
|
+
incomingPort: number = 80
|
|
78
|
+
): number {
|
|
73
79
|
if (typeof port === 'function') {
|
|
74
80
|
try {
|
|
75
|
-
// Create a minimal context for the function
|
|
76
|
-
const ctx = { port:
|
|
81
|
+
// Create a minimal context for the function that includes the incoming port
|
|
82
|
+
const ctx = { port: incomingPort };
|
|
77
83
|
return port(ctx);
|
|
78
84
|
} catch (err) {
|
|
79
85
|
console.error('Error resolving port function:', err);
|
|
80
|
-
return
|
|
86
|
+
return incomingPort; // Fall back to incoming port
|
|
81
87
|
}
|
|
82
88
|
} else if (port === 'preserve') {
|
|
83
|
-
return
|
|
89
|
+
return incomingPort; // Use the actual incoming port for 'preserve'
|
|
84
90
|
} else {
|
|
85
91
|
return port;
|
|
86
92
|
}
|
|
@@ -38,6 +38,7 @@ export class HttpForwardingHandler extends ForwardingHandler {
|
|
|
38
38
|
// For HTTP, we mainly handle parsed requests, but we can still set up
|
|
39
39
|
// some basic connection tracking
|
|
40
40
|
const remoteAddress = socket.remoteAddress || 'unknown';
|
|
41
|
+
const localPort = socket.localPort || 80;
|
|
41
42
|
|
|
42
43
|
socket.on('close', (hadError) => {
|
|
43
44
|
this.emit(ForwardingHandlerEvents.DISCONNECTED, {
|
|
@@ -54,7 +55,8 @@ export class HttpForwardingHandler extends ForwardingHandler {
|
|
|
54
55
|
});
|
|
55
56
|
|
|
56
57
|
this.emit(ForwardingHandlerEvents.CONNECTED, {
|
|
57
|
-
remoteAddress
|
|
58
|
+
remoteAddress,
|
|
59
|
+
localPort
|
|
58
60
|
});
|
|
59
61
|
}
|
|
60
62
|
|
|
@@ -64,8 +66,11 @@ export class HttpForwardingHandler extends ForwardingHandler {
|
|
|
64
66
|
* @param res The HTTP response
|
|
65
67
|
*/
|
|
66
68
|
public handleHttpRequest(req: plugins.http.IncomingMessage, res: plugins.http.ServerResponse): void {
|
|
67
|
-
// Get the
|
|
68
|
-
const
|
|
69
|
+
// Get the local port from the request (for 'preserve' port handling)
|
|
70
|
+
const localPort = req.socket.localPort || 80;
|
|
71
|
+
|
|
72
|
+
// Get the target from configuration, passing the incoming port
|
|
73
|
+
const target = this.getTargetFromConfig(localPort);
|
|
69
74
|
|
|
70
75
|
// Create a custom headers object with variables for substitution
|
|
71
76
|
const variables = {
|
|
@@ -27,8 +27,8 @@ export interface ISmartProxyOptions {
|
|
|
27
27
|
port: number; // Default port to use when not specified in routes
|
|
28
28
|
};
|
|
29
29
|
security?: {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
ipAllowList?: string[]; // Default allowed IPs
|
|
31
|
+
ipBlockList?: string[]; // Default blocked IPs
|
|
32
32
|
maxConnections?: number; // Default max connections
|
|
33
33
|
};
|
|
34
34
|
preserveSourceIP?: boolean; // Default source IP preservation
|
|
@@ -112,13 +112,39 @@ export interface IRouteAuthentication {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
|
-
* Security options for
|
|
115
|
+
* Security options for routes
|
|
116
116
|
*/
|
|
117
117
|
export interface IRouteSecurity {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
// Access control lists
|
|
119
|
+
ipAllowList?: string[]; // IP addresses that are allowed to connect
|
|
120
|
+
ipBlockList?: string[]; // IP addresses that are blocked from connecting
|
|
121
|
+
|
|
122
|
+
// Connection limits
|
|
123
|
+
maxConnections?: number; // Maximum concurrent connections
|
|
124
|
+
|
|
125
|
+
// Authentication
|
|
121
126
|
authentication?: IRouteAuthentication;
|
|
127
|
+
|
|
128
|
+
// Rate limiting
|
|
129
|
+
rateLimit?: IRouteRateLimit;
|
|
130
|
+
|
|
131
|
+
// Authentication methods
|
|
132
|
+
basicAuth?: {
|
|
133
|
+
enabled: boolean;
|
|
134
|
+
users: Array<{ username: string; password: string }>;
|
|
135
|
+
realm?: string;
|
|
136
|
+
excludePaths?: string[];
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
jwtAuth?: {
|
|
140
|
+
enabled: boolean;
|
|
141
|
+
secret: string;
|
|
142
|
+
algorithm?: string;
|
|
143
|
+
issuer?: string;
|
|
144
|
+
audience?: string;
|
|
145
|
+
expiresIn?: number;
|
|
146
|
+
excludePaths?: string[];
|
|
147
|
+
};
|
|
122
148
|
}
|
|
123
149
|
|
|
124
150
|
/**
|
|
@@ -247,29 +273,7 @@ export interface IRouteRateLimit {
|
|
|
247
273
|
errorMessage?: string;
|
|
248
274
|
}
|
|
249
275
|
|
|
250
|
-
|
|
251
|
-
* Security features for routes
|
|
252
|
-
*/
|
|
253
|
-
export interface IRouteSecurity {
|
|
254
|
-
rateLimit?: IRouteRateLimit;
|
|
255
|
-
basicAuth?: {
|
|
256
|
-
enabled: boolean;
|
|
257
|
-
users: Array<{ username: string; password: string }>;
|
|
258
|
-
realm?: string;
|
|
259
|
-
excludePaths?: string[];
|
|
260
|
-
};
|
|
261
|
-
jwtAuth?: {
|
|
262
|
-
enabled: boolean;
|
|
263
|
-
secret: string;
|
|
264
|
-
algorithm?: string;
|
|
265
|
-
issuer?: string;
|
|
266
|
-
audience?: string;
|
|
267
|
-
expiresIn?: number;
|
|
268
|
-
excludePaths?: string[];
|
|
269
|
-
};
|
|
270
|
-
ipAllowList?: string[];
|
|
271
|
-
ipBlockList?: string[];
|
|
272
|
-
}
|
|
276
|
+
// IRouteSecurity is defined above - unified definition is used for all routes
|
|
273
277
|
|
|
274
278
|
/**
|
|
275
279
|
* CORS configuration for a route
|
|
@@ -289,11 +289,11 @@ export class RouteConnectionHandler {
|
|
|
289
289
|
// Check default security settings
|
|
290
290
|
const defaultSecuritySettings = this.settings.defaults?.security;
|
|
291
291
|
if (defaultSecuritySettings) {
|
|
292
|
-
if (defaultSecuritySettings.
|
|
292
|
+
if (defaultSecuritySettings.ipAllowList && defaultSecuritySettings.ipAllowList.length > 0) {
|
|
293
293
|
const isAllowed = this.securityManager.isIPAuthorized(
|
|
294
294
|
remoteIP,
|
|
295
|
-
defaultSecuritySettings.
|
|
296
|
-
defaultSecuritySettings.
|
|
295
|
+
defaultSecuritySettings.ipAllowList,
|
|
296
|
+
defaultSecuritySettings.ipBlockList || []
|
|
297
297
|
);
|
|
298
298
|
|
|
299
299
|
if (!isAllowed) {
|