@push.rocks/smartproxy 19.3.2 → 19.3.4

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 (313) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/forwarding/factory/forwarding-factory.js +29 -1
  3. package/dist_ts/http/index.d.ts +1 -3
  4. package/dist_ts/http/index.js +4 -10
  5. package/dist_ts/http/models/http-types.d.ts +4 -91
  6. package/dist_ts/http/models/http-types.js +5 -60
  7. package/dist_ts/http/router/proxy-router.d.ts +1 -1
  8. package/dist_ts/http/router/route-router.d.ts +1 -1
  9. package/dist_ts/index.d.ts +9 -7
  10. package/dist_ts/index.js +10 -7
  11. package/dist_ts/proxies/{network-proxy → http-proxy}/certificate-manager.d.ts +2 -2
  12. package/dist_ts/proxies/{network-proxy → http-proxy}/certificate-manager.js +1 -1
  13. package/dist_ts/proxies/{network-proxy → http-proxy}/connection-pool.d.ts +2 -2
  14. package/dist_ts/proxies/http-proxy/connection-pool.js +210 -0
  15. package/dist_ts/proxies/http-proxy/context-creator.js +108 -0
  16. package/dist_ts/proxies/{network-proxy → http-proxy}/function-cache.js +1 -1
  17. package/dist_ts/proxies/http-proxy/handlers/index.d.ts +5 -0
  18. package/dist_ts/proxies/http-proxy/handlers/index.js +6 -0
  19. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.d.ts +18 -0
  20. package/dist_ts/proxies/http-proxy/handlers/redirect-handler.js +78 -0
  21. package/dist_ts/proxies/http-proxy/handlers/static-handler.d.ts +19 -0
  22. package/dist_ts/proxies/http-proxy/handlers/static-handler.js +203 -0
  23. package/dist_ts/proxies/{network-proxy/network-proxy.d.ts → http-proxy/http-proxy.d.ts} +10 -9
  24. package/dist_ts/proxies/{network-proxy/network-proxy.js → http-proxy/http-proxy.js} +13 -12
  25. package/dist_ts/proxies/{network-proxy → http-proxy}/http-request-handler.js +1 -1
  26. package/dist_ts/proxies/http-proxy/http2-request-handler.js +201 -0
  27. package/dist_ts/proxies/{network-proxy → http-proxy}/index.d.ts +2 -2
  28. package/dist_ts/proxies/http-proxy/index.js +12 -0
  29. package/dist_ts/proxies/http-proxy/models/http-types.d.ts +119 -0
  30. package/dist_ts/proxies/http-proxy/models/http-types.js +112 -0
  31. package/dist_ts/proxies/http-proxy/models/index.d.ts +5 -0
  32. package/dist_ts/proxies/http-proxy/models/index.js +6 -0
  33. package/dist_ts/proxies/{network-proxy → http-proxy}/models/types.d.ts +2 -2
  34. package/dist_ts/proxies/http-proxy/models/types.js +276 -0
  35. package/dist_ts/proxies/{network-proxy → http-proxy}/request-handler.d.ts +3 -3
  36. package/dist_ts/proxies/{network-proxy → http-proxy}/request-handler.js +2 -2
  37. package/dist_ts/proxies/http-proxy/security-manager.js +255 -0
  38. package/dist_ts/proxies/{network-proxy → http-proxy}/websocket-handler.d.ts +3 -3
  39. package/dist_ts/proxies/{network-proxy → http-proxy}/websocket-handler.js +2 -2
  40. package/dist_ts/proxies/index.d.ts +5 -5
  41. package/dist_ts/proxies/index.js +5 -5
  42. package/dist_ts/proxies/smart-proxy/certificate-manager.d.ts +4 -4
  43. package/dist_ts/proxies/smart-proxy/certificate-manager.js +11 -11
  44. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +41 -0
  45. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +121 -0
  46. package/dist_ts/proxies/smart-proxy/index.d.ts +2 -1
  47. package/dist_ts/proxies/smart-proxy/index.js +4 -2
  48. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +2 -2
  49. package/dist_ts/proxies/smart-proxy/port-manager.js +3 -3
  50. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +3 -3
  51. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +24 -265
  52. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +1 -1
  53. package/dist_ts/proxies/smart-proxy/smart-proxy.js +25 -25
  54. package/dist_ts/routing/index.d.ts +5 -0
  55. package/dist_ts/routing/index.js +8 -0
  56. package/dist_ts/routing/models/http-types.d.ts +6 -0
  57. package/dist_ts/routing/models/http-types.js +7 -0
  58. package/dist_ts/routing/router/index.d.ts +8 -0
  59. package/dist_ts/routing/router/index.js +7 -0
  60. package/dist_ts/{classes.router.d.ts → routing/router/proxy-router.d.ts} +14 -11
  61. package/dist_ts/{classes.router.js → routing/router/proxy-router.js} +2 -2
  62. package/dist_ts/routing/router/route-router.d.ts +108 -0
  63. package/dist_ts/routing/router/route-router.js +393 -0
  64. package/package.json +1 -1
  65. package/readme.md +18 -35
  66. package/readme.plan.md +173 -271
  67. package/ts/00_commitinfo_data.ts +1 -1
  68. package/ts/forwarding/factory/forwarding-factory.ts +28 -0
  69. package/ts/index.ts +13 -9
  70. package/ts/proxies/{network-proxy → http-proxy}/certificate-manager.ts +2 -2
  71. package/ts/proxies/{network-proxy → http-proxy}/connection-pool.ts +2 -2
  72. package/ts/proxies/http-proxy/handlers/index.ts +6 -0
  73. package/ts/proxies/http-proxy/handlers/redirect-handler.ts +105 -0
  74. package/ts/proxies/http-proxy/handlers/static-handler.ts +251 -0
  75. package/ts/proxies/{network-proxy/network-proxy.ts → http-proxy/http-proxy.ts} +15 -14
  76. package/ts/proxies/{network-proxy → http-proxy}/index.ts +3 -3
  77. package/ts/proxies/http-proxy/models/http-types.ts +165 -0
  78. package/ts/proxies/http-proxy/models/index.ts +5 -0
  79. package/ts/proxies/{network-proxy → http-proxy}/models/types.ts +2 -2
  80. package/ts/proxies/{network-proxy → http-proxy}/request-handler.ts +3 -3
  81. package/ts/proxies/{network-proxy → http-proxy}/websocket-handler.ts +3 -3
  82. package/ts/proxies/index.ts +7 -7
  83. package/ts/proxies/smart-proxy/certificate-manager.ts +10 -10
  84. package/ts/proxies/smart-proxy/{network-proxy-bridge.ts → http-proxy-bridge.ts} +44 -44
  85. package/ts/proxies/smart-proxy/index.ts +4 -1
  86. package/ts/proxies/smart-proxy/models/interfaces.ts +3 -3
  87. package/ts/proxies/smart-proxy/port-manager.ts +2 -2
  88. package/ts/proxies/smart-proxy/route-connection-handler.ts +23 -307
  89. package/ts/proxies/smart-proxy/smart-proxy.ts +25 -25
  90. package/ts/routing/index.ts +9 -0
  91. package/ts/routing/models/http-types.ts +6 -0
  92. package/ts/{http → routing}/router/proxy-router.ts +1 -1
  93. package/ts/{http → routing}/router/route-router.ts +1 -1
  94. package/dist_ts/certificate/acme/acme-factory.d.ts +0 -17
  95. package/dist_ts/certificate/acme/acme-factory.js +0 -40
  96. package/dist_ts/certificate/acme/challenge-handler.d.ts +0 -44
  97. package/dist_ts/certificate/acme/challenge-handler.js +0 -92
  98. package/dist_ts/certificate/acme/index.d.ts +0 -4
  99. package/dist_ts/certificate/acme/index.js +0 -5
  100. package/dist_ts/certificate/certificate-manager.d.ts +0 -150
  101. package/dist_ts/certificate/certificate-manager.js +0 -505
  102. package/dist_ts/certificate/events/certificate-events.d.ts +0 -33
  103. package/dist_ts/certificate/events/certificate-events.js +0 -38
  104. package/dist_ts/certificate/events/simplified-events.d.ts +0 -56
  105. package/dist_ts/certificate/events/simplified-events.js +0 -13
  106. package/dist_ts/certificate/index.d.ts +0 -30
  107. package/dist_ts/certificate/index.js +0 -37
  108. package/dist_ts/certificate/models/certificate-errors.d.ts +0 -69
  109. package/dist_ts/certificate/models/certificate-errors.js +0 -141
  110. package/dist_ts/certificate/models/certificate-strategy.d.ts +0 -60
  111. package/dist_ts/certificate/models/certificate-strategy.js +0 -73
  112. package/dist_ts/certificate/models/certificate-types.d.ts +0 -97
  113. package/dist_ts/certificate/models/certificate-types.js +0 -2
  114. package/dist_ts/certificate/providers/cert-provisioner.d.ts +0 -119
  115. package/dist_ts/certificate/providers/cert-provisioner.js +0 -422
  116. package/dist_ts/certificate/providers/index.d.ts +0 -4
  117. package/dist_ts/certificate/providers/index.js +0 -5
  118. package/dist_ts/certificate/simplified-certificate-manager.d.ts +0 -150
  119. package/dist_ts/certificate/simplified-certificate-manager.js +0 -501
  120. package/dist_ts/certificate/storage/file-storage.d.ts +0 -66
  121. package/dist_ts/certificate/storage/file-storage.js +0 -194
  122. package/dist_ts/certificate/storage/index.d.ts +0 -4
  123. package/dist_ts/certificate/storage/index.js +0 -5
  124. package/dist_ts/certificate/utils/certificate-helpers.d.ts +0 -17
  125. package/dist_ts/certificate/utils/certificate-helpers.js +0 -45
  126. package/dist_ts/classes.iptablesproxy.d.ts +0 -112
  127. package/dist_ts/classes.iptablesproxy.js +0 -765
  128. package/dist_ts/classes.networkproxy.d.ts +0 -243
  129. package/dist_ts/classes.networkproxy.js +0 -1424
  130. package/dist_ts/classes.nftablesproxy.d.ts +0 -219
  131. package/dist_ts/classes.nftablesproxy.js +0 -1542
  132. package/dist_ts/classes.port80handler.d.ts +0 -215
  133. package/dist_ts/classes.port80handler.js +0 -736
  134. package/dist_ts/classes.portproxy.d.ts +0 -171
  135. package/dist_ts/classes.portproxy.js +0 -1802
  136. package/dist_ts/classes.pp.acmemanager.d.ts +0 -34
  137. package/dist_ts/classes.pp.acmemanager.js +0 -123
  138. package/dist_ts/classes.pp.connectionhandler.d.ts +0 -39
  139. package/dist_ts/classes.pp.connectionhandler.js +0 -754
  140. package/dist_ts/classes.pp.connectionmanager.d.ts +0 -78
  141. package/dist_ts/classes.pp.connectionmanager.js +0 -378
  142. package/dist_ts/classes.pp.domainconfigmanager.d.ts +0 -55
  143. package/dist_ts/classes.pp.domainconfigmanager.js +0 -103
  144. package/dist_ts/classes.pp.interfaces.d.ts +0 -133
  145. package/dist_ts/classes.pp.interfaces.js +0 -2
  146. package/dist_ts/classes.pp.networkproxybridge.d.ts +0 -57
  147. package/dist_ts/classes.pp.networkproxybridge.js +0 -306
  148. package/dist_ts/classes.pp.portproxy.d.ts +0 -64
  149. package/dist_ts/classes.pp.portproxy.js +0 -567
  150. package/dist_ts/classes.pp.portrangemanager.d.ts +0 -56
  151. package/dist_ts/classes.pp.portrangemanager.js +0 -179
  152. package/dist_ts/classes.pp.securitymanager.d.ts +0 -47
  153. package/dist_ts/classes.pp.securitymanager.js +0 -126
  154. package/dist_ts/classes.pp.snihandler.d.ts +0 -153
  155. package/dist_ts/classes.pp.snihandler.js +0 -1053
  156. package/dist_ts/classes.pp.timeoutmanager.d.ts +0 -47
  157. package/dist_ts/classes.pp.timeoutmanager.js +0 -154
  158. package/dist_ts/classes.pp.tlsalert.d.ts +0 -149
  159. package/dist_ts/classes.pp.tlsalert.js +0 -225
  160. package/dist_ts/classes.pp.tlsmanager.d.ts +0 -57
  161. package/dist_ts/classes.pp.tlsmanager.js +0 -132
  162. package/dist_ts/classes.snihandler.d.ts +0 -198
  163. package/dist_ts/classes.snihandler.js +0 -1210
  164. package/dist_ts/classes.sslredirect.d.ts +0 -8
  165. package/dist_ts/classes.sslredirect.js +0 -28
  166. package/dist_ts/common/acmeFactory.d.ts +0 -9
  167. package/dist_ts/common/acmeFactory.js +0 -20
  168. package/dist_ts/common/port80-adapter.d.ts +0 -11
  169. package/dist_ts/common/port80-adapter.js +0 -87
  170. package/dist_ts/examples/forwarding-example.d.ts +0 -1
  171. package/dist_ts/examples/forwarding-example.js +0 -96
  172. package/dist_ts/forwarding/config/domain-config.d.ts +0 -12
  173. package/dist_ts/forwarding/config/domain-config.js +0 -12
  174. package/dist_ts/forwarding/config/domain-manager.d.ts +0 -86
  175. package/dist_ts/forwarding/config/domain-manager.js +0 -242
  176. package/dist_ts/helpers.certificates.d.ts +0 -5
  177. package/dist_ts/helpers.certificates.js +0 -23
  178. package/dist_ts/http/port80/acme-interfaces.d.ts +0 -108
  179. package/dist_ts/http/port80/acme-interfaces.js +0 -51
  180. package/dist_ts/http/port80/challenge-responder.d.ts +0 -53
  181. package/dist_ts/http/port80/challenge-responder.js +0 -203
  182. package/dist_ts/http/port80/index.d.ts +0 -6
  183. package/dist_ts/http/port80/index.js +0 -9
  184. package/dist_ts/http/port80/port80-handler.d.ts +0 -136
  185. package/dist_ts/http/port80/port80-handler.js +0 -592
  186. package/dist_ts/http/redirects/index.d.ts +0 -4
  187. package/dist_ts/http/redirects/index.js +0 -5
  188. package/dist_ts/networkproxy/classes.np.certificatemanager.d.ts +0 -77
  189. package/dist_ts/networkproxy/classes.np.certificatemanager.js +0 -372
  190. package/dist_ts/networkproxy/classes.np.connectionpool.d.ts +0 -47
  191. package/dist_ts/networkproxy/classes.np.connectionpool.js +0 -210
  192. package/dist_ts/networkproxy/classes.np.networkproxy.d.ts +0 -118
  193. package/dist_ts/networkproxy/classes.np.networkproxy.js +0 -387
  194. package/dist_ts/networkproxy/classes.np.requesthandler.d.ts +0 -56
  195. package/dist_ts/networkproxy/classes.np.requesthandler.js +0 -393
  196. package/dist_ts/networkproxy/classes.np.types.d.ts +0 -83
  197. package/dist_ts/networkproxy/classes.np.types.js +0 -35
  198. package/dist_ts/networkproxy/classes.np.websockethandler.d.ts +0 -38
  199. package/dist_ts/networkproxy/classes.np.websockethandler.js +0 -188
  200. package/dist_ts/networkproxy/index.d.ts +0 -1
  201. package/dist_ts/networkproxy/index.js +0 -4
  202. package/dist_ts/nfttablesproxy/classes.nftablesproxy.d.ts +0 -219
  203. package/dist_ts/nfttablesproxy/classes.nftablesproxy.js +0 -1542
  204. package/dist_ts/port80handler/classes.port80handler.d.ts +0 -10
  205. package/dist_ts/port80handler/classes.port80handler.js +0 -16
  206. package/dist_ts/proxies/network-proxy/connection-pool.js +0 -210
  207. package/dist_ts/proxies/network-proxy/context-creator.js +0 -108
  208. package/dist_ts/proxies/network-proxy/http2-request-handler.js +0 -201
  209. package/dist_ts/proxies/network-proxy/index.js +0 -12
  210. package/dist_ts/proxies/network-proxy/models/index.d.ts +0 -4
  211. package/dist_ts/proxies/network-proxy/models/index.js +0 -5
  212. package/dist_ts/proxies/network-proxy/models/types.js +0 -276
  213. package/dist_ts/proxies/network-proxy/security-manager.js +0 -255
  214. package/dist_ts/proxies/network-proxy/simplified-certificate-bridge.d.ts +0 -48
  215. package/dist_ts/proxies/network-proxy/simplified-certificate-bridge.js +0 -76
  216. package/dist_ts/proxies/smart-proxy/connection-handler.d.ts +0 -39
  217. package/dist_ts/proxies/smart-proxy/connection-handler.js +0 -894
  218. package/dist_ts/proxies/smart-proxy/domain-config-manager.d.ts +0 -110
  219. package/dist_ts/proxies/smart-proxy/domain-config-manager.js +0 -386
  220. package/dist_ts/proxies/smart-proxy/legacy-smart-proxy.d.ts +0 -168
  221. package/dist_ts/proxies/smart-proxy/legacy-smart-proxy.js +0 -642
  222. package/dist_ts/proxies/smart-proxy/models/simplified-smartproxy-config.d.ts +0 -65
  223. package/dist_ts/proxies/smart-proxy/models/simplified-smartproxy-config.js +0 -31
  224. package/dist_ts/proxies/smart-proxy/models/smartproxy-options.d.ts +0 -102
  225. package/dist_ts/proxies/smart-proxy/models/smartproxy-options.js +0 -73
  226. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.d.ts +0 -41
  227. package/dist_ts/proxies/smart-proxy/network-proxy-bridge.js +0 -121
  228. package/dist_ts/proxies/smart-proxy/port-range-manager.d.ts +0 -56
  229. package/dist_ts/proxies/smart-proxy/port-range-manager.js +0 -176
  230. package/dist_ts/proxies/smart-proxy/route-helpers/index.d.ts +0 -9
  231. package/dist_ts/proxies/smart-proxy/route-helpers/index.js +0 -11
  232. package/dist_ts/proxies/smart-proxy/route-helpers.d.ts +0 -7
  233. package/dist_ts/proxies/smart-proxy/route-helpers.js +0 -9
  234. package/dist_ts/proxies/smart-proxy/simplified-smart-proxy.d.ts +0 -41
  235. package/dist_ts/proxies/smart-proxy/simplified-smart-proxy.js +0 -132
  236. package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.d.ts +0 -51
  237. package/dist_ts/proxies/smart-proxy/utils/route-migration-utils.js +0 -124
  238. package/dist_ts/redirect/classes.redirect.d.ts +0 -96
  239. package/dist_ts/redirect/classes.redirect.js +0 -194
  240. package/dist_ts/smartproxy/classes.pp.certprovisioner.d.ts +0 -54
  241. package/dist_ts/smartproxy/classes.pp.certprovisioner.js +0 -179
  242. package/dist_ts/smartproxy/classes.pp.connectionhandler.d.ts +0 -39
  243. package/dist_ts/smartproxy/classes.pp.connectionhandler.js +0 -894
  244. package/dist_ts/smartproxy/classes.pp.connectionmanager.d.ts +0 -78
  245. package/dist_ts/smartproxy/classes.pp.connectionmanager.js +0 -378
  246. package/dist_ts/smartproxy/classes.pp.domainconfigmanager.d.ts +0 -94
  247. package/dist_ts/smartproxy/classes.pp.domainconfigmanager.js +0 -255
  248. package/dist_ts/smartproxy/classes.pp.interfaces.d.ts +0 -103
  249. package/dist_ts/smartproxy/classes.pp.interfaces.js +0 -2
  250. package/dist_ts/smartproxy/classes.pp.networkproxybridge.d.ts +0 -62
  251. package/dist_ts/smartproxy/classes.pp.networkproxybridge.js +0 -316
  252. package/dist_ts/smartproxy/classes.pp.portrangemanager.d.ts +0 -56
  253. package/dist_ts/smartproxy/classes.pp.portrangemanager.js +0 -176
  254. package/dist_ts/smartproxy/classes.pp.securitymanager.d.ts +0 -64
  255. package/dist_ts/smartproxy/classes.pp.securitymanager.js +0 -149
  256. package/dist_ts/smartproxy/classes.pp.snihandler.d.ts +0 -153
  257. package/dist_ts/smartproxy/classes.pp.snihandler.js +0 -1053
  258. package/dist_ts/smartproxy/classes.pp.timeoutmanager.d.ts +0 -47
  259. package/dist_ts/smartproxy/classes.pp.timeoutmanager.js +0 -154
  260. package/dist_ts/smartproxy/classes.pp.tlsalert.d.ts +0 -149
  261. package/dist_ts/smartproxy/classes.pp.tlsalert.js +0 -225
  262. package/dist_ts/smartproxy/classes.pp.tlsmanager.d.ts +0 -57
  263. package/dist_ts/smartproxy/classes.pp.tlsmanager.js +0 -132
  264. package/dist_ts/smartproxy/classes.smartproxy.d.ts +0 -63
  265. package/dist_ts/smartproxy/classes.smartproxy.js +0 -521
  266. package/dist_ts/smartproxy/forwarding/domain-config.d.ts +0 -12
  267. package/dist_ts/smartproxy/forwarding/domain-config.js +0 -12
  268. package/dist_ts/smartproxy/forwarding/domain-manager.d.ts +0 -86
  269. package/dist_ts/smartproxy/forwarding/domain-manager.js +0 -241
  270. package/dist_ts/smartproxy/forwarding/forwarding.factory.d.ts +0 -24
  271. package/dist_ts/smartproxy/forwarding/forwarding.factory.js +0 -137
  272. package/dist_ts/smartproxy/forwarding/forwarding.handler.d.ts +0 -55
  273. package/dist_ts/smartproxy/forwarding/forwarding.handler.js +0 -94
  274. package/dist_ts/smartproxy/forwarding/http.handler.d.ts +0 -25
  275. package/dist_ts/smartproxy/forwarding/http.handler.js +0 -123
  276. package/dist_ts/smartproxy/forwarding/https-passthrough.handler.d.ts +0 -24
  277. package/dist_ts/smartproxy/forwarding/https-passthrough.handler.js +0 -154
  278. package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.d.ts +0 -36
  279. package/dist_ts/smartproxy/forwarding/https-terminate-to-http.handler.js +0 -229
  280. package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.d.ts +0 -35
  281. package/dist_ts/smartproxy/forwarding/https-terminate-to-https.handler.js +0 -254
  282. package/dist_ts/smartproxy/forwarding/index.d.ts +0 -16
  283. package/dist_ts/smartproxy/forwarding/index.js +0 -23
  284. package/dist_ts/smartproxy/types/forwarding.types.d.ts +0 -104
  285. package/dist_ts/smartproxy/types/forwarding.types.js +0 -50
  286. package/dist_ts/smartproxy.classes.networkproxy.d.ts +0 -31
  287. package/dist_ts/smartproxy.classes.networkproxy.js +0 -305
  288. package/dist_ts/smartproxy.classes.router.d.ts +0 -13
  289. package/dist_ts/smartproxy.classes.router.js +0 -33
  290. package/dist_ts/smartproxy.classes.sslredirect.d.ts +0 -8
  291. package/dist_ts/smartproxy.classes.sslredirect.js +0 -28
  292. package/dist_ts/smartproxy.helpers.certificates.d.ts +0 -5
  293. package/dist_ts/smartproxy.helpers.certificates.js +0 -23
  294. package/dist_ts/smartproxy.plugins.d.ts +0 -18
  295. package/dist_ts/smartproxy.plugins.js +0 -23
  296. package/dist_ts/smartproxy.portproxy.d.ts +0 -26
  297. package/dist_ts/smartproxy.portproxy.js +0 -295
  298. package/ts/http/index.ts +0 -16
  299. package/ts/http/models/http-types.ts +0 -108
  300. package/ts/http/redirects/index.ts +0 -3
  301. package/ts/proxies/network-proxy/models/index.ts +0 -4
  302. package/ts/redirect/classes.redirect.ts +0 -295
  303. /package/dist_ts/proxies/{network-proxy → http-proxy}/context-creator.d.ts +0 -0
  304. /package/dist_ts/proxies/{network-proxy → http-proxy}/function-cache.d.ts +0 -0
  305. /package/dist_ts/proxies/{network-proxy → http-proxy}/http-request-handler.d.ts +0 -0
  306. /package/dist_ts/proxies/{network-proxy → http-proxy}/http2-request-handler.d.ts +0 -0
  307. /package/dist_ts/proxies/{network-proxy → http-proxy}/security-manager.d.ts +0 -0
  308. /package/ts/proxies/{network-proxy → http-proxy}/context-creator.ts +0 -0
  309. /package/ts/proxies/{network-proxy → http-proxy}/function-cache.ts +0 -0
  310. /package/ts/proxies/{network-proxy → http-proxy}/http-request-handler.ts +0 -0
  311. /package/ts/proxies/{network-proxy → http-proxy}/http2-request-handler.ts +0 -0
  312. /package/ts/proxies/{network-proxy → http-proxy}/security-manager.ts +0 -0
  313. /package/ts/{http → routing}/router/index.ts +0 -0
@@ -1,765 +0,0 @@
1
- import { exec, execSync } from 'child_process';
2
- import { promisify } from 'util';
3
- const execAsync = promisify(exec);
4
- /**
5
- * IPTablesProxy sets up iptables NAT rules to forward TCP traffic.
6
- * Enhanced with multi-port support, IPv6, and integration with PortProxy/NetworkProxy.
7
- */
8
- export class IPTablesProxy {
9
- constructor(settings) {
10
- this.rules = [];
11
- this.customChain = null;
12
- // Validate inputs to prevent command injection
13
- this.validateSettings(settings);
14
- // Set default settings
15
- this.settings = {
16
- ...settings,
17
- toHost: settings.toHost || 'localhost',
18
- protocol: settings.protocol || 'tcp',
19
- enableLogging: settings.enableLogging !== undefined ? settings.enableLogging : false,
20
- ipv6Support: settings.ipv6Support !== undefined ? settings.ipv6Support : false,
21
- checkExistingRules: settings.checkExistingRules !== undefined ? settings.checkExistingRules : true,
22
- netProxyIntegration: settings.netProxyIntegration || { enabled: false }
23
- };
24
- // Generate a unique identifier for the rules added by this instance
25
- this.ruleTag = `IPTablesProxy:${Date.now()}:${Math.random().toString(36).substr(2, 5)}`;
26
- if (this.settings.addJumpRule) {
27
- this.customChain = `IPTablesProxy_${Math.random().toString(36).substr(2, 5)}`;
28
- }
29
- // Register cleanup handlers if deleteOnExit is true
30
- if (this.settings.deleteOnExit) {
31
- const cleanup = () => {
32
- try {
33
- this.stopSync();
34
- }
35
- catch (err) {
36
- console.error('Error cleaning iptables rules on exit:', err);
37
- }
38
- };
39
- process.on('exit', cleanup);
40
- process.on('SIGINT', () => {
41
- cleanup();
42
- process.exit();
43
- });
44
- process.on('SIGTERM', () => {
45
- cleanup();
46
- process.exit();
47
- });
48
- }
49
- }
50
- /**
51
- * Validates settings to prevent command injection and ensure valid values
52
- */
53
- validateSettings(settings) {
54
- // Validate port numbers
55
- const validatePorts = (port) => {
56
- if (Array.isArray(port)) {
57
- port.forEach(p => validatePorts(p));
58
- return;
59
- }
60
- if (typeof port === 'number') {
61
- if (port < 1 || port > 65535) {
62
- throw new Error(`Invalid port number: ${port}`);
63
- }
64
- }
65
- else if (typeof port === 'object') {
66
- if (port.from < 1 || port.from > 65535 || port.to < 1 || port.to > 65535 || port.from > port.to) {
67
- throw new Error(`Invalid port range: ${port.from}-${port.to}`);
68
- }
69
- }
70
- };
71
- validatePorts(settings.fromPort);
72
- validatePorts(settings.toPort);
73
- // Define regex patterns at the method level so they're available throughout
74
- const ipRegex = /^(([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]))?$/;
75
- const ipv6Regex = /^(([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]))?$/;
76
- // Validate IP addresses
77
- const validateIPs = (ips) => {
78
- if (!ips)
79
- return;
80
- for (const ip of ips) {
81
- if (!ipRegex.test(ip) && !ipv6Regex.test(ip)) {
82
- throw new Error(`Invalid IP address format: ${ip}`);
83
- }
84
- }
85
- };
86
- validateIPs(settings.allowedSourceIPs);
87
- validateIPs(settings.bannedSourceIPs);
88
- // Validate toHost - only allow hostnames or IPs
89
- if (settings.toHost) {
90
- const hostRegex = /^(([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])$/;
91
- if (!hostRegex.test(settings.toHost) && !ipRegex.test(settings.toHost) && !ipv6Regex.test(settings.toHost)) {
92
- throw new Error(`Invalid host format: ${settings.toHost}`);
93
- }
94
- }
95
- }
96
- /**
97
- * Normalizes port specifications into an array of port ranges
98
- */
99
- normalizePortSpec(portSpec) {
100
- const result = [];
101
- if (Array.isArray(portSpec)) {
102
- // If it's an array, process each element
103
- for (const spec of portSpec) {
104
- result.push(...this.normalizePortSpec(spec));
105
- }
106
- }
107
- else if (typeof portSpec === 'number') {
108
- // Single port becomes a range with the same start and end
109
- result.push({ from: portSpec, to: portSpec });
110
- }
111
- else {
112
- // Already a range
113
- result.push(portSpec);
114
- }
115
- return result;
116
- }
117
- /**
118
- * Gets the appropriate iptables command based on settings
119
- */
120
- getIptablesCommand(isIpv6 = false) {
121
- return isIpv6 ? 'ip6tables' : 'iptables';
122
- }
123
- /**
124
- * Checks if a rule already exists in iptables
125
- */
126
- async ruleExists(table, command, isIpv6 = false) {
127
- try {
128
- const iptablesCmd = this.getIptablesCommand(isIpv6);
129
- const { stdout } = await execAsync(`${iptablesCmd}-save -t ${table}`);
130
- // Convert the command to the format found in iptables-save output
131
- // (This is a simplification - in reality, you'd need more parsing)
132
- const rulePattern = command.replace(`${iptablesCmd} -t ${table} -A `, '-A ');
133
- return stdout.split('\n').some(line => line.trim() === rulePattern);
134
- }
135
- catch (err) {
136
- this.log('error', `Failed to check if rule exists: ${err}`);
137
- return false;
138
- }
139
- }
140
- /**
141
- * Sets up a custom chain for better rule management
142
- */
143
- async setupCustomChain(isIpv6 = false) {
144
- if (!this.customChain)
145
- return true;
146
- const iptablesCmd = this.getIptablesCommand(isIpv6);
147
- const table = 'nat';
148
- try {
149
- // Create the chain
150
- await execAsync(`${iptablesCmd} -t ${table} -N ${this.customChain}`);
151
- this.log('info', `Created custom chain: ${this.customChain}`);
152
- // Add jump rule to PREROUTING chain
153
- const jumpCommand = `${iptablesCmd} -t ${table} -A PREROUTING -j ${this.customChain} -m comment --comment "${this.ruleTag}:JUMP"`;
154
- await execAsync(jumpCommand);
155
- this.log('info', `Added jump rule to ${this.customChain}`);
156
- // Store the jump rule
157
- this.rules.push({
158
- table,
159
- chain: 'PREROUTING',
160
- command: jumpCommand,
161
- tag: `${this.ruleTag}:JUMP`,
162
- added: true
163
- });
164
- return true;
165
- }
166
- catch (err) {
167
- this.log('error', `Failed to set up custom chain: ${err}`);
168
- return false;
169
- }
170
- }
171
- /**
172
- * Add a source IP filter rule
173
- */
174
- async addSourceIPFilter(isIpv6 = false) {
175
- if (!this.settings.allowedSourceIPs && !this.settings.bannedSourceIPs) {
176
- return true;
177
- }
178
- const iptablesCmd = this.getIptablesCommand(isIpv6);
179
- const table = 'nat';
180
- const chain = this.customChain || 'PREROUTING';
181
- try {
182
- // Add banned IPs first (explicit deny)
183
- if (this.settings.bannedSourceIPs && this.settings.bannedSourceIPs.length > 0) {
184
- for (const ip of this.settings.bannedSourceIPs) {
185
- const command = `${iptablesCmd} -t ${table} -A ${chain} -s ${ip} -j DROP -m comment --comment "${this.ruleTag}:BANNED"`;
186
- // Check if rule already exists
187
- if (this.settings.checkExistingRules && await this.ruleExists(table, command, isIpv6)) {
188
- this.log('info', `Rule already exists, skipping: ${command}`);
189
- continue;
190
- }
191
- await execAsync(command);
192
- this.log('info', `Added banned IP rule: ${command}`);
193
- this.rules.push({
194
- table,
195
- chain,
196
- command,
197
- tag: `${this.ruleTag}:BANNED`,
198
- added: true
199
- });
200
- }
201
- }
202
- // Add allowed IPs (explicit allow)
203
- if (this.settings.allowedSourceIPs && this.settings.allowedSourceIPs.length > 0) {
204
- // First add a default deny for all
205
- const denyAllCommand = `${iptablesCmd} -t ${table} -A ${chain} -p ${this.settings.protocol} -j DROP -m comment --comment "${this.ruleTag}:DENY_ALL"`;
206
- // Add allow rules for specific IPs
207
- for (const ip of this.settings.allowedSourceIPs) {
208
- const command = `${iptablesCmd} -t ${table} -A ${chain} -s ${ip} -p ${this.settings.protocol} -j ACCEPT -m comment --comment "${this.ruleTag}:ALLOWED"`;
209
- // Check if rule already exists
210
- if (this.settings.checkExistingRules && await this.ruleExists(table, command, isIpv6)) {
211
- this.log('info', `Rule already exists, skipping: ${command}`);
212
- continue;
213
- }
214
- await execAsync(command);
215
- this.log('info', `Added allowed IP rule: ${command}`);
216
- this.rules.push({
217
- table,
218
- chain,
219
- command,
220
- tag: `${this.ruleTag}:ALLOWED`,
221
- added: true
222
- });
223
- }
224
- // Now add the default deny after all allows
225
- if (this.settings.checkExistingRules && await this.ruleExists(table, denyAllCommand, isIpv6)) {
226
- this.log('info', `Rule already exists, skipping: ${denyAllCommand}`);
227
- }
228
- else {
229
- await execAsync(denyAllCommand);
230
- this.log('info', `Added default deny rule: ${denyAllCommand}`);
231
- this.rules.push({
232
- table,
233
- chain,
234
- command: denyAllCommand,
235
- tag: `${this.ruleTag}:DENY_ALL`,
236
- added: true
237
- });
238
- }
239
- }
240
- return true;
241
- }
242
- catch (err) {
243
- this.log('error', `Failed to add source IP filter rules: ${err}`);
244
- return false;
245
- }
246
- }
247
- /**
248
- * Adds a port forwarding rule
249
- */
250
- async addPortForwardingRule(fromPortRange, toPortRange, isIpv6 = false) {
251
- const iptablesCmd = this.getIptablesCommand(isIpv6);
252
- const table = 'nat';
253
- const chain = this.customChain || 'PREROUTING';
254
- try {
255
- // Handle single port case
256
- if (fromPortRange.from === fromPortRange.to && toPortRange.from === toPortRange.to) {
257
- // Single port forward
258
- const command = `${iptablesCmd} -t ${table} -A ${chain} -p ${this.settings.protocol} --dport ${fromPortRange.from} ` +
259
- `-j DNAT --to-destination ${this.settings.toHost}:${toPortRange.from} ` +
260
- `-m comment --comment "${this.ruleTag}:DNAT"`;
261
- // Check if rule already exists
262
- if (this.settings.checkExistingRules && await this.ruleExists(table, command, isIpv6)) {
263
- this.log('info', `Rule already exists, skipping: ${command}`);
264
- }
265
- else {
266
- await execAsync(command);
267
- this.log('info', `Added port forwarding rule: ${command}`);
268
- this.rules.push({
269
- table,
270
- chain,
271
- command,
272
- tag: `${this.ruleTag}:DNAT`,
273
- added: true
274
- });
275
- }
276
- }
277
- else if (fromPortRange.to - fromPortRange.from === toPortRange.to - toPortRange.from) {
278
- // Port range forward with equal ranges
279
- const command = `${iptablesCmd} -t ${table} -A ${chain} -p ${this.settings.protocol} --dport ${fromPortRange.from}:${fromPortRange.to} ` +
280
- `-j DNAT --to-destination ${this.settings.toHost}:${toPortRange.from}-${toPortRange.to} ` +
281
- `-m comment --comment "${this.ruleTag}:DNAT_RANGE"`;
282
- // Check if rule already exists
283
- if (this.settings.checkExistingRules && await this.ruleExists(table, command, isIpv6)) {
284
- this.log('info', `Rule already exists, skipping: ${command}`);
285
- }
286
- else {
287
- await execAsync(command);
288
- this.log('info', `Added port range forwarding rule: ${command}`);
289
- this.rules.push({
290
- table,
291
- chain,
292
- command,
293
- tag: `${this.ruleTag}:DNAT_RANGE`,
294
- added: true
295
- });
296
- }
297
- }
298
- else {
299
- // Unequal port ranges need individual rules
300
- for (let i = 0; i <= fromPortRange.to - fromPortRange.from; i++) {
301
- const fromPort = fromPortRange.from + i;
302
- const toPort = toPortRange.from + i % (toPortRange.to - toPortRange.from + 1);
303
- const command = `${iptablesCmd} -t ${table} -A ${chain} -p ${this.settings.protocol} --dport ${fromPort} ` +
304
- `-j DNAT --to-destination ${this.settings.toHost}:${toPort} ` +
305
- `-m comment --comment "${this.ruleTag}:DNAT_INDIVIDUAL"`;
306
- // Check if rule already exists
307
- if (this.settings.checkExistingRules && await this.ruleExists(table, command, isIpv6)) {
308
- this.log('info', `Rule already exists, skipping: ${command}`);
309
- continue;
310
- }
311
- await execAsync(command);
312
- this.log('info', `Added individual port forwarding rule: ${command}`);
313
- this.rules.push({
314
- table,
315
- chain,
316
- command,
317
- tag: `${this.ruleTag}:DNAT_INDIVIDUAL`,
318
- added: true
319
- });
320
- }
321
- }
322
- // If preserveSourceIP is false, add a MASQUERADE rule
323
- if (!this.settings.preserveSourceIP) {
324
- // For port range
325
- const masqCommand = `${iptablesCmd} -t nat -A POSTROUTING -p ${this.settings.protocol} -d ${this.settings.toHost} ` +
326
- `--dport ${toPortRange.from}:${toPortRange.to} -j MASQUERADE ` +
327
- `-m comment --comment "${this.ruleTag}:MASQ"`;
328
- // Check if rule already exists
329
- if (this.settings.checkExistingRules && await this.ruleExists('nat', masqCommand, isIpv6)) {
330
- this.log('info', `Rule already exists, skipping: ${masqCommand}`);
331
- }
332
- else {
333
- await execAsync(masqCommand);
334
- this.log('info', `Added MASQUERADE rule: ${masqCommand}`);
335
- this.rules.push({
336
- table: 'nat',
337
- chain: 'POSTROUTING',
338
- command: masqCommand,
339
- tag: `${this.ruleTag}:MASQ`,
340
- added: true
341
- });
342
- }
343
- }
344
- return true;
345
- }
346
- catch (err) {
347
- this.log('error', `Failed to add port forwarding rule: ${err}`);
348
- // Try to roll back any rules that were already added
349
- await this.rollbackRules();
350
- return false;
351
- }
352
- }
353
- /**
354
- * Special handling for NetworkProxy integration
355
- */
356
- async setupNetworkProxyIntegration(isIpv6 = false) {
357
- if (!this.settings.netProxyIntegration?.enabled) {
358
- return true;
359
- }
360
- const netProxyConfig = this.settings.netProxyIntegration;
361
- const iptablesCmd = this.getIptablesCommand(isIpv6);
362
- const table = 'nat';
363
- const chain = this.customChain || 'PREROUTING';
364
- try {
365
- // If redirectLocalhost is true, set up special rule to redirect localhost traffic to NetworkProxy
366
- if (netProxyConfig.redirectLocalhost && netProxyConfig.sslTerminationPort) {
367
- const redirectCommand = `${iptablesCmd} -t ${table} -A OUTPUT -p tcp -d 127.0.0.1 -j REDIRECT ` +
368
- `--to-port ${netProxyConfig.sslTerminationPort} ` +
369
- `-m comment --comment "${this.ruleTag}:NETPROXY_REDIRECT"`;
370
- // Check if rule already exists
371
- if (this.settings.checkExistingRules && await this.ruleExists(table, redirectCommand, isIpv6)) {
372
- this.log('info', `Rule already exists, skipping: ${redirectCommand}`);
373
- }
374
- else {
375
- await execAsync(redirectCommand);
376
- this.log('info', `Added NetworkProxy redirection rule: ${redirectCommand}`);
377
- this.rules.push({
378
- table,
379
- chain: 'OUTPUT',
380
- command: redirectCommand,
381
- tag: `${this.ruleTag}:NETPROXY_REDIRECT`,
382
- added: true
383
- });
384
- }
385
- }
386
- return true;
387
- }
388
- catch (err) {
389
- this.log('error', `Failed to set up NetworkProxy integration: ${err}`);
390
- return false;
391
- }
392
- }
393
- /**
394
- * Rolls back rules that were added in case of error
395
- */
396
- async rollbackRules() {
397
- // Process rules in reverse order (LIFO)
398
- for (let i = this.rules.length - 1; i >= 0; i--) {
399
- const rule = this.rules[i];
400
- if (rule.added) {
401
- try {
402
- // Convert -A (add) to -D (delete)
403
- const deleteCommand = rule.command.replace('-A', '-D');
404
- await execAsync(deleteCommand);
405
- this.log('info', `Rolled back rule: ${deleteCommand}`);
406
- rule.added = false;
407
- }
408
- catch (err) {
409
- this.log('error', `Failed to roll back rule: ${err}`);
410
- }
411
- }
412
- }
413
- }
414
- /**
415
- * Sets up iptables rules for port forwarding with enhanced features
416
- */
417
- async start() {
418
- // Optionally clean the slate first
419
- if (this.settings.forceCleanSlate) {
420
- await IPTablesProxy.cleanSlate();
421
- }
422
- // First set up any custom chains
423
- if (this.settings.addJumpRule) {
424
- const chainSetupSuccess = await this.setupCustomChain();
425
- if (!chainSetupSuccess) {
426
- throw new Error('Failed to set up custom chain');
427
- }
428
- // For IPv6 if enabled
429
- if (this.settings.ipv6Support) {
430
- const chainSetupSuccessIpv6 = await this.setupCustomChain(true);
431
- if (!chainSetupSuccessIpv6) {
432
- this.log('warn', 'Failed to set up IPv6 custom chain, continuing with IPv4 only');
433
- }
434
- }
435
- }
436
- // Add source IP filters
437
- await this.addSourceIPFilter();
438
- if (this.settings.ipv6Support) {
439
- await this.addSourceIPFilter(true);
440
- }
441
- // Set up NetworkProxy integration if enabled
442
- if (this.settings.netProxyIntegration?.enabled) {
443
- const netProxySetupSuccess = await this.setupNetworkProxyIntegration();
444
- if (!netProxySetupSuccess) {
445
- this.log('warn', 'Failed to set up NetworkProxy integration');
446
- }
447
- if (this.settings.ipv6Support) {
448
- await this.setupNetworkProxyIntegration(true);
449
- }
450
- }
451
- // Normalize port specifications
452
- const fromPortRanges = this.normalizePortSpec(this.settings.fromPort);
453
- const toPortRanges = this.normalizePortSpec(this.settings.toPort);
454
- // Handle the case where fromPort and toPort counts don't match
455
- if (fromPortRanges.length !== toPortRanges.length) {
456
- if (toPortRanges.length === 1) {
457
- // If there's only one toPort, use it for all fromPorts
458
- for (const fromRange of fromPortRanges) {
459
- await this.addPortForwardingRule(fromRange, toPortRanges[0]);
460
- if (this.settings.ipv6Support) {
461
- await this.addPortForwardingRule(fromRange, toPortRanges[0], true);
462
- }
463
- }
464
- }
465
- else {
466
- throw new Error('Mismatched port counts: fromPort and toPort arrays must have equal length or toPort must be a single value');
467
- }
468
- }
469
- else {
470
- // Add port forwarding rules for each port specification
471
- for (let i = 0; i < fromPortRanges.length; i++) {
472
- await this.addPortForwardingRule(fromPortRanges[i], toPortRanges[i]);
473
- if (this.settings.ipv6Support) {
474
- await this.addPortForwardingRule(fromPortRanges[i], toPortRanges[i], true);
475
- }
476
- }
477
- }
478
- // Final check - ensure we have at least one rule added
479
- if (this.rules.filter(r => r.added).length === 0) {
480
- throw new Error('No rules were added');
481
- }
482
- }
483
- /**
484
- * Removes all added iptables rules
485
- */
486
- async stop() {
487
- // Process rules in reverse order (LIFO)
488
- for (let i = this.rules.length - 1; i >= 0; i--) {
489
- const rule = this.rules[i];
490
- if (rule.added) {
491
- try {
492
- // Convert -A (add) to -D (delete)
493
- const deleteCommand = rule.command.replace('-A', '-D');
494
- await execAsync(deleteCommand);
495
- this.log('info', `Removed rule: ${deleteCommand}`);
496
- rule.added = false;
497
- }
498
- catch (err) {
499
- this.log('error', `Failed to remove rule: ${err}`);
500
- }
501
- }
502
- }
503
- // If we created a custom chain, we need to clean it up
504
- if (this.customChain) {
505
- try {
506
- // First flush the chain
507
- await execAsync(`iptables -t nat -F ${this.customChain}`);
508
- this.log('info', `Flushed custom chain: ${this.customChain}`);
509
- // Then delete it
510
- await execAsync(`iptables -t nat -X ${this.customChain}`);
511
- this.log('info', `Deleted custom chain: ${this.customChain}`);
512
- // Same for IPv6 if enabled
513
- if (this.settings.ipv6Support) {
514
- try {
515
- await execAsync(`ip6tables -t nat -F ${this.customChain}`);
516
- await execAsync(`ip6tables -t nat -X ${this.customChain}`);
517
- this.log('info', `Deleted IPv6 custom chain: ${this.customChain}`);
518
- }
519
- catch (err) {
520
- this.log('error', `Failed to delete IPv6 custom chain: ${err}`);
521
- }
522
- }
523
- }
524
- catch (err) {
525
- this.log('error', `Failed to delete custom chain: ${err}`);
526
- }
527
- }
528
- // Clear rules array
529
- this.rules = [];
530
- }
531
- /**
532
- * Synchronous version of stop, for use in exit handlers
533
- */
534
- stopSync() {
535
- // Process rules in reverse order (LIFO)
536
- for (let i = this.rules.length - 1; i >= 0; i--) {
537
- const rule = this.rules[i];
538
- if (rule.added) {
539
- try {
540
- // Convert -A (add) to -D (delete)
541
- const deleteCommand = rule.command.replace('-A', '-D');
542
- execSync(deleteCommand);
543
- this.log('info', `Removed rule: ${deleteCommand}`);
544
- rule.added = false;
545
- }
546
- catch (err) {
547
- this.log('error', `Failed to remove rule: ${err}`);
548
- }
549
- }
550
- }
551
- // If we created a custom chain, we need to clean it up
552
- if (this.customChain) {
553
- try {
554
- // First flush the chain
555
- execSync(`iptables -t nat -F ${this.customChain}`);
556
- // Then delete it
557
- execSync(`iptables -t nat -X ${this.customChain}`);
558
- this.log('info', `Deleted custom chain: ${this.customChain}`);
559
- // Same for IPv6 if enabled
560
- if (this.settings.ipv6Support) {
561
- try {
562
- execSync(`ip6tables -t nat -F ${this.customChain}`);
563
- execSync(`ip6tables -t nat -X ${this.customChain}`);
564
- }
565
- catch (err) {
566
- // IPv6 failures are non-critical
567
- }
568
- }
569
- }
570
- catch (err) {
571
- this.log('error', `Failed to delete custom chain: ${err}`);
572
- }
573
- }
574
- // Clear rules array
575
- this.rules = [];
576
- }
577
- /**
578
- * Asynchronously cleans up any iptables rules in the nat table that were added by this module.
579
- * It looks for rules with comments containing "IPTablesProxy:".
580
- */
581
- static async cleanSlate() {
582
- await IPTablesProxy.cleanSlateInternal();
583
- // Also clean IPv6 rules
584
- await IPTablesProxy.cleanSlateInternal(true);
585
- }
586
- /**
587
- * Internal implementation of cleanSlate with IPv6 support
588
- */
589
- static async cleanSlateInternal(isIpv6 = false) {
590
- const iptablesCmd = isIpv6 ? 'ip6tables' : 'iptables';
591
- try {
592
- const { stdout } = await execAsync(`${iptablesCmd}-save -t nat`);
593
- const lines = stdout.split('\n');
594
- const proxyLines = lines.filter(line => line.includes('IPTablesProxy:'));
595
- // First, find and remove any custom chains
596
- const customChains = new Set();
597
- const jumpRules = [];
598
- for (const line of proxyLines) {
599
- if (line.includes('IPTablesProxy:JUMP')) {
600
- // Extract chain name from jump rule
601
- const match = line.match(/\s+-j\s+(\S+)\s+/);
602
- if (match && match[1].startsWith('IPTablesProxy_')) {
603
- customChains.add(match[1]);
604
- jumpRules.push(line);
605
- }
606
- }
607
- }
608
- // Remove jump rules first
609
- for (const line of jumpRules) {
610
- const trimmedLine = line.trim();
611
- if (trimmedLine.startsWith('-A')) {
612
- // Replace the "-A" with "-D" to form a deletion command
613
- const deleteRule = trimmedLine.replace('-A', '-D');
614
- const cmd = `${iptablesCmd} -t nat ${deleteRule}`;
615
- try {
616
- await execAsync(cmd);
617
- console.log(`Cleaned up iptables jump rule: ${cmd}`);
618
- }
619
- catch (err) {
620
- console.error(`Failed to remove iptables jump rule: ${cmd}`, err);
621
- }
622
- }
623
- }
624
- // Then remove all other rules
625
- for (const line of proxyLines) {
626
- if (!line.includes('IPTablesProxy:JUMP')) { // Skip jump rules we already handled
627
- const trimmedLine = line.trim();
628
- if (trimmedLine.startsWith('-A')) {
629
- // Replace the "-A" with "-D" to form a deletion command
630
- const deleteRule = trimmedLine.replace('-A', '-D');
631
- const cmd = `${iptablesCmd} -t nat ${deleteRule}`;
632
- try {
633
- await execAsync(cmd);
634
- console.log(`Cleaned up iptables rule: ${cmd}`);
635
- }
636
- catch (err) {
637
- console.error(`Failed to remove iptables rule: ${cmd}`, err);
638
- }
639
- }
640
- }
641
- }
642
- // Finally clean up custom chains
643
- for (const chain of customChains) {
644
- try {
645
- // Flush the chain
646
- await execAsync(`${iptablesCmd} -t nat -F ${chain}`);
647
- console.log(`Flushed custom chain: ${chain}`);
648
- // Delete the chain
649
- await execAsync(`${iptablesCmd} -t nat -X ${chain}`);
650
- console.log(`Deleted custom chain: ${chain}`);
651
- }
652
- catch (err) {
653
- console.error(`Failed to delete custom chain ${chain}:`, err);
654
- }
655
- }
656
- }
657
- catch (err) {
658
- console.error(`Failed to run ${iptablesCmd}-save: ${err}`);
659
- }
660
- }
661
- /**
662
- * Synchronously cleans up any iptables rules in the nat table that were added by this module.
663
- * It looks for rules with comments containing "IPTablesProxy:".
664
- * This method is intended for use in process exit handlers.
665
- */
666
- static cleanSlateSync() {
667
- IPTablesProxy.cleanSlateSyncInternal();
668
- // Also clean IPv6 rules
669
- IPTablesProxy.cleanSlateSyncInternal(true);
670
- }
671
- /**
672
- * Internal implementation of cleanSlateSync with IPv6 support
673
- */
674
- static cleanSlateSyncInternal(isIpv6 = false) {
675
- const iptablesCmd = isIpv6 ? 'ip6tables' : 'iptables';
676
- try {
677
- const stdout = execSync(`${iptablesCmd}-save -t nat`).toString();
678
- const lines = stdout.split('\n');
679
- const proxyLines = lines.filter(line => line.includes('IPTablesProxy:'));
680
- // First, find and remove any custom chains
681
- const customChains = new Set();
682
- const jumpRules = [];
683
- for (const line of proxyLines) {
684
- if (line.includes('IPTablesProxy:JUMP')) {
685
- // Extract chain name from jump rule
686
- const match = line.match(/\s+-j\s+(\S+)\s+/);
687
- if (match && match[1].startsWith('IPTablesProxy_')) {
688
- customChains.add(match[1]);
689
- jumpRules.push(line);
690
- }
691
- }
692
- }
693
- // Remove jump rules first
694
- for (const line of jumpRules) {
695
- const trimmedLine = line.trim();
696
- if (trimmedLine.startsWith('-A')) {
697
- // Replace the "-A" with "-D" to form a deletion command
698
- const deleteRule = trimmedLine.replace('-A', '-D');
699
- const cmd = `${iptablesCmd} -t nat ${deleteRule}`;
700
- try {
701
- execSync(cmd);
702
- console.log(`Cleaned up iptables jump rule: ${cmd}`);
703
- }
704
- catch (err) {
705
- console.error(`Failed to remove iptables jump rule: ${cmd}`, err);
706
- }
707
- }
708
- }
709
- // Then remove all other rules
710
- for (const line of proxyLines) {
711
- if (!line.includes('IPTablesProxy:JUMP')) { // Skip jump rules we already handled
712
- const trimmedLine = line.trim();
713
- if (trimmedLine.startsWith('-A')) {
714
- const deleteRule = trimmedLine.replace('-A', '-D');
715
- const cmd = `${iptablesCmd} -t nat ${deleteRule}`;
716
- try {
717
- execSync(cmd);
718
- console.log(`Cleaned up iptables rule: ${cmd}`);
719
- }
720
- catch (err) {
721
- console.error(`Failed to remove iptables rule: ${cmd}`, err);
722
- }
723
- }
724
- }
725
- }
726
- // Finally clean up custom chains
727
- for (const chain of customChains) {
728
- try {
729
- // Flush the chain
730
- execSync(`${iptablesCmd} -t nat -F ${chain}`);
731
- // Delete the chain
732
- execSync(`${iptablesCmd} -t nat -X ${chain}`);
733
- console.log(`Deleted custom chain: ${chain}`);
734
- }
735
- catch (err) {
736
- console.error(`Failed to delete custom chain ${chain}:`, err);
737
- }
738
- }
739
- }
740
- catch (err) {
741
- console.error(`Failed to run ${iptablesCmd}-save: ${err}`);
742
- }
743
- }
744
- /**
745
- * Logging utility that respects the enableLogging setting
746
- */
747
- log(level, message) {
748
- if (!this.settings.enableLogging && level === 'info') {
749
- return;
750
- }
751
- const timestamp = new Date().toISOString();
752
- switch (level) {
753
- case 'info':
754
- console.log(`[${timestamp}] [INFO] ${message}`);
755
- break;
756
- case 'warn':
757
- console.warn(`[${timestamp}] [WARN] ${message}`);
758
- break;
759
- case 'error':
760
- console.error(`[${timestamp}] [ERROR] ${message}`);
761
- break;
762
- }
763
- }
764
- }
765
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5pcHRhYmxlc3Byb3h5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5pcHRhYmxlc3Byb3h5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9DLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFakMsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBc0RsQzs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sYUFBYTtJQU14QixZQUFZLFFBQStCO1FBSm5DLFVBQUssR0FBbUIsRUFBRSxDQUFDO1FBRTNCLGdCQUFXLEdBQWtCLElBQUksQ0FBQztRQUd4QywrQ0FBK0M7UUFDL0MsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWhDLHVCQUF1QjtRQUN2QixJQUFJLENBQUMsUUFBUSxHQUFHO1lBQ2QsR0FBRyxRQUFRO1lBQ1gsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNLElBQUksV0FBVztZQUN0QyxRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsSUFBSSxLQUFLO1lBQ3BDLGFBQWEsRUFBRSxRQUFRLENBQUMsYUFBYSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsS0FBSztZQUNwRixXQUFXLEVBQUUsUUFBUSxDQUFDLFdBQVcsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEtBQUs7WUFDOUUsa0JBQWtCLEVBQUUsUUFBUSxDQUFDLGtCQUFrQixLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxJQUFJO1lBQ2xHLG1CQUFtQixFQUFFLFFBQVEsQ0FBQyxtQkFBbUIsSUFBSSxFQUFFLE9BQU8sRUFBRSxL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