@serve.zone/dcrouter 15.0.1 → 15.0.2

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 (53) hide show
  1. package/deno.json +1 -1
  2. package/dist_ts/00_commitinfo_data.js +1 -1
  3. package/dist_ts/acme/classes.smartacme-lifecycle.d.ts +25 -0
  4. package/dist_ts/acme/classes.smartacme-lifecycle.js +144 -0
  5. package/dist_ts/acme/index.d.ts +1 -0
  6. package/dist_ts/acme/index.js +2 -1
  7. package/dist_ts/classes.dcrouter.d.ts +21 -139
  8. package/dist_ts/classes.dcrouter.js +71 -1585
  9. package/dist_ts/dns/classes.dns-server-runtime.d.ts +37 -0
  10. package/dist_ts/dns/classes.dns-server-runtime.js +449 -0
  11. package/dist_ts/dns/index.d.ts +1 -0
  12. package/dist_ts/dns/index.js +2 -1
  13. package/dist_ts/email/classes.accepted-email-spool.d.ts +55 -0
  14. package/dist_ts/email/classes.accepted-email-spool.js +345 -0
  15. package/dist_ts/email/classes.email-route-builder.d.ts +28 -0
  16. package/dist_ts/email/classes.email-route-builder.js +260 -0
  17. package/dist_ts/email/index.d.ts +2 -0
  18. package/dist_ts/email/index.js +3 -1
  19. package/dist_ts/opsserver/handlers/gatewayclient.handler.js +10 -8
  20. package/dist_ts/remoteingress/classes.hub-lifecycle.d.ts +27 -0
  21. package/dist_ts/remoteingress/classes.hub-lifecycle.js +241 -0
  22. package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +1 -2
  23. package/dist_ts/remoteingress/index.d.ts +1 -0
  24. package/dist_ts/remoteingress/index.js +2 -1
  25. package/dist_ts/security/classes.route-policy-augmenter.d.ts +22 -0
  26. package/dist_ts/security/classes.route-policy-augmenter.js +120 -0
  27. package/dist_ts/security/index.d.ts +1 -0
  28. package/dist_ts/security/index.js +2 -1
  29. package/dist_ts/vpn/classes.vpn-access-resolver.d.ts +34 -0
  30. package/dist_ts/vpn/classes.vpn-access-resolver.js +101 -0
  31. package/dist_ts/vpn/index.d.ts +1 -0
  32. package/dist_ts/vpn/index.js +2 -1
  33. package/dist_ts_migrations/index.js +92 -9
  34. package/dist_ts_web/00_commitinfo_data.js +1 -1
  35. package/package.json +1 -1
  36. package/ts/00_commitinfo_data.ts +1 -1
  37. package/ts/acme/classes.smartacme-lifecycle.ts +155 -0
  38. package/ts/acme/index.ts +1 -0
  39. package/ts/classes.dcrouter.ts +118 -1919
  40. package/ts/dns/classes.dns-server-runtime.ts +525 -0
  41. package/ts/dns/index.ts +1 -0
  42. package/ts/email/classes.accepted-email-spool.ts +434 -0
  43. package/ts/email/classes.email-route-builder.ts +312 -0
  44. package/ts/email/index.ts +2 -0
  45. package/ts/opsserver/handlers/gatewayclient.handler.ts +9 -7
  46. package/ts/remoteingress/classes.hub-lifecycle.ts +278 -0
  47. package/ts/remoteingress/classes.remoteingress-manager.ts +1 -1
  48. package/ts/remoteingress/index.ts +1 -0
  49. package/ts/security/classes.route-policy-augmenter.ts +140 -0
  50. package/ts/security/index.ts +1 -0
  51. package/ts/vpn/classes.vpn-access-resolver.ts +126 -0
  52. package/ts/vpn/index.ts +1 -0
  53. package/ts_web/00_commitinfo_data.ts +1 -1
@@ -0,0 +1,241 @@
1
+ import * as plugins from '../plugins.js';
2
+ import { logger } from '../logger.js';
3
+ import { ProxyCertDoc } from '../db/index.js';
4
+ import { RemoteIngressManager } from './classes.remoteingress-manager.js';
5
+ import { TunnelManager } from './classes.tunnel-manager.js';
6
+ /**
7
+ * Generation-guarded lifecycle for the RemoteIngress tunnel hub: serialized
8
+ * start/stop/restart of the Rust hub, edge mutations, route/firewall pushes,
9
+ * and hub-settings updates that may require a SmartProxy restart.
10
+ */
11
+ export class RemoteIngressHubLifecycle {
12
+ dcRouterRef;
13
+ lifecycleChain = Promise.resolve();
14
+ stopping = false;
15
+ generation = 0;
16
+ constructor(dcRouterRef) {
17
+ this.dcRouterRef = dcRouterRef;
18
+ }
19
+ async setup() {
20
+ const remoteIngressManager = this.dcRouterRef.remoteIngressManager;
21
+ if (!remoteIngressManager) {
22
+ return;
23
+ }
24
+ const hubSettings = remoteIngressManager.getHubSettings();
25
+ if (!hubSettings.enabled) {
26
+ logger.log('info', 'Remote Ingress hub is disabled in DB settings');
27
+ return;
28
+ }
29
+ logger.log('info', 'Setting up Remote Ingress hub...');
30
+ this.stopping = false;
31
+ const generation = ++this.generation;
32
+ const firewallConfig = await this.dcRouterRef.securityPolicyManager?.compileRemoteIngressFirewall();
33
+ if (!this.isGenerationCurrent(generation, remoteIngressManager)) {
34
+ return;
35
+ }
36
+ remoteIngressManager.setFirewallConfig(firewallConfig);
37
+ // Pass current bootstrap routes so the manager can derive edge ports initially.
38
+ // Once RouteConfigManager applies the full DB set, the onRoutesApplied callback
39
+ // will push the complete merged routes here.
40
+ remoteIngressManager.setRoutes(this.dcRouterRef.getRemoteIngressBootstrapRoutes());
41
+ // If ConfigManagers finished before us, re-apply routes
42
+ // so the callback delivers the full DB set to our newly-created remoteIngressManager.
43
+ if (this.dcRouterRef.routeConfigManager) {
44
+ await this.dcRouterRef.routeConfigManager.applyRoutes();
45
+ }
46
+ if (!this.isGenerationCurrent(generation, remoteIngressManager)) {
47
+ return;
48
+ }
49
+ await this.queueTask(async () => {
50
+ await this.startTunnelHubLocked(generation);
51
+ });
52
+ if (!this.isGenerationCurrent(generation, remoteIngressManager)) {
53
+ return;
54
+ }
55
+ const edgeCount = remoteIngressManager.getAllEdges().length;
56
+ logger.log('info', `Remote Ingress hub started on port ${hubSettings.tunnelPort} with ${edgeCount} registered edge(s)`);
57
+ }
58
+ async stop() {
59
+ this.stopping = true;
60
+ this.generation++;
61
+ await this.queueTask(async () => {
62
+ const currentTunnelManager = this.dcRouterRef.tunnelManager;
63
+ if (currentTunnelManager) {
64
+ await currentTunnelManager.stop();
65
+ if (this.dcRouterRef.tunnelManager === currentTunnelManager) {
66
+ this.dcRouterRef.tunnelManager = undefined;
67
+ }
68
+ }
69
+ });
70
+ }
71
+ async mutateEdges(mutation, syncAllowedEdges = true) {
72
+ return await this.queueTask(async () => {
73
+ if (this.stopping) {
74
+ throw new Error('RemoteIngress is stopping');
75
+ }
76
+ const manager = this.dcRouterRef.remoteIngressManager;
77
+ if (!manager) {
78
+ throw new Error('RemoteIngress not configured');
79
+ }
80
+ const result = await mutation(manager);
81
+ if (syncAllowedEdges && this.dcRouterRef.tunnelManager) {
82
+ await this.dcRouterRef.tunnelManager.syncAllowedEdges();
83
+ }
84
+ return result;
85
+ });
86
+ }
87
+ async updateRoutes(routes) {
88
+ await this.queueTask(async () => {
89
+ if (this.stopping)
90
+ return;
91
+ if (this.dcRouterRef.remoteIngressManager) {
92
+ this.dcRouterRef.remoteIngressManager.setRoutes(routes);
93
+ }
94
+ if (this.dcRouterRef.tunnelManager) {
95
+ await this.dcRouterRef.tunnelManager.syncAllowedEdges();
96
+ }
97
+ });
98
+ }
99
+ async applyFirewallConfig(firewallConfig) {
100
+ await this.queueTask(async () => {
101
+ if (this.stopping)
102
+ return;
103
+ if (this.dcRouterRef.remoteIngressManager) {
104
+ this.dcRouterRef.remoteIngressManager.setFirewallConfig(firewallConfig);
105
+ }
106
+ if (this.dcRouterRef.tunnelManager) {
107
+ await this.dcRouterRef.tunnelManager.syncAllowedEdges();
108
+ }
109
+ });
110
+ }
111
+ async updateHubSettings(updates, updatedBy) {
112
+ const manager = this.dcRouterRef.remoteIngressManager;
113
+ if (!manager) {
114
+ throw new Error('RemoteIngress is not configured');
115
+ }
116
+ const previousSettings = manager.getHubSettings();
117
+ const settings = await manager.updateHubSettings(updates, updatedBy);
118
+ const enabledChanged = previousSettings.enabled !== settings.enabled;
119
+ if (!settings.enabled) {
120
+ await this.queueTask(async () => {
121
+ await this.stopTunnelHubLocked();
122
+ });
123
+ }
124
+ if (enabledChanged) {
125
+ await this.dcRouterRef.restartSmartProxyForRemoteIngressSettings();
126
+ }
127
+ if (settings.enabled) {
128
+ await this.queueTask(async () => {
129
+ await this.restartTunnelHubLocked();
130
+ });
131
+ }
132
+ return settings;
133
+ }
134
+ isGenerationCurrent(generation, manager) {
135
+ return !this.stopping
136
+ && generation === this.generation
137
+ && this.dcRouterRef.remoteIngressManager === manager;
138
+ }
139
+ queueTask(task) {
140
+ const run = this.lifecycleChain.then(task);
141
+ this.lifecycleChain = run.then(() => undefined, () => undefined);
142
+ return run;
143
+ }
144
+ async stopTunnelHubLocked() {
145
+ this.generation++;
146
+ const currentTunnelManager = this.dcRouterRef.tunnelManager;
147
+ if (currentTunnelManager) {
148
+ await currentTunnelManager.stop();
149
+ if (this.dcRouterRef.tunnelManager === currentTunnelManager) {
150
+ this.dcRouterRef.tunnelManager = undefined;
151
+ }
152
+ }
153
+ }
154
+ async restartTunnelHubLocked() {
155
+ const generation = ++this.generation;
156
+ const hubSettings = this.dcRouterRef.remoteIngressManager?.getHubSettings();
157
+ if (!this.dcRouterRef.remoteIngressManager || !hubSettings?.enabled || this.stopping) {
158
+ return;
159
+ }
160
+ const currentTunnelManager = this.dcRouterRef.tunnelManager;
161
+ if (currentTunnelManager) {
162
+ await currentTunnelManager.stop();
163
+ if (this.dcRouterRef.tunnelManager === currentTunnelManager) {
164
+ this.dcRouterRef.tunnelManager = undefined;
165
+ }
166
+ }
167
+ if (this.stopping || generation !== this.generation) {
168
+ return;
169
+ }
170
+ await this.startTunnelHubLocked(generation);
171
+ }
172
+ async startTunnelHubLocked(generation) {
173
+ const manager = this.dcRouterRef.remoteIngressManager;
174
+ const hubSettings = manager?.getHubSettings();
175
+ if (!manager || !hubSettings?.enabled || this.stopping || generation !== this.generation) {
176
+ return;
177
+ }
178
+ const firewallConfig = await this.dcRouterRef.securityPolicyManager?.compileRemoteIngressFirewall();
179
+ if (this.stopping || generation !== this.generation || this.dcRouterRef.remoteIngressManager !== manager) {
180
+ return;
181
+ }
182
+ manager.setFirewallConfig(firewallConfig);
183
+ const tlsConfig = await this.resolveTlsConfig(hubSettings.hubDomain);
184
+ if (this.stopping || generation !== this.generation || this.dcRouterRef.remoteIngressManager !== manager) {
185
+ return;
186
+ }
187
+ const tunnelManager = new TunnelManager(manager, {
188
+ tunnelPort: hubSettings.tunnelPort,
189
+ targetHost: '127.0.0.1',
190
+ tls: tlsConfig,
191
+ performance: manager.getHubPerformanceConfig(),
192
+ });
193
+ try {
194
+ await tunnelManager.start();
195
+ }
196
+ catch (err) {
197
+ await tunnelManager.stop().catch(() => { });
198
+ throw err;
199
+ }
200
+ if (this.stopping || generation !== this.generation || this.dcRouterRef.remoteIngressManager !== manager) {
201
+ await tunnelManager.stop().catch((err) => {
202
+ logger.log('warn', `Failed to stop stale RemoteIngress tunnel hub: ${err.message}`);
203
+ });
204
+ return;
205
+ }
206
+ this.dcRouterRef.tunnelManager = tunnelManager;
207
+ }
208
+ async resolveTlsConfig(hubDomain) {
209
+ // Resolve TLS certs for tunnel: explicit paths > ACME for hubDomain > self-signed (Rust default)
210
+ let tlsConfig;
211
+ // Priority 1: Explicit cert/key file paths
212
+ const explicitTls = this.dcRouterRef.options.remoteIngressConfig?.tls;
213
+ if (explicitTls?.certPath && explicitTls?.keyPath) {
214
+ try {
215
+ const certPem = plugins.fs.readFileSync(explicitTls.certPath, 'utf8');
216
+ const keyPem = plugins.fs.readFileSync(explicitTls.keyPath, 'utf8');
217
+ tlsConfig = { certPem, keyPem };
218
+ logger.log('info', 'Using explicit TLS cert/key for RemoteIngress tunnel');
219
+ }
220
+ catch (err) {
221
+ logger.log('warn', `Failed to read RemoteIngress TLS cert/key files: ${err.message}`);
222
+ }
223
+ }
224
+ // Priority 2: Existing cert from SmartProxy cert store for hubDomain
225
+ if (!tlsConfig && hubDomain) {
226
+ try {
227
+ const stored = await ProxyCertDoc.findByDomain(hubDomain);
228
+ if (stored?.publicKey && stored?.privateKey) {
229
+ tlsConfig = { certPem: stored.publicKey, keyPem: stored.privateKey };
230
+ logger.log('info', `Using stored ACME cert for RemoteIngress tunnel TLS: ${hubDomain}`);
231
+ }
232
+ }
233
+ catch { /* no stored cert, fall through */ }
234
+ }
235
+ if (!tlsConfig) {
236
+ logger.log('info', 'No TLS cert configured for RemoteIngress tunnel — using auto-generated self-signed');
237
+ }
238
+ return tlsConfig;
239
+ }
240
+ }
241
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5odWItbGlmZWN5Y2xlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvcmVtb3RlaW5ncmVzcy9jbGFzc2VzLmh1Yi1saWZlY3ljbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN0QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLG9CQUFvQixFQUFxQyxNQUFNLG9DQUFvQyxDQUFDO0FBQzdHLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUk1RDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLHlCQUF5QjtJQUtoQjtJQUpaLGNBQWMsR0FBa0IsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2xELFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDakIsVUFBVSxHQUFHLENBQUMsQ0FBQztJQUV2QixZQUFvQixXQUFxQjtRQUFyQixnQkFBVyxHQUFYLFdBQVcsQ0FBVTtJQUFHLENBQUM7SUFFdEMsS0FBSyxDQUFDLEtBQUs7UUFDaEIsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDO1FBQ25FLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQzFCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxXQUFXLEdBQUcsb0JBQW9CLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDMUQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUN6QixNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSwrQ0FBK0MsQ0FBQyxDQUFDO1lBQ3BFLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsa0NBQWtDLENBQUMsQ0FBQztRQUN2RCxJ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
@@ -1,5 +1,5 @@
1
1
  import type { IDcRouterRouteConfig, IRemoteIngress, IRemoteIngressHubSettings, IRemoteIngressPerformanceConfig, TRemoteIngressHubSettingsUpdate } from '../../dist_ts_interfaces/data/remoteingress.js';
2
- interface IRemoteIngressFirewallConfig {
2
+ export interface IRemoteIngressFirewallConfig {
3
3
  blockedIps?: string[];
4
4
  }
5
5
  /**
@@ -109,4 +109,3 @@ export declare class RemoteIngressManager {
109
109
  private normalizePerformanceConfig;
110
110
  private toHubSettings;
111
111
  }
112
- export {};
@@ -1,2 +1,3 @@
1
1
  export * from './classes.remoteingress-manager.js';
2
2
  export * from './classes.tunnel-manager.js';
3
+ export * from './classes.hub-lifecycle.js';
@@ -1,3 +1,4 @@
1
1
  export * from './classes.remoteingress-manager.js';
2
2
  export * from './classes.tunnel-manager.js';
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9yZW1vdGVpbmdyZXNzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsb0NBQW9DLENBQUM7QUFDbkQsY0FBYyw2QkFBNkIsQ0FBQyJ9
3
+ export * from './classes.hub-lifecycle.js';
4
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9yZW1vdGVpbmdyZXNzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsb0NBQW9DLENBQUM7QUFDbkQsY0FBYyw2QkFBNkIsQ0FBQztBQUM1QyxjQUFjLDRCQUE0QixDQUFDIn0=
@@ -0,0 +1,22 @@
1
+ import * as plugins from '../plugins.js';
2
+ import type { ISecurityCompiledPolicy } from '../../dist_ts_interfaces/data/security-policy.js';
3
+ import type { DcRouter } from '../classes.dcrouter.js';
4
+ /**
5
+ * Pure route-policy transformations applied before routes reach SmartProxy:
6
+ * per-listener inbound PROXY protocol policies (driven by RemoteIngress and
7
+ * VPN) and merging of compiled security policies.
8
+ */
9
+ export declare class RoutePolicyAugmenter {
10
+ private dcRouterRef;
11
+ constructor(dcRouterRef: DcRouter);
12
+ /**
13
+ * Ensure every route on a shared listener carries a compatible
14
+ * inboundProxyProtocol policy, deriving defaults from RemoteIngress/VPN.
15
+ */
16
+ applyInboundProxyProtocolPolicies(routes: plugins.smartproxy.IRouteConfig[]): plugins.smartproxy.IRouteConfig[];
17
+ /** Union blocked IPs/CIDRs across configured and compiled security policies. */
18
+ mergeSecurityPolicies(...policies: Array<Partial<ISecurityCompiledPolicy> | undefined>): ISecurityCompiledPolicy | undefined;
19
+ private getDesiredInboundProxyProtocolPolicy;
20
+ private getInboundProxyListenerKeys;
21
+ private mergeInboundProxyProtocolPolicies;
22
+ }
@@ -0,0 +1,120 @@
1
+ import * as plugins from '../plugins.js';
2
+ /**
3
+ * Pure route-policy transformations applied before routes reach SmartProxy:
4
+ * per-listener inbound PROXY protocol policies (driven by RemoteIngress and
5
+ * VPN) and merging of compiled security policies.
6
+ */
7
+ export class RoutePolicyAugmenter {
8
+ dcRouterRef;
9
+ constructor(dcRouterRef) {
10
+ this.dcRouterRef = dcRouterRef;
11
+ }
12
+ /**
13
+ * Ensure every route on a shared listener carries a compatible
14
+ * inboundProxyProtocol policy, deriving defaults from RemoteIngress/VPN.
15
+ */
16
+ applyInboundProxyProtocolPolicies(routes) {
17
+ const policiesByListener = new Map();
18
+ for (const route of routes) {
19
+ const policy = route.match?.inboundProxyProtocol || this.getDesiredInboundProxyProtocolPolicy(route);
20
+ if (!policy) {
21
+ continue;
22
+ }
23
+ for (const listenerKey of this.getInboundProxyListenerKeys(route)) {
24
+ const mergedPolicy = this.mergeInboundProxyProtocolPolicies(policiesByListener.get(listenerKey), policy);
25
+ if (mergedPolicy) {
26
+ policiesByListener.set(listenerKey, mergedPolicy);
27
+ }
28
+ }
29
+ }
30
+ if (policiesByListener.size === 0) {
31
+ return routes;
32
+ }
33
+ return routes.map((route) => {
34
+ if (route.match?.inboundProxyProtocol) {
35
+ return route;
36
+ }
37
+ let listenerPolicy;
38
+ for (const listenerKey of this.getInboundProxyListenerKeys(route)) {
39
+ listenerPolicy = this.mergeInboundProxyProtocolPolicies(listenerPolicy, policiesByListener.get(listenerKey));
40
+ }
41
+ if (!listenerPolicy) {
42
+ return route;
43
+ }
44
+ return {
45
+ ...route,
46
+ match: {
47
+ ...route.match,
48
+ inboundProxyProtocol: listenerPolicy,
49
+ },
50
+ };
51
+ });
52
+ }
53
+ /** Union blocked IPs/CIDRs across configured and compiled security policies. */
54
+ mergeSecurityPolicies(...policies) {
55
+ const blockedIps = new Set();
56
+ const blockedCidrs = new Set();
57
+ for (const policy of policies) {
58
+ for (const ip of policy?.blockedIps || []) {
59
+ if (ip)
60
+ blockedIps.add(ip);
61
+ }
62
+ for (const cidr of policy?.blockedCidrs || []) {
63
+ if (cidr)
64
+ blockedCidrs.add(cidr);
65
+ }
66
+ }
67
+ if (blockedIps.size === 0 && blockedCidrs.size === 0) {
68
+ return undefined;
69
+ }
70
+ return {
71
+ blockedIps: [...blockedIps].sort(),
72
+ blockedCidrs: [...blockedCidrs].sort(),
73
+ };
74
+ }
75
+ getDesiredInboundProxyProtocolPolicy(route) {
76
+ const dcRoute = route;
77
+ if (this.dcRouterRef.isRemoteIngressHubEnabled() && dcRoute.remoteIngress?.enabled) {
78
+ const ports = plugins.smartproxy.expandPortRange(route.match.ports);
79
+ if (ports.some((port) => port === 25 || port === 587)) {
80
+ return { mode: 'required' };
81
+ }
82
+ return { mode: 'optional' };
83
+ }
84
+ if (this.dcRouterRef.options.vpnConfig?.enabled) {
85
+ return { mode: 'optional' };
86
+ }
87
+ return undefined;
88
+ }
89
+ getInboundProxyListenerKeys(route) {
90
+ const ports = plugins.smartproxy.expandPortRange(route.match.ports);
91
+ const transports = route.match.transport === 'udp'
92
+ ? ['udp']
93
+ : route.match.transport === 'all'
94
+ ? ['tcp', 'udp']
95
+ : ['tcp'];
96
+ const keys = [];
97
+ for (const port of ports) {
98
+ for (const transport of transports) {
99
+ keys.push(`${transport}:${port}`);
100
+ }
101
+ }
102
+ return keys;
103
+ }
104
+ mergeInboundProxyProtocolPolicies(current, next) {
105
+ if (!current)
106
+ return next;
107
+ if (!next)
108
+ return current;
109
+ if (current.mode === 'required')
110
+ return current;
111
+ if (next.mode === 'required')
112
+ return next;
113
+ if (current.mode === 'optional')
114
+ return current;
115
+ if (next.mode === 'optional')
116
+ return next;
117
+ return current;
118
+ }
119
+ }
120
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5yb3V0ZS1wb2xpY3ktYXVnbWVudGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvc2VjdXJpdHkvY2xhc3Nlcy5yb3V0ZS1wb2xpY3ktYXVnbWVudGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBT3pDOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sb0JBQW9CO0lBQ1g7SUFBcEIsWUFBb0IsV0FBcUI7UUFBckIsZ0JBQVcsR0FBWCxXQUFXLENBQVU7SUFBRyxDQUFDO0lBRTdDOzs7T0FHRztJQUNJLGlDQUFpQyxDQUN0QyxNQUF5QztRQUV6QyxNQUFNLGtCQUFrQixHQUFHLElBQUksR0FBRyxFQUF1QyxDQUFDO1FBRTFFLEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxFQUFFLENBQUM7WUFDM0IsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxvQkFBb0IsSUFBSSxJQUFJLENBQUMsb0NBQW9DLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNaLFNBQVM7WUFDWCxDQUFDO1lBQ0QsS0FBSyxNQUFNLFdBQVcsSUFBSSxJQUFJLENBQUMsMkJBQTJCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDbEUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGlDQUFpQyxDQUN6RCxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQ25DLE1BQU0sQ0FDUCxDQUFDO2dCQUNGLElBQUksWUFBWSxFQUFFLENBQUM7b0JBQ2pCLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBQ3BELENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksa0JBQWtCLENBQUMsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sTUFBTSxD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
@@ -2,3 +2,4 @@ export { SecurityLogger, SecurityLogLevel, SecurityEventType, type ISecurityEven
2
2
  export { IPReputationChecker, ReputationThreshold, IPType, type IReputationResult, type IIPReputationOptions } from './classes.ipreputationchecker.js';
3
3
  export { ContentScanner, ThreatCategory, type IScanResult, type IContentScannerOptions } from './classes.contentscanner.js';
4
4
  export { SecurityPolicyManager, type ISecurityPolicyManagerOptions, type IRemoteIngressFirewallSnapshot, } from './classes.security-policy-manager.js';
5
+ export * from './classes.route-policy-augmenter.js';
@@ -2,4 +2,5 @@ export { SecurityLogger, SecurityLogLevel, SecurityEventType } from './classes.s
2
2
  export { IPReputationChecker, ReputationThreshold, IPType } from './classes.ipreputationchecker.js';
3
3
  export { ContentScanner, ThreatCategory } from './classes.contentscanner.js';
4
4
  export { SecurityPolicyManager, } from './classes.security-policy-manager.js';
5
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zZWN1cml0eS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixpQkFBaUIsRUFFbEIsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLG1CQUFtQixFQUNuQixNQUFNLEVBR1AsTUFBTSxrQ0FBa0MsQ0FBQztBQUUxQyxPQUFPLEVBQ0wsY0FBYyxFQUNkLGNBQWMsRUFHZixNQUFNLDZCQUE2QixDQUFDO0FBRXJDLE9BQU8sRUFDTCxxQkFBcUIsR0FHdEIsTUFBTSxzQ0FBc0MsQ0FBQyJ9
5
+ export * from './classes.route-policy-augmenter.js';
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9zZWN1cml0eS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsY0FBYyxFQUNkLGdCQUFnQixFQUNoQixpQkFBaUIsRUFFbEIsTUFBTSw2QkFBNkIsQ0FBQztBQUVyQyxPQUFPLEVBQ0wsbUJBQW1CLEVBQ25CLG1CQUFtQixFQUNuQixNQUFNLEVBR1AsTUFBTSxrQ0FBa0MsQ0FBQztBQUUxQyxPQUFPLEVBQ0wsY0FBYyxFQUNkLGNBQWMsRUFHZixNQUFNLDZCQUE2QixDQUFDO0FBRXJDLE9BQU8sRUFDTCxxQkFBcUIsR0FHdEIsTUFBTSxzQ0FBc0MsQ0FBQztBQUM5QyxjQUFjLHFDQUFxQyxDQUFDIn0=
@@ -0,0 +1,34 @@
1
+ import type { TVpnClientAllowEntry } from '../config/classes.route-config-manager.js';
2
+ import type { IDcRouterRouteConfig } from '../../dist_ts_interfaces/data/remoteingress.js';
3
+ import type { DcRouter } from '../classes.dcrouter.js';
4
+ /**
5
+ * Resolves which VPN clients may access which routes and which IPs belong in
6
+ * a client's WireGuard AllowedIPs, including cached DNS resolution of
7
+ * VPN-gated route domains.
8
+ */
9
+ export declare class VpnAccessResolver {
10
+ private dcRouterRef;
11
+ /** Cache for DNS-resolved IPs of VPN-gated domains. TTL: 5 minutes. */
12
+ private domainIpCache;
13
+ /** Deduplicate wildcard-resolution warnings for WireGuard AllowedIPs generation. */
14
+ private warnedWildcardDomains;
15
+ constructor(dcRouterRef: DcRouter);
16
+ /** Clear DNS and warning caches, e.g. after a VPN config change. */
17
+ reset(): void;
18
+ /**
19
+ * Build the per-route VPN client allow resolver handed to RouteConfigManager,
20
+ * or undefined when VPN is disabled.
21
+ */
22
+ createRouteAllowResolver(): ((route: IDcRouterRouteConfig, routeId?: string) => TVpnClientAllowEntry[]) | undefined;
23
+ /**
24
+ * Compute the WireGuard AllowedIPs for a client from its target profiles:
25
+ * the VPN subnet, direct target IPs, and DNS-resolved route domains.
26
+ */
27
+ getClientAllowedIPs(targetProfileIds: string[]): Promise<string[]>;
28
+ /**
29
+ * Resolve a domain's A record(s) for VPN AllowedIPs, with a 5-minute cache.
30
+ */
31
+ private resolveDomainIPs;
32
+ private isWildcardDomain;
33
+ private logSkippedWildcardAllowedIp;
34
+ }
@@ -0,0 +1,101 @@
1
+ import { logger } from '../logger.js';
2
+ /**
3
+ * Resolves which VPN clients may access which routes and which IPs belong in
4
+ * a client's WireGuard AllowedIPs, including cached DNS resolution of
5
+ * VPN-gated route domains.
6
+ */
7
+ export class VpnAccessResolver {
8
+ dcRouterRef;
9
+ /** Cache for DNS-resolved IPs of VPN-gated domains. TTL: 5 minutes. */
10
+ domainIpCache = new Map();
11
+ /** Deduplicate wildcard-resolution warnings for WireGuard AllowedIPs generation. */
12
+ warnedWildcardDomains = new Set();
13
+ constructor(dcRouterRef) {
14
+ this.dcRouterRef = dcRouterRef;
15
+ }
16
+ /** Clear DNS and warning caches, e.g. after a VPN config change. */
17
+ reset() {
18
+ this.domainIpCache.clear();
19
+ this.warnedWildcardDomains.clear();
20
+ }
21
+ /**
22
+ * Build the per-route VPN client allow resolver handed to RouteConfigManager,
23
+ * or undefined when VPN is disabled.
24
+ */
25
+ createRouteAllowResolver() {
26
+ if (!this.dcRouterRef.options.vpnConfig?.enabled) {
27
+ return undefined;
28
+ }
29
+ return (route, routeId) => {
30
+ if (!this.dcRouterRef.vpnManager || !this.dcRouterRef.targetProfileManager) {
31
+ // VPN not ready yet — deny all until re-apply after VPN starts.
32
+ return [];
33
+ }
34
+ return this.dcRouterRef.targetProfileManager.getMatchingVpnClients(route, routeId, this.dcRouterRef.vpnManager.listClients(), this.dcRouterRef.routeConfigManager?.getRoutes() || new Map());
35
+ };
36
+ }
37
+ /**
38
+ * Compute the WireGuard AllowedIPs for a client from its target profiles:
39
+ * the VPN subnet, direct target IPs, and DNS-resolved route domains.
40
+ */
41
+ async getClientAllowedIPs(targetProfileIds) {
42
+ const subnet = this.dcRouterRef.options.vpnConfig?.subnet || '10.8.0.0/24';
43
+ const ips = new Set([subnet]);
44
+ const targetProfileManager = this.dcRouterRef.targetProfileManager;
45
+ if (!targetProfileManager)
46
+ return [...ips];
47
+ const allRoutes = this.dcRouterRef.routeConfigManager?.getRoutes() || new Map();
48
+ const { domains, targetIps } = targetProfileManager.getClientAccessSpec(targetProfileIds, allRoutes);
49
+ // Add target IPs directly
50
+ for (const ip of targetIps) {
51
+ ips.add(`${ip}/32`);
52
+ }
53
+ // Resolve DNS A records for matched domains (with caching)
54
+ for (const domain of domains) {
55
+ if (this.isWildcardDomain(domain)) {
56
+ this.logSkippedWildcardAllowedIp(domain);
57
+ continue;
58
+ }
59
+ const resolvedIps = await this.resolveDomainIPs(domain);
60
+ for (const ip of resolvedIps) {
61
+ ips.add(`${ip}/32`);
62
+ }
63
+ }
64
+ return [...ips];
65
+ }
66
+ /**
67
+ * Resolve a domain's A record(s) for VPN AllowedIPs, with a 5-minute cache.
68
+ */
69
+ async resolveDomainIPs(domain) {
70
+ const cached = this.domainIpCache.get(domain);
71
+ if (cached && cached.expiresAt > Date.now()) {
72
+ return cached.ips;
73
+ }
74
+ try {
75
+ const { promises: dnsPromises } = await import('dns');
76
+ const ips = await dnsPromises.resolve4(domain);
77
+ this.domainIpCache.set(domain, { ips, expiresAt: Date.now() + 5 * 60 * 1000 });
78
+ // Evict oldest entries if cache exceeds 1000 entries
79
+ if (this.domainIpCache.size > 1000) {
80
+ const firstKey = this.domainIpCache.keys().next().value;
81
+ if (firstKey)
82
+ this.domainIpCache.delete(firstKey);
83
+ }
84
+ return ips;
85
+ }
86
+ catch (err) {
87
+ logger.log('warn', `VPN: Failed to resolve ${domain} for AllowedIPs: ${err.message}`);
88
+ return cached?.ips || []; // Return stale cache on failure, or empty
89
+ }
90
+ }
91
+ isWildcardDomain(domain) {
92
+ return domain.includes('*');
93
+ }
94
+ logSkippedWildcardAllowedIp(domain) {
95
+ if (this.warnedWildcardDomains.has(domain))
96
+ return;
97
+ this.warnedWildcardDomains.add(domain);
98
+ logger.log('warn', `VPN: Skipping wildcard domain '${domain}' for WireGuard AllowedIPs; wildcard patterns must be resolved to concrete hostnames by matching routes.`);
99
+ }
100
+ }
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy52cG4tYWNjZXNzLXJlc29sdmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvdnBuL2NsYXNzZXMudnBuLWFjY2Vzcy1yZXNvbHZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBS3RDOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8saUJBQWlCO0lBTVI7SUFMcEIsdUVBQXVFO0lBQy9ELGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBZ0QsQ0FBQztJQUNoRixvRkFBb0Y7SUFDNUUscUJBQXFCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUVsRCxZQUFvQixXQUFxQjtRQUFyQixnQkFBVyxHQUFYLFdBQVcsQ0FBVTtJQUFHLENBQUM7SUFFN0Msb0VBQW9FO0lBQzdELEtBQUs7UUFDVixJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzNCLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksd0JBQXdCO1FBSTdCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDakQsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUVELE9BQU8sQ0FBQyxLQUEyQixFQUFFLE9BQWdCLEVBQUUsRUFBRTtZQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixFQUFFLENBQUM7Z0JBQzNFLGdFQUFnRTtnQkFDaEUsT0FBTyxFQUFFLENBQUM7WUFDWixDQUFDO1lBRUQsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDLHFCQUFxQixDQUNoRSxLQUFLLEVBQ0wsT0FBTyxFQUNQLElBQUksQ0FBQyxXQUFX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
@@ -1 +1,2 @@
1
1
  export * from './classes.vpn-manager.js';
2
+ export * from './classes.vpn-access-resolver.js';
@@ -1,2 +1,3 @@
1
1
  export * from './classes.vpn-manager.js';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy92cG4vaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYywwQkFBMEIsQ0FBQyJ9
2
+ export * from './classes.vpn-access-resolver.js';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy92cG4vaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYywwQkFBMEIsQ0FBQztBQUN6QyxjQUFjLGtDQUFrQyxDQUFDIn0=