@push.rocks/smartproxy 22.6.0 → 23.1.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.
Files changed (196) hide show
  1. package/changelog.md +18 -0
  2. package/dist_rust/{rustproxy → rustproxy_linux_amd64} +0 -0
  3. package/dist_rust/rustproxy_linux_arm64 +0 -0
  4. package/dist_ts/00_commitinfo_data.js +1 -1
  5. package/dist_ts/index.d.ts +0 -1
  6. package/dist_ts/index.js +1 -3
  7. package/dist_ts/plugins.d.ts +2 -1
  8. package/dist_ts/plugins.js +3 -2
  9. package/dist_ts/proxies/index.d.ts +0 -1
  10. package/dist_ts/proxies/index.js +1 -3
  11. package/dist_ts/proxies/smart-proxy/models/route-types.js +1 -1
  12. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.d.ts +9 -21
  13. package/dist_ts/proxies/smart-proxy/rust-proxy-bridge.js +83 -212
  14. package/dist_ts/proxies/smart-proxy/smart-proxy.js +2 -3
  15. package/npmextra.json +3 -0
  16. package/package.json +13 -11
  17. package/readme.md +35 -31
  18. package/ts/00_commitinfo_data.ts +1 -1
  19. package/ts/index.ts +0 -3
  20. package/ts/plugins.ts +2 -0
  21. package/ts/proxies/index.ts +0 -3
  22. package/ts/proxies/smart-proxy/models/route-types.ts +0 -2
  23. package/ts/proxies/smart-proxy/rust-proxy-bridge.ts +102 -233
  24. package/ts/proxies/smart-proxy/smart-proxy.ts +1 -2
  25. package/dist_ts/common/eventUtils.d.ts +0 -14
  26. package/dist_ts/common/eventUtils.js +0 -20
  27. package/dist_ts/common/types.d.ts +0 -82
  28. package/dist_ts/common/types.js +0 -15
  29. package/dist_ts/core/utils/event-system.d.ts +0 -200
  30. package/dist_ts/core/utils/event-system.js +0 -224
  31. package/dist_ts/core/utils/event-utils.d.ts +0 -15
  32. package/dist_ts/core/utils/event-utils.js +0 -11
  33. package/dist_ts/core/utils/route-manager.d.ts +0 -88
  34. package/dist_ts/core/utils/route-manager.js +0 -342
  35. package/dist_ts/core/utils/route-utils.d.ts +0 -28
  36. package/dist_ts/core/utils/route-utils.js +0 -67
  37. package/dist_ts/detection/detectors/http-detector-v2.d.ts +0 -33
  38. package/dist_ts/detection/detectors/http-detector-v2.js +0 -87
  39. package/dist_ts/detection/detectors/tls-detector-v2.d.ts +0 -33
  40. package/dist_ts/detection/detectors/tls-detector-v2.js +0 -80
  41. package/dist_ts/detection/protocol-detector-v2.d.ts +0 -46
  42. package/dist_ts/detection/protocol-detector-v2.js +0 -116
  43. package/dist_ts/forwarding/config/forwarding-types.d.ts +0 -42
  44. package/dist_ts/forwarding/config/forwarding-types.js +0 -18
  45. package/dist_ts/forwarding/config/index.d.ts +0 -9
  46. package/dist_ts/forwarding/config/index.js +0 -10
  47. package/dist_ts/forwarding/factory/forwarding-factory.d.ts +0 -25
  48. package/dist_ts/forwarding/factory/forwarding-factory.js +0 -172
  49. package/dist_ts/forwarding/factory/index.d.ts +0 -4
  50. package/dist_ts/forwarding/factory/index.js +0 -5
  51. package/dist_ts/forwarding/handlers/base-handler.d.ts +0 -62
  52. package/dist_ts/forwarding/handlers/base-handler.js +0 -121
  53. package/dist_ts/forwarding/handlers/http-handler.d.ts +0 -30
  54. package/dist_ts/forwarding/handlers/http-handler.js +0 -143
  55. package/dist_ts/forwarding/handlers/https-passthrough-handler.d.ts +0 -29
  56. package/dist_ts/forwarding/handlers/https-passthrough-handler.js +0 -156
  57. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.d.ts +0 -36
  58. package/dist_ts/forwarding/handlers/https-terminate-to-http-handler.js +0 -276
  59. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.d.ts +0 -35
  60. package/dist_ts/forwarding/handlers/https-terminate-to-https-handler.js +0 -261
  61. package/dist_ts/forwarding/handlers/index.d.ts +0 -8
  62. package/dist_ts/forwarding/handlers/index.js +0 -9
  63. package/dist_ts/forwarding/index.d.ts +0 -13
  64. package/dist_ts/forwarding/index.js +0 -16
  65. package/dist_ts/http/index.d.ts +0 -5
  66. package/dist_ts/http/index.js +0 -8
  67. package/dist_ts/http/models/http-types.d.ts +0 -6
  68. package/dist_ts/http/models/http-types.js +0 -7
  69. package/dist_ts/http/router/index.d.ts +0 -8
  70. package/dist_ts/http/router/index.js +0 -7
  71. package/dist_ts/http/router/proxy-router.d.ts +0 -115
  72. package/dist_ts/http/router/proxy-router.js +0 -325
  73. package/dist_ts/http/router/route-router.d.ts +0 -108
  74. package/dist_ts/http/router/route-router.js +0 -393
  75. package/dist_ts/protocols/tls/constants.d.ts +0 -122
  76. package/dist_ts/protocols/tls/constants.js +0 -135
  77. package/dist_ts/protocols/tls/parser.d.ts +0 -53
  78. package/dist_ts/protocols/tls/parser.js +0 -294
  79. package/dist_ts/protocols/tls/types.d.ts +0 -65
  80. package/dist_ts/protocols/tls/types.js +0 -5
  81. package/dist_ts/proxies/http-proxy/certificate-manager.d.ts +0 -95
  82. package/dist_ts/proxies/http-proxy/certificate-manager.js +0 -214
  83. package/dist_ts/proxies/http-proxy/connection-pool.d.ts +0 -47
  84. package/dist_ts/proxies/http-proxy/connection-pool.js +0 -195
  85. package/dist_ts/proxies/http-proxy/context-creator.d.ts +0 -34
  86. package/dist_ts/proxies/http-proxy/context-creator.js +0 -108
  87. package/dist_ts/proxies/http-proxy/default-certificates.d.ts +0 -54
  88. package/dist_ts/proxies/http-proxy/default-certificates.js +0 -127
  89. package/dist_ts/proxies/http-proxy/function-cache.d.ts +0 -95
  90. package/dist_ts/proxies/http-proxy/function-cache.js +0 -215
  91. package/dist_ts/proxies/http-proxy/handlers/index.d.ts +0 -4
  92. package/dist_ts/proxies/http-proxy/handlers/index.js +0 -6
  93. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.d.ts +0 -18
  94. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.js +0 -78
  95. package/dist_ts/proxies/http-proxy/handlers/static-handler.d.ts +0 -19
  96. package/dist_ts/proxies/http-proxy/handlers/static-handler.js +0 -211
  97. package/dist_ts/proxies/http-proxy/http-proxy.d.ts +0 -117
  98. package/dist_ts/proxies/http-proxy/http-proxy.js +0 -521
  99. package/dist_ts/proxies/http-proxy/http-request-handler.d.ts +0 -40
  100. package/dist_ts/proxies/http-proxy/http-request-handler.js +0 -257
  101. package/dist_ts/proxies/http-proxy/http2-request-handler.d.ts +0 -24
  102. package/dist_ts/proxies/http-proxy/http2-request-handler.js +0 -201
  103. package/dist_ts/proxies/http-proxy/index.d.ts +0 -14
  104. package/dist_ts/proxies/http-proxy/index.js +0 -16
  105. package/dist_ts/proxies/http-proxy/models/http-types.d.ts +0 -117
  106. package/dist_ts/proxies/http-proxy/models/http-types.js +0 -92
  107. package/dist_ts/proxies/http-proxy/models/index.d.ts +0 -5
  108. package/dist_ts/proxies/http-proxy/models/index.js +0 -6
  109. package/dist_ts/proxies/http-proxy/models/types.d.ts +0 -75
  110. package/dist_ts/proxies/http-proxy/models/types.js +0 -35
  111. package/dist_ts/proxies/http-proxy/request-handler.d.ts +0 -97
  112. package/dist_ts/proxies/http-proxy/request-handler.js +0 -737
  113. package/dist_ts/proxies/http-proxy/security-manager.d.ts +0 -98
  114. package/dist_ts/proxies/http-proxy/security-manager.js +0 -341
  115. package/dist_ts/proxies/http-proxy/websocket-handler.d.ts +0 -50
  116. package/dist_ts/proxies/http-proxy/websocket-handler.js +0 -505
  117. package/dist_ts/proxies/nftables-proxy/index.d.ts +0 -6
  118. package/dist_ts/proxies/nftables-proxy/index.js +0 -7
  119. package/dist_ts/proxies/nftables-proxy/models/errors.d.ts +0 -15
  120. package/dist_ts/proxies/nftables-proxy/models/errors.js +0 -28
  121. package/dist_ts/proxies/nftables-proxy/models/index.d.ts +0 -5
  122. package/dist_ts/proxies/nftables-proxy/models/index.js +0 -6
  123. package/dist_ts/proxies/nftables-proxy/models/interfaces.d.ts +0 -75
  124. package/dist_ts/proxies/nftables-proxy/models/interfaces.js +0 -5
  125. package/dist_ts/proxies/nftables-proxy/nftables-proxy.d.ts +0 -124
  126. package/dist_ts/proxies/nftables-proxy/nftables-proxy.js +0 -1374
  127. package/dist_ts/proxies/nftables-proxy/utils/index.d.ts +0 -9
  128. package/dist_ts/proxies/nftables-proxy/utils/index.js +0 -12
  129. package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.d.ts +0 -66
  130. package/dist_ts/proxies/nftables-proxy/utils/nft-command-executor.js +0 -131
  131. package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.d.ts +0 -39
  132. package/dist_ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.js +0 -112
  133. package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.d.ts +0 -59
  134. package/dist_ts/proxies/nftables-proxy/utils/nft-rule-validator.js +0 -130
  135. package/dist_ts/proxies/smart-proxy/acme-state-manager.d.ts +0 -42
  136. package/dist_ts/proxies/smart-proxy/acme-state-manager.js +0 -101
  137. package/dist_ts/proxies/smart-proxy/cert-store.d.ts +0 -10
  138. package/dist_ts/proxies/smart-proxy/cert-store.js +0 -72
  139. package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +0 -164
  140. package/dist_ts/proxies/smart-proxy/certificate-manager.js +0 -745
  141. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +0 -128
  142. package/dist_ts/proxies/smart-proxy/connection-manager.js +0 -689
  143. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +0 -43
  144. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +0 -180
  145. package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +0 -98
  146. package/dist_ts/proxies/smart-proxy/metrics-collector.js +0 -355
  147. package/dist_ts/proxies/smart-proxy/nftables-manager.d.ts +0 -82
  148. package/dist_ts/proxies/smart-proxy/nftables-manager.js +0 -237
  149. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +0 -117
  150. package/dist_ts/proxies/smart-proxy/port-manager.js +0 -318
  151. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +0 -60
  152. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +0 -1407
  153. package/dist_ts/proxies/smart-proxy/route-manager.d.ts +0 -112
  154. package/dist_ts/proxies/smart-proxy/route-manager.js +0 -453
  155. package/dist_ts/proxies/smart-proxy/route-orchestrator.d.ts +0 -56
  156. package/dist_ts/proxies/smart-proxy/route-orchestrator.js +0 -204
  157. package/dist_ts/proxies/smart-proxy/rust-binary-locator.d.ts +0 -23
  158. package/dist_ts/proxies/smart-proxy/rust-binary-locator.js +0 -104
  159. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +0 -74
  160. package/dist_ts/proxies/smart-proxy/security-manager.js +0 -227
  161. package/dist_ts/proxies/smart-proxy/throughput-tracker.d.ts +0 -36
  162. package/dist_ts/proxies/smart-proxy/throughput-tracker.js +0 -115
  163. package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +0 -48
  164. package/dist_ts/proxies/smart-proxy/timeout-manager.js +0 -158
  165. package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +0 -50
  166. package/dist_ts/proxies/smart-proxy/tls-manager.js +0 -110
  167. package/dist_ts/proxies/smart-proxy/utils/route-patterns.d.ts +0 -161
  168. package/dist_ts/proxies/smart-proxy/utils/route-patterns.js +0 -282
  169. package/dist_ts/proxies/smart-proxy/utils/route-validators.d.ts +0 -73
  170. package/dist_ts/proxies/smart-proxy/utils/route-validators.js +0 -259
  171. package/dist_ts/routing/router/proxy-router.d.ts +0 -115
  172. package/dist_ts/routing/router/proxy-router.js +0 -325
  173. package/dist_ts/routing/router/route-router.d.ts +0 -108
  174. package/dist_ts/routing/router/route-router.js +0 -393
  175. package/dist_ts/tls/alerts/index.d.ts +0 -4
  176. package/dist_ts/tls/alerts/index.js +0 -5
  177. package/dist_ts/tls/alerts/tls-alert.d.ts +0 -150
  178. package/dist_ts/tls/alerts/tls-alert.js +0 -226
  179. package/dist_ts/tls/sni/client-hello-parser.d.ts +0 -100
  180. package/dist_ts/tls/sni/client-hello-parser.js +0 -464
  181. package/dist_ts/tls/sni/sni-extraction.d.ts +0 -58
  182. package/dist_ts/tls/sni/sni-extraction.js +0 -275
  183. package/dist_ts/tls/utils/index.d.ts +0 -4
  184. package/dist_ts/tls/utils/index.js +0 -5
  185. package/dist_ts/tls/utils/tls-utils.d.ts +0 -49
  186. package/dist_ts/tls/utils/tls-utils.js +0 -75
  187. package/ts/proxies/nftables-proxy/index.ts +0 -6
  188. package/ts/proxies/nftables-proxy/models/errors.ts +0 -30
  189. package/ts/proxies/nftables-proxy/models/index.ts +0 -5
  190. package/ts/proxies/nftables-proxy/models/interfaces.ts +0 -94
  191. package/ts/proxies/nftables-proxy/nftables-proxy.ts +0 -1754
  192. package/ts/proxies/nftables-proxy/utils/index.ts +0 -38
  193. package/ts/proxies/nftables-proxy/utils/nft-command-executor.ts +0 -162
  194. package/ts/proxies/nftables-proxy/utils/nft-port-spec-normalizer.ts +0 -125
  195. package/ts/proxies/nftables-proxy/utils/nft-rule-validator.ts +0 -156
  196. package/ts/proxies/smart-proxy/rust-binary-locator.ts +0 -112
@@ -1,38 +0,0 @@
1
- /**
2
- * NFTables Proxy Utilities
3
- *
4
- * This module exports utility functions and classes for NFTables operations.
5
- */
6
-
7
- // Command execution
8
- export { NftCommandExecutor } from './nft-command-executor.js';
9
- export type { INftLoggerFn, INftExecutorOptions } from './nft-command-executor.js';
10
-
11
- // Port specification normalization
12
- export {
13
- normalizePortSpec,
14
- validatePorts,
15
- formatPortRange,
16
- portSpecToNftExpr,
17
- rangesOverlap,
18
- mergeOverlappingRanges,
19
- countPorts,
20
- isPortInSpec
21
- } from './nft-port-spec-normalizer.js';
22
-
23
- // Rule validation
24
- export {
25
- isValidIP,
26
- isValidIPv4,
27
- isValidIPv6,
28
- isValidHostname,
29
- isValidTableName,
30
- isValidRate,
31
- validateIPs,
32
- validateHost,
33
- validateTableName,
34
- validateQosSettings,
35
- validateSettings,
36
- isIPForFamily,
37
- filterIPsByFamily
38
- } from './nft-rule-validator.js';
@@ -1,162 +0,0 @@
1
- /**
2
- * NFTables Command Executor
3
- *
4
- * Handles command execution with retry logic, temp file management,
5
- * and error handling for nftables operations.
6
- */
7
-
8
- import { exec, execSync } from 'child_process';
9
- import { promisify } from 'util';
10
- import { delay } from '../../../core/utils/async-utils.js';
11
- import { AsyncFileSystem } from '../../../core/utils/fs-utils.js';
12
- import { NftExecutionError } from '../models/index.js';
13
-
14
- const execAsync = promisify(exec);
15
-
16
- export interface INftLoggerFn {
17
- (level: 'info' | 'warn' | 'error' | 'debug', message: string, data?: Record<string, any>): void;
18
- }
19
-
20
- export interface INftExecutorOptions {
21
- maxRetries?: number;
22
- retryDelayMs?: number;
23
- tempFilePath?: string;
24
- }
25
-
26
- /**
27
- * NFTables command executor with retry logic and temp file support
28
- */
29
- export class NftCommandExecutor {
30
- private static readonly NFT_CMD = 'nft';
31
- private maxRetries: number;
32
- private retryDelayMs: number;
33
- private tempFilePath: string;
34
-
35
- constructor(
36
- private log: INftLoggerFn,
37
- options: INftExecutorOptions = {}
38
- ) {
39
- this.maxRetries = options.maxRetries || 3;
40
- this.retryDelayMs = options.retryDelayMs || 1000;
41
- this.tempFilePath = options.tempFilePath || `/tmp/nft-rules-${Date.now()}.nft`;
42
- }
43
-
44
- /**
45
- * Execute a command with retry capability
46
- */
47
- async executeWithRetry(command: string, maxRetries?: number, retryDelayMs?: number): Promise<string> {
48
- const retries = maxRetries ?? this.maxRetries;
49
- const delayMs = retryDelayMs ?? this.retryDelayMs;
50
- let lastError: Error | undefined;
51
-
52
- for (let i = 0; i < retries; i++) {
53
- try {
54
- const { stdout } = await execAsync(command);
55
- return stdout;
56
- } catch (err) {
57
- lastError = err as Error;
58
- this.log('warn', `Command failed (attempt ${i+1}/${retries}): ${command}`, { error: lastError.message });
59
-
60
- // Wait before retry, unless it's the last attempt
61
- if (i < retries - 1) {
62
- await delay(delayMs);
63
- }
64
- }
65
- }
66
-
67
- throw new NftExecutionError(`Failed after ${retries} attempts: ${lastError?.message || 'Unknown error'}`);
68
- }
69
-
70
- /**
71
- * Execute system command synchronously (single attempt, no retry)
72
- * Used only for exit handlers where the process is terminating anyway.
73
- */
74
- executeSync(command: string): string {
75
- try {
76
- return execSync(command, { timeout: 5000 }).toString();
77
- } catch (err) {
78
- this.log('warn', `Sync command failed: ${command}`, { error: (err as Error).message });
79
- throw err;
80
- }
81
- }
82
-
83
- /**
84
- * Execute nftables commands with a temporary file
85
- */
86
- async executeWithTempFile(rulesetContent: string): Promise<void> {
87
- await AsyncFileSystem.writeFile(this.tempFilePath, rulesetContent);
88
-
89
- try {
90
- await this.executeWithRetry(
91
- `${NftCommandExecutor.NFT_CMD} -f ${this.tempFilePath}`,
92
- this.maxRetries,
93
- this.retryDelayMs
94
- );
95
- } finally {
96
- // Always clean up the temp file
97
- await AsyncFileSystem.remove(this.tempFilePath);
98
- }
99
- }
100
-
101
- /**
102
- * Check if nftables is available
103
- */
104
- async checkAvailability(): Promise<boolean> {
105
- try {
106
- await this.executeWithRetry(`${NftCommandExecutor.NFT_CMD} --version`, this.maxRetries, this.retryDelayMs);
107
- return true;
108
- } catch (err) {
109
- this.log('error', `nftables is not available: ${(err as Error).message}`);
110
- return false;
111
- }
112
- }
113
-
114
- /**
115
- * Check if connection tracking modules are loaded
116
- */
117
- async checkConntrackModules(): Promise<boolean> {
118
- try {
119
- await this.executeWithRetry('lsmod | grep nf_conntrack', this.maxRetries, this.retryDelayMs);
120
- return true;
121
- } catch (err) {
122
- this.log('warn', 'Connection tracking modules might not be loaded, advanced NAT features may not work');
123
- return false;
124
- }
125
- }
126
-
127
- /**
128
- * Run an nft command directly
129
- */
130
- async nft(args: string): Promise<string> {
131
- return this.executeWithRetry(`${NftCommandExecutor.NFT_CMD} ${args}`, this.maxRetries, this.retryDelayMs);
132
- }
133
-
134
- /**
135
- * Run an nft command synchronously (for cleanup on exit)
136
- */
137
- nftSync(args: string): string {
138
- return this.executeSync(`${NftCommandExecutor.NFT_CMD} ${args}`);
139
- }
140
-
141
- /**
142
- * Get the NFT command path
143
- */
144
- static get nftCmd(): string {
145
- return NftCommandExecutor.NFT_CMD;
146
- }
147
-
148
- /**
149
- * Update the temp file path
150
- */
151
- setTempFilePath(path: string): void {
152
- this.tempFilePath = path;
153
- }
154
-
155
- /**
156
- * Update retry settings
157
- */
158
- setRetryOptions(maxRetries: number, retryDelayMs: number): void {
159
- this.maxRetries = maxRetries;
160
- this.retryDelayMs = retryDelayMs;
161
- }
162
- }
@@ -1,125 +0,0 @@
1
- /**
2
- * NFTables Port Specification Normalizer
3
- *
4
- * Handles normalization and validation of port specifications
5
- * for nftables rules.
6
- */
7
-
8
- import type { PortRange } from '../models/index.js';
9
- import { NftValidationError } from '../models/index.js';
10
-
11
- /**
12
- * Normalizes port specifications into an array of port ranges
13
- */
14
- export function normalizePortSpec(portSpec: number | PortRange | Array<number | PortRange>): PortRange[] {
15
- const result: PortRange[] = [];
16
-
17
- if (Array.isArray(portSpec)) {
18
- // If it's an array, process each element
19
- for (const spec of portSpec) {
20
- result.push(...normalizePortSpec(spec));
21
- }
22
- } else if (typeof portSpec === 'number') {
23
- // Single port becomes a range with the same start and end
24
- result.push({ from: portSpec, to: portSpec });
25
- } else {
26
- // Already a range
27
- result.push(portSpec);
28
- }
29
-
30
- return result;
31
- }
32
-
33
- /**
34
- * Validates port numbers or ranges
35
- */
36
- export function validatePorts(port: number | PortRange | Array<number | PortRange>): void {
37
- if (Array.isArray(port)) {
38
- port.forEach(p => validatePorts(p));
39
- return;
40
- }
41
-
42
- if (typeof port === 'number') {
43
- if (port < 1 || port > 65535) {
44
- throw new NftValidationError(`Invalid port number: ${port}`);
45
- }
46
- } else if (typeof port === 'object') {
47
- if (port.from < 1 || port.from > 65535 || port.to < 1 || port.to > 65535 || port.from > port.to) {
48
- throw new NftValidationError(`Invalid port range: ${port.from}-${port.to}`);
49
- }
50
- }
51
- }
52
-
53
- /**
54
- * Format port range for nftables rule
55
- */
56
- export function formatPortRange(range: PortRange): string {
57
- if (range.from === range.to) {
58
- return String(range.from);
59
- }
60
- return `${range.from}-${range.to}`;
61
- }
62
-
63
- /**
64
- * Convert port spec to nftables expression
65
- */
66
- export function portSpecToNftExpr(portSpec: number | PortRange | Array<number | PortRange>): string {
67
- const ranges = normalizePortSpec(portSpec);
68
-
69
- if (ranges.length === 1) {
70
- return formatPortRange(ranges[0]);
71
- }
72
-
73
- // Multiple ports/ranges need to use a set
74
- const ports = ranges.map(formatPortRange);
75
- return `{ ${ports.join(', ')} }`;
76
- }
77
-
78
- /**
79
- * Check if two port ranges overlap
80
- */
81
- export function rangesOverlap(range1: PortRange, range2: PortRange): boolean {
82
- return range1.from <= range2.to && range2.from <= range1.to;
83
- }
84
-
85
- /**
86
- * Merge overlapping port ranges
87
- */
88
- export function mergeOverlappingRanges(ranges: PortRange[]): PortRange[] {
89
- if (ranges.length <= 1) return ranges;
90
-
91
- // Sort by start port
92
- const sorted = [...ranges].sort((a, b) => a.from - b.from);
93
- const merged: PortRange[] = [sorted[0]];
94
-
95
- for (let i = 1; i < sorted.length; i++) {
96
- const current = sorted[i];
97
- const lastMerged = merged[merged.length - 1];
98
-
99
- if (current.from <= lastMerged.to + 1) {
100
- // Ranges overlap or are adjacent, merge them
101
- lastMerged.to = Math.max(lastMerged.to, current.to);
102
- } else {
103
- // No overlap, add as new range
104
- merged.push(current);
105
- }
106
- }
107
-
108
- return merged;
109
- }
110
-
111
- /**
112
- * Calculate the total number of ports in a port specification
113
- */
114
- export function countPorts(portSpec: number | PortRange | Array<number | PortRange>): number {
115
- const ranges = normalizePortSpec(portSpec);
116
- return ranges.reduce((total, range) => total + (range.to - range.from + 1), 0);
117
- }
118
-
119
- /**
120
- * Check if a port is within the given specification
121
- */
122
- export function isPortInSpec(port: number, portSpec: number | PortRange | Array<number | PortRange>): boolean {
123
- const ranges = normalizePortSpec(portSpec);
124
- return ranges.some(range => port >= range.from && port <= range.to);
125
- }
@@ -1,156 +0,0 @@
1
- /**
2
- * NFTables Rule Validator
3
- *
4
- * Handles validation of settings and inputs for nftables operations.
5
- * Prevents command injection and ensures valid values.
6
- */
7
-
8
- import type { PortRange, NfTableProxyOptions } from '../models/index.js';
9
- import { NftValidationError } from '../models/index.js';
10
- import { validatePorts } from './nft-port-spec-normalizer.js';
11
-
12
- // IP address validation patterns
13
- const IPV4_REGEX = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$/;
14
- const IPV6_REGEX = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$/;
15
- const HOSTNAME_REGEX = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
16
- const TABLE_NAME_REGEX = /^[a-zA-Z0-9_]+$/;
17
- const RATE_REGEX = /^[0-9]+[kKmMgG]?bps$/;
18
-
19
- /**
20
- * Validates an IP address (IPv4 or IPv6)
21
- */
22
- export function isValidIP(ip: string): boolean {
23
- return IPV4_REGEX.test(ip) || IPV6_REGEX.test(ip);
24
- }
25
-
26
- /**
27
- * Validates an IPv4 address
28
- */
29
- export function isValidIPv4(ip: string): boolean {
30
- return IPV4_REGEX.test(ip);
31
- }
32
-
33
- /**
34
- * Validates an IPv6 address
35
- */
36
- export function isValidIPv6(ip: string): boolean {
37
- return IPV6_REGEX.test(ip);
38
- }
39
-
40
- /**
41
- * Validates a hostname
42
- */
43
- export function isValidHostname(hostname: string): boolean {
44
- return HOSTNAME_REGEX.test(hostname);
45
- }
46
-
47
- /**
48
- * Validates a table name for nftables
49
- */
50
- export function isValidTableName(tableName: string): boolean {
51
- return TABLE_NAME_REGEX.test(tableName);
52
- }
53
-
54
- /**
55
- * Validates a rate specification (e.g., "10mbps")
56
- */
57
- export function isValidRate(rate: string): boolean {
58
- return RATE_REGEX.test(rate);
59
- }
60
-
61
- /**
62
- * Validates an array of IP addresses
63
- */
64
- export function validateIPs(ips?: string[]): void {
65
- if (!ips) return;
66
-
67
- for (const ip of ips) {
68
- if (!isValidIP(ip)) {
69
- throw new NftValidationError(`Invalid IP address format: ${ip}`);
70
- }
71
- }
72
- }
73
-
74
- /**
75
- * Validates a host (can be hostname or IP)
76
- */
77
- export function validateHost(host?: string): void {
78
- if (!host) return;
79
-
80
- if (!isValidHostname(host) && !isValidIP(host)) {
81
- throw new NftValidationError(`Invalid host format: ${host}`);
82
- }
83
- }
84
-
85
- /**
86
- * Validates a table name
87
- */
88
- export function validateTableName(tableName?: string): void {
89
- if (!tableName) return;
90
-
91
- if (!isValidTableName(tableName)) {
92
- throw new NftValidationError(
93
- `Invalid table name: ${tableName}. Only alphanumeric characters and underscores are allowed.`
94
- );
95
- }
96
- }
97
-
98
- /**
99
- * Validates QoS settings
100
- */
101
- export function validateQosSettings(qos?: NfTableProxyOptions['qos']): void {
102
- if (!qos?.enabled) return;
103
-
104
- if (qos.maxRate && !isValidRate(qos.maxRate)) {
105
- throw new NftValidationError(
106
- `Invalid rate format: ${qos.maxRate}. Use format like "10mbps", "1gbps", etc.`
107
- );
108
- }
109
-
110
- if (qos.priority !== undefined) {
111
- if (qos.priority < 1 || qos.priority > 10 || !Number.isInteger(qos.priority)) {
112
- throw new NftValidationError(
113
- `Invalid priority: ${qos.priority}. Must be an integer between 1 and 10.`
114
- );
115
- }
116
- }
117
- }
118
-
119
- /**
120
- * Validates all NfTablesProxy settings
121
- */
122
- export function validateSettings(settings: NfTableProxyOptions): void {
123
- // Validate port numbers
124
- validatePorts(settings.fromPort);
125
- validatePorts(settings.toPort);
126
-
127
- // Validate IP addresses
128
- validateIPs(settings.ipAllowList);
129
- validateIPs(settings.ipBlockList);
130
-
131
- // Validate target host
132
- validateHost(settings.toHost);
133
-
134
- // Validate table name
135
- validateTableName(settings.tableName);
136
-
137
- // Validate QoS settings
138
- validateQosSettings(settings.qos);
139
- }
140
-
141
- /**
142
- * Check if an IP matches the given family (ip or ip6)
143
- */
144
- export function isIPForFamily(ip: string, family: 'ip' | 'ip6'): boolean {
145
- if (family === 'ip6') {
146
- return ip.includes(':');
147
- }
148
- return ip.includes('.');
149
- }
150
-
151
- /**
152
- * Filter IPs by family
153
- */
154
- export function filterIPsByFamily(ips: string[], family: 'ip' | 'ip6'): string[] {
155
- return ips.filter(ip => isIPForFamily(ip, family));
156
- }
@@ -1,112 +0,0 @@
1
- import * as plugins from '../../plugins.js';
2
- import { logger } from '../../core/utils/logger.js';
3
-
4
- /**
5
- * Locates the RustProxy binary using a priority-ordered search strategy:
6
- * 1. SMARTPROXY_RUST_BINARY environment variable
7
- * 2. Platform-specific optional npm package
8
- * 3. Local development build at ./rust/target/release/rustproxy
9
- * 4. System PATH
10
- */
11
- export class RustBinaryLocator {
12
- private cachedPath: string | null = null;
13
-
14
- /**
15
- * Find the RustProxy binary path.
16
- * Returns null if no binary is available.
17
- */
18
- public async findBinary(): Promise<string | null> {
19
- if (this.cachedPath !== null) {
20
- return this.cachedPath;
21
- }
22
-
23
- const path = await this.searchBinary();
24
- this.cachedPath = path;
25
- return path;
26
- }
27
-
28
- /**
29
- * Clear the cached binary path (e.g., after a failed launch).
30
- */
31
- public clearCache(): void {
32
- this.cachedPath = null;
33
- }
34
-
35
- private async searchBinary(): Promise<string | null> {
36
- // 1. Environment variable override
37
- const envPath = process.env.SMARTPROXY_RUST_BINARY;
38
- if (envPath) {
39
- if (await this.isExecutable(envPath)) {
40
- logger.log('info', `RustProxy binary found via SMARTPROXY_RUST_BINARY: ${envPath}`, { component: 'rust-locator' });
41
- return envPath;
42
- }
43
- logger.log('warn', `SMARTPROXY_RUST_BINARY set but not executable: ${envPath}`, { component: 'rust-locator' });
44
- }
45
-
46
- // 2. Platform-specific optional npm package
47
- const platformBinary = await this.findPlatformPackageBinary();
48
- if (platformBinary) {
49
- logger.log('info', `RustProxy binary found in platform package: ${platformBinary}`, { component: 'rust-locator' });
50
- return platformBinary;
51
- }
52
-
53
- // 3. Local development build
54
- const localPaths = [
55
- plugins.path.resolve(process.cwd(), 'rust/target/release/rustproxy'),
56
- plugins.path.resolve(process.cwd(), 'rust/target/debug/rustproxy'),
57
- ];
58
- for (const localPath of localPaths) {
59
- if (await this.isExecutable(localPath)) {
60
- logger.log('info', `RustProxy binary found at local path: ${localPath}`, { component: 'rust-locator' });
61
- return localPath;
62
- }
63
- }
64
-
65
- // 4. System PATH
66
- const systemPath = await this.findInPath('rustproxy');
67
- if (systemPath) {
68
- logger.log('info', `RustProxy binary found in system PATH: ${systemPath}`, { component: 'rust-locator' });
69
- return systemPath;
70
- }
71
-
72
- logger.log('error', 'No RustProxy binary found. Set SMARTPROXY_RUST_BINARY, install the platform package, or build with: cd rust && cargo build --release', { component: 'rust-locator' });
73
- return null;
74
- }
75
-
76
- private async findPlatformPackageBinary(): Promise<string | null> {
77
- const platform = process.platform;
78
- const arch = process.arch;
79
- const packageName = `@push.rocks/smartproxy-${platform}-${arch}`;
80
-
81
- try {
82
- // Try to resolve the platform-specific package
83
- const packagePath = require.resolve(`${packageName}/rustproxy`);
84
- if (await this.isExecutable(packagePath)) {
85
- return packagePath;
86
- }
87
- } catch {
88
- // Package not installed - expected for development
89
- }
90
- return null;
91
- }
92
-
93
- private async isExecutable(filePath: string): Promise<boolean> {
94
- try {
95
- await plugins.fs.promises.access(filePath, plugins.fs.constants.X_OK);
96
- return true;
97
- } catch {
98
- return false;
99
- }
100
- }
101
-
102
- private async findInPath(binaryName: string): Promise<string | null> {
103
- const pathDirs = (process.env.PATH || '').split(plugins.path.delimiter);
104
- for (const dir of pathDirs) {
105
- const fullPath = plugins.path.join(dir, binaryName);
106
- if (await this.isExecutable(fullPath)) {
107
- return fullPath;
108
- }
109
- }
110
- return null;
111
- }
112
- }