@serve.zone/dcrouter 13.21.1 → 13.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_serve/bundle.js +26 -4
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.dcrouter.d.ts +6 -0
- package/dist_ts/classes.dcrouter.js +83 -5
- package/dist_ts/config/classes.route-config-manager.d.ts +1 -1
- package/dist_ts/config/classes.route-config-manager.js +2 -2
- package/dist_ts/db/documents/classes.ip-intelligence.doc.d.ts +25 -0
- package/dist_ts/db/documents/classes.ip-intelligence.doc.js +175 -0
- package/dist_ts/db/documents/classes.security-block-rule.doc.d.ts +17 -0
- package/dist_ts/db/documents/classes.security-block-rule.doc.js +124 -0
- package/dist_ts/db/documents/classes.security-policy-audit.doc.d.ts +11 -0
- package/dist_ts/db/documents/classes.security-policy-audit.doc.js +95 -0
- package/dist_ts/db/documents/index.d.ts +3 -0
- package/dist_ts/db/documents/index.js +4 -1
- package/dist_ts/monitoring/classes.metricsmanager.js +2 -1
- package/dist_ts/opsserver/handlers/config.handler.js +2 -1
- package/dist_ts/opsserver/handlers/remoteingress.handler.js +3 -1
- package/dist_ts/opsserver/handlers/security.handler.js +42 -1
- package/dist_ts/remoteingress/classes.remoteingress-manager.d.ts +10 -0
- package/dist_ts/remoteingress/classes.remoteingress-manager.js +9 -1
- package/dist_ts/remoteingress/classes.tunnel-manager.d.ts +3 -0
- package/dist_ts/remoteingress/classes.tunnel-manager.js +23 -5
- package/dist_ts/security/classes.security-policy-manager.d.ts +41 -0
- package/dist_ts/security/classes.security-policy-manager.js +283 -0
- package/dist_ts/security/index.d.ts +1 -0
- package/dist_ts/security/index.js +2 -1
- package/dist_ts_apiclient/classes.remoteingress.d.ts +2 -0
- package/dist_ts_apiclient/classes.remoteingress.js +7 -1
- package/dist_ts_interfaces/data/index.d.ts +1 -0
- package/dist_ts_interfaces/data/index.js +2 -1
- package/dist_ts_interfaces/data/remoteingress.d.ts +51 -0
- package/dist_ts_interfaces/data/security-policy.d.ts +32 -0
- package/dist_ts_interfaces/data/security-policy.js +2 -0
- package/dist_ts_interfaces/requests/config.d.ts +1 -0
- package/dist_ts_interfaces/requests/index.d.ts +1 -0
- package/dist_ts_interfaces/requests/index.js +2 -1
- package/dist_ts_interfaces/requests/security-policy.d.ts +64 -0
- package/dist_ts_interfaces/requests/security-policy.js +2 -0
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/network/ops-view-remoteingress.d.ts +5 -0
- package/dist_ts_web/elements/network/ops-view-remoteingress.js +69 -1
- package/package.json +3 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.dcrouter.ts +106 -6
- package/ts/config/classes.route-config-manager.ts +2 -2
- package/ts/db/documents/classes.ip-intelligence.doc.ts +75 -0
- package/ts/db/documents/classes.security-block-rule.doc.ts +52 -0
- package/ts/db/documents/classes.security-policy-audit.doc.ts +33 -0
- package/ts/db/documents/index.ts +3 -0
- package/ts/monitoring/classes.metricsmanager.ts +2 -0
- package/ts/opsserver/handlers/config.handler.ts +1 -0
- package/ts/opsserver/handlers/remoteingress.handler.ts +2 -0
- package/ts/opsserver/handlers/security.handler.ts +69 -0
- package/ts/remoteingress/classes.remoteingress-manager.ts +15 -2
- package/ts/remoteingress/classes.tunnel-manager.ts +25 -5
- package/ts/security/classes.security-policy-manager.ts +315 -0
- package/ts/security/index.ts +7 -1
- package/ts_apiclient/classes.remoteingress.ts +6 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/network/ops-view-remoteingress.ts +68 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { IIpIntelligenceResult } from '@push.rocks/smartnetwork';
|
|
2
|
+
export type TSecurityBlockRuleType = 'ip' | 'cidr' | 'asn' | 'organization';
|
|
3
|
+
export type TSecurityBlockRuleMatchMode = 'exact' | 'contains';
|
|
4
|
+
export interface IIpIntelligenceRecord extends IIpIntelligenceResult {
|
|
5
|
+
ipAddress: string;
|
|
6
|
+
firstSeenAt: number;
|
|
7
|
+
lastSeenAt: number;
|
|
8
|
+
updatedAt: number;
|
|
9
|
+
seenCount: number;
|
|
10
|
+
}
|
|
11
|
+
export interface ISecurityBlockRule {
|
|
12
|
+
id: string;
|
|
13
|
+
type: TSecurityBlockRuleType;
|
|
14
|
+
value: string;
|
|
15
|
+
matchMode?: TSecurityBlockRuleMatchMode;
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
reason?: string;
|
|
18
|
+
createdAt: number;
|
|
19
|
+
updatedAt: number;
|
|
20
|
+
createdBy: string;
|
|
21
|
+
}
|
|
22
|
+
export interface ISecurityCompiledPolicy {
|
|
23
|
+
blockedIps: string[];
|
|
24
|
+
blockedCidrs: string[];
|
|
25
|
+
}
|
|
26
|
+
export interface ISecurityPolicyAuditEvent {
|
|
27
|
+
id: string;
|
|
28
|
+
action: string;
|
|
29
|
+
actor: string;
|
|
30
|
+
details: Record<string, unknown>;
|
|
31
|
+
createdAt: number;
|
|
32
|
+
}
|
|
@@ -75,6 +75,7 @@ export interface IConfigData {
|
|
|
75
75
|
hubDomain: string | null;
|
|
76
76
|
tlsMode: 'custom' | 'acme' | 'self-signed';
|
|
77
77
|
connectedEdgeIps: string[];
|
|
78
|
+
performance?: import('../data/remoteingress.js').IRemoteIngressPerformanceConfig;
|
|
78
79
|
};
|
|
79
80
|
}
|
|
80
81
|
export interface IReq_GetConfiguration extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_GetConfiguration> {
|
|
@@ -19,4 +19,5 @@ export * from './domains.js';
|
|
|
19
19
|
export * from './dns-records.js';
|
|
20
20
|
export * from './acme-config.js';
|
|
21
21
|
export * from './email-domains.js';
|
|
22
|
-
|
|
22
|
+
export * from './security-policy.js';
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90c19pbnRlcmZhY2VzL3JlcXVlc3RzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsWUFBWSxDQUFDO0FBQzNCLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsWUFBWSxDQUFDO0FBQzNCLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxnQkFBZ0IsQ0FBQztBQUMvQixjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLGlCQUFpQixDQUFDO0FBQ2hDLGNBQWMsVUFBVSxDQUFDO0FBQ3pCLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsWUFBWSxDQUFDO0FBQzNCLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxrQkFBa0IsQ0FBQztBQUNqQyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsb0JBQW9CLENBQUM7QUFDbkMsY0FBYyxzQkFBc0IsQ0FBQyJ9
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import type * as authInterfaces from '../data/auth.js';
|
|
3
|
+
import type { IIpIntelligenceRecord, ISecurityBlockRule, TSecurityBlockRuleMatchMode, TSecurityBlockRuleType } from '../data/security-policy.js';
|
|
4
|
+
export interface IReq_ListSecurityBlockRules extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ListSecurityBlockRules> {
|
|
5
|
+
method: 'listSecurityBlockRules';
|
|
6
|
+
request: {
|
|
7
|
+
identity: authInterfaces.IIdentity;
|
|
8
|
+
};
|
|
9
|
+
response: {
|
|
10
|
+
rules: ISecurityBlockRule[];
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export interface IReq_CreateSecurityBlockRule extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_CreateSecurityBlockRule> {
|
|
14
|
+
method: 'createSecurityBlockRule';
|
|
15
|
+
request: {
|
|
16
|
+
identity: authInterfaces.IIdentity;
|
|
17
|
+
type: TSecurityBlockRuleType;
|
|
18
|
+
value: string;
|
|
19
|
+
matchMode?: TSecurityBlockRuleMatchMode;
|
|
20
|
+
reason?: string;
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
};
|
|
23
|
+
response: {
|
|
24
|
+
success: boolean;
|
|
25
|
+
rule?: ISecurityBlockRule;
|
|
26
|
+
message?: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface IReq_UpdateSecurityBlockRule extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_UpdateSecurityBlockRule> {
|
|
30
|
+
method: 'updateSecurityBlockRule';
|
|
31
|
+
request: {
|
|
32
|
+
identity: authInterfaces.IIdentity;
|
|
33
|
+
id: string;
|
|
34
|
+
value?: string;
|
|
35
|
+
matchMode?: TSecurityBlockRuleMatchMode;
|
|
36
|
+
reason?: string;
|
|
37
|
+
enabled?: boolean;
|
|
38
|
+
};
|
|
39
|
+
response: {
|
|
40
|
+
success: boolean;
|
|
41
|
+
rule?: ISecurityBlockRule;
|
|
42
|
+
message?: string;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export interface IReq_DeleteSecurityBlockRule extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_DeleteSecurityBlockRule> {
|
|
46
|
+
method: 'deleteSecurityBlockRule';
|
|
47
|
+
request: {
|
|
48
|
+
identity: authInterfaces.IIdentity;
|
|
49
|
+
id: string;
|
|
50
|
+
};
|
|
51
|
+
response: {
|
|
52
|
+
success: boolean;
|
|
53
|
+
message?: string;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export interface IReq_ListIpIntelligence extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_ListIpIntelligence> {
|
|
57
|
+
method: 'listIpIntelligence';
|
|
58
|
+
request: {
|
|
59
|
+
identity: authInterfaces.IIdentity;
|
|
60
|
+
};
|
|
61
|
+
response: {
|
|
62
|
+
records: IIpIntelligenceRecord[];
|
|
63
|
+
};
|
|
64
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJpdHktcG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfaW50ZXJmYWNlcy9yZXF1ZXN0cy9zZWN1cml0eS1wb2xpY3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxlQUFlLENBQUMifQ==
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '13.
|
|
6
|
+
version: '13.23.0',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
|
|
@@ -16,5 +16,10 @@ export declare class OpsViewRemoteIngress extends DeesElement {
|
|
|
16
16
|
private getEdgePublicIp;
|
|
17
17
|
private getPortsHtml;
|
|
18
18
|
private getEdgeTunnelCount;
|
|
19
|
+
private getTransportHtml;
|
|
20
|
+
private getWindowHtml;
|
|
21
|
+
private getQueuesHtml;
|
|
22
|
+
private getTrafficHtml;
|
|
19
23
|
private getLastHeartbeat;
|
|
24
|
+
private formatBytes;
|
|
20
25
|
}
|
|
@@ -160,6 +160,18 @@ let OpsViewRemoteIngress = (() => {
|
|
|
160
160
|
color: ${cssManager.bdTheme('#047857', '#34d399')};
|
|
161
161
|
border: 1px dashed ${cssManager.bdTheme('#6ee7b7', '#065f46')};
|
|
162
162
|
}
|
|
163
|
+
|
|
164
|
+
.metricStack {
|
|
165
|
+
display: flex;
|
|
166
|
+
flex-direction: column;
|
|
167
|
+
gap: 2px;
|
|
168
|
+
font-size: 12px;
|
|
169
|
+
line-height: 1.35;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.metricMuted {
|
|
173
|
+
color: var(--text-muted, #6b7280);
|
|
174
|
+
}
|
|
163
175
|
`,
|
|
164
176
|
];
|
|
165
177
|
render() {
|
|
@@ -261,9 +273,13 @@ let OpsViewRemoteIngress = (() => {
|
|
|
261
273
|
.displayFunction=${(edge) => ({
|
|
262
274
|
name: edge.name,
|
|
263
275
|
status: this.getEdgeStatusHtml(edge),
|
|
276
|
+
transport: this.getTransportHtml(edge.id),
|
|
264
277
|
publicIp: this.getEdgePublicIp(edge.id),
|
|
265
278
|
ports: this.getPortsHtml(edge),
|
|
266
279
|
tunnels: this.getEdgeTunnelCount(edge.id),
|
|
280
|
+
window: this.getWindowHtml(edge.id),
|
|
281
|
+
queues: this.getQueuesHtml(edge.id),
|
|
282
|
+
traffic: this.getTrafficHtml(edge.id),
|
|
267
283
|
lastHeartbeat: this.getLastHeartbeat(edge.id),
|
|
268
284
|
})}
|
|
269
285
|
.dataActions=${[
|
|
@@ -476,6 +492,46 @@ let OpsViewRemoteIngress = (() => {
|
|
|
476
492
|
const status = this.getEdgeStatus(edgeId);
|
|
477
493
|
return status?.activeTunnels || 0;
|
|
478
494
|
}
|
|
495
|
+
getTransportHtml(edgeId) {
|
|
496
|
+
const status = this.getEdgeStatus(edgeId);
|
|
497
|
+
if (!status?.connected)
|
|
498
|
+
return '-';
|
|
499
|
+
const mode = status.transportMode || 'unknown';
|
|
500
|
+
const label = mode === 'quic' ? 'QUIC' : mode === 'tcpTls' ? 'TCP/TLS' : mode;
|
|
501
|
+
return html `<div class="metricStack"><strong>${label}</strong><span class="metricMuted">${status.fallbackUsed ? 'fallback' : status.performance?.profile || 'default'}</span></div>`;
|
|
502
|
+
}
|
|
503
|
+
getWindowHtml(edgeId) {
|
|
504
|
+
const status = this.getEdgeStatus(edgeId);
|
|
505
|
+
if (!status?.connected || !status.flowControl)
|
|
506
|
+
return '-';
|
|
507
|
+
if (!status.flowControl.applies) {
|
|
508
|
+
return html `<div class="metricStack"><span>native QUIC</span><span class="metricMuted">max ${status.performance?.maxStreamsPerEdge || '-'} streams</span></div>`;
|
|
509
|
+
}
|
|
510
|
+
return html `
|
|
511
|
+
<div class="metricStack">
|
|
512
|
+
<span>${this.formatBytes(status.flowControl.currentWindowBytes)} window</span>
|
|
513
|
+
<span class="metricMuted">${this.formatBytes(status.flowControl.estimatedInFlightBytes)} est. in-flight</span>
|
|
514
|
+
</div>
|
|
515
|
+
`;
|
|
516
|
+
}
|
|
517
|
+
getQueuesHtml(edgeId) {
|
|
518
|
+
const status = this.getEdgeStatus(edgeId);
|
|
519
|
+
if (!status?.connected || !status.queues)
|
|
520
|
+
return '-';
|
|
521
|
+
return html `<div class="metricStack"><span>C ${status.queues.ctrlQueueDepth} / D ${status.queues.dataQueueDepth}</span><span class="metricMuted">S ${status.queues.sustainedQueueDepth}</span></div>`;
|
|
522
|
+
}
|
|
523
|
+
getTrafficHtml(edgeId) {
|
|
524
|
+
const status = this.getEdgeStatus(edgeId);
|
|
525
|
+
if (!status?.connected || !status.traffic)
|
|
526
|
+
return '-';
|
|
527
|
+
const drops = (status.traffic.rejectedStreams || 0) + (status.udp?.droppedDatagrams || 0);
|
|
528
|
+
return html `
|
|
529
|
+
<div class="metricStack">
|
|
530
|
+
<span>${this.formatBytes(status.traffic.bytesIn)} in / ${this.formatBytes(status.traffic.bytesOut)} out</span>
|
|
531
|
+
<span class="metricMuted">${drops} rejected/dropped</span>
|
|
532
|
+
</div>
|
|
533
|
+
`;
|
|
534
|
+
}
|
|
479
535
|
getLastHeartbeat(edgeId) {
|
|
480
536
|
const status = this.getEdgeStatus(edgeId);
|
|
481
537
|
if (!status?.lastHeartbeat)
|
|
@@ -487,6 +543,18 @@ let OpsViewRemoteIngress = (() => {
|
|
|
487
543
|
return `${Math.floor(ago / 60000)}m ago`;
|
|
488
544
|
return `${Math.floor(ago / 3600000)}h ago`;
|
|
489
545
|
}
|
|
546
|
+
formatBytes(bytes) {
|
|
547
|
+
if (!Number.isFinite(bytes) || bytes <= 0)
|
|
548
|
+
return '0 B';
|
|
549
|
+
const units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
550
|
+
let value = bytes;
|
|
551
|
+
let unitIndex = 0;
|
|
552
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
553
|
+
value = value / 1024;
|
|
554
|
+
unitIndex++;
|
|
555
|
+
}
|
|
556
|
+
return `${value >= 10 || unitIndex === 0 ? value.toFixed(0) : value.toFixed(1)} ${units[unitIndex]}`;
|
|
557
|
+
}
|
|
490
558
|
static {
|
|
491
559
|
__runInitializers(_classThis, _classExtraInitializers);
|
|
492
560
|
}
|
|
@@ -494,4 +562,4 @@ let OpsViewRemoteIngress = (() => {
|
|
|
494
562
|
return OpsViewRemoteIngress = _classThis;
|
|
495
563
|
})();
|
|
496
564
|
export { OpsViewRemoteIngress };
|
|
497
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctcmVtb3RlaW5ncmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RzX3dlYi9lbGVtZW50cy9uZXR3b3JrL29wcy12aWV3LXJlbW90ZWluZ3Jlc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sRUFDTCxXQUFXLEVBQ1gsSUFBSSxFQUNKLGFBQWEsRUFFYixHQUFHLEVBQ0gsS0FBSyxFQUNMLFVBQVUsR0FDWCxNQUFNLDZCQUE2QixDQUFDO0FBQ3JDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLFVBQVUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDL0MsT0FBTyxFQUFtQixNQUFNLDZCQUE2QixDQUFDO0lBU2pELG9CQUFvQjs0QkFEaEMsYUFBYSxDQUFDLHdCQUF3QixDQUFDOzs7O3NCQUNFLFdBQVc7Ozs7b0NBQW5CLFNBQVEsV0FBVzs7OzttQ0FDbEQsS0FBSyxFQUFFO1lBQ1IsMEtBQVMsT0FBTyw2QkFBUCxPQUFPLHlGQUE2RTtZQUYvRiw2S0FnY0M7Ozs7UUE5YkMsMkVBQWlELFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxRQUFRLEVBQUcsRUFBQztRQUE3RixJQUFTLE9BQU8sNkNBQTZFO1FBQTdGLElBQVMsT0FBTyxtREFBNkU7UUFFN0Y7WUFDRSxLQUFLLEVBQUUsQ0FBQzs7WUFDUixNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsc0JBQXNCLENBQUMsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7Z0JBQzFFLElBQUksQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDO1lBQzFCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFD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
|
|
565
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BzLXZpZXctcmVtb3RlaW5ncmVzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3RzX3dlYi9lbGVtZW50cy9uZXR3b3JrL29wcy12aWV3LXJlbW90ZWluZ3Jlc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sRUFDTCxXQUFXLEVBQ1gsSUFBSSxFQUNKLGFBQWEsRUFFYixHQUFHLEVBQ0gsS0FBSyxFQUNMLFVBQVUsR0FDWCxNQUFNLDZCQUE2QixDQUFDO0FBQ3JDLE9BQU8sS0FBSyxRQUFRLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxLQUFLLFVBQVUsTUFBTSxzQ0FBc0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDL0MsT0FBTyxFQUFtQixNQUFNLDZCQUE2QixDQUFDO0lBU2pELG9CQUFvQjs0QkFEaEMsYUFBYSxDQUFDLHdCQUF3QixDQUFDOzs7O3NCQUNFLFdBQVc7Ozs7b0NBQW5CLFNBQVEsV0FBVzs7OzttQ0FDbEQsS0FBSyxFQUFFO1lBQ1IsMEtBQVMsT0FBTyw2QkFBUCxPQUFPLHlGQUE2RTtZQUYvRiw2S0FvZ0JDOzs7O1FBbGdCQywyRUFBaUQsUUFBUSxDQUFDLHNCQUFzQixDQUFDLFFBQVEsRUFBRyxFQUFDO1FBQTdGLElBQVMsT0FBTyw2Q0FBNkU7UUFBN0YsSUFBUyxPQUFPLG1EQUE2RTtRQUU3RjtZQUNFLEtBQUssRUFBRSxDQUFDOztZQUNSLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDMUUsSUFBSSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7WUFDMUIsQ0FBQyxDQUFDLENBQUM7WUFDSCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxHQUFHLENB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
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serve.zone/dcrouter",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "13.
|
|
4
|
+
"version": "13.23.0",
|
|
5
5
|
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@push.rocks/smartnetwork": "^4.6.0",
|
|
55
55
|
"@push.rocks/smartpath": "^6.0.0",
|
|
56
56
|
"@push.rocks/smartpromise": "^4.2.3",
|
|
57
|
-
"@push.rocks/smartproxy": "^27.
|
|
57
|
+
"@push.rocks/smartproxy": "^27.9.0",
|
|
58
58
|
"@push.rocks/smartradius": "^1.1.1",
|
|
59
59
|
"@push.rocks/smartrequest": "^5.0.1",
|
|
60
60
|
"@push.rocks/smartrx": "^3.0.10",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"@push.rocks/taskbuffer": "^8.0.2",
|
|
65
65
|
"@serve.zone/catalog": "^2.12.4",
|
|
66
66
|
"@serve.zone/interfaces": "^5.4.3",
|
|
67
|
-
"@serve.zone/remoteingress": "^4.
|
|
67
|
+
"@serve.zone/remoteingress": "^4.17.1",
|
|
68
68
|
"@tsclass/tsclass": "^9.5.0",
|
|
69
69
|
"@types/qrcode": "^1.5.6",
|
|
70
70
|
"lru-cache": "^11.3.5",
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/classes.dcrouter.ts
CHANGED
|
@@ -27,12 +27,13 @@ import { RemoteIngressManager, TunnelManager } from './remoteingress/index.js';
|
|
|
27
27
|
import { VpnManager, type IVpnManagerConfig } from './vpn/index.js';
|
|
28
28
|
import { RouteConfigManager, ApiTokenManager, ReferenceResolver, DbSeeder, TargetProfileManager } from './config/index.js';
|
|
29
29
|
import type { TIpAllowEntry } from './config/classes.route-config-manager.js';
|
|
30
|
-
import { SecurityLogger, ContentScanner, IPReputationChecker } from './security/index.js';
|
|
30
|
+
import { SecurityLogger, ContentScanner, IPReputationChecker, SecurityPolicyManager } from './security/index.js';
|
|
31
31
|
import { type IHttp3Config, augmentRoutesWithHttp3 } from './http3/index.js';
|
|
32
32
|
import { DnsManager } from './dns/manager.dns.js';
|
|
33
33
|
import { AcmeConfigManager } from './acme/manager.acme-config.js';
|
|
34
34
|
import { EmailDomainManager, SmartMtaStorageManager, buildEmailDnsRecords } from './email/index.js';
|
|
35
35
|
import type { IRoute } from '../ts_interfaces/data/route-management.js';
|
|
36
|
+
import type { ISecurityCompiledPolicy } from '../ts_interfaces/data/security-policy.js';
|
|
36
37
|
|
|
37
38
|
export interface IDcRouterOptions {
|
|
38
39
|
/** Base directory for all dcrouter data. Defaults to ~/.serve.zone/dcrouter */
|
|
@@ -178,6 +179,8 @@ export interface IDcRouterOptions {
|
|
|
178
179
|
certPath?: string;
|
|
179
180
|
keyPath?: string;
|
|
180
181
|
};
|
|
182
|
+
/** Performance profile and limits for remote ingress hub/edge tunnels. */
|
|
183
|
+
performance?: import('../ts_interfaces/data/remoteingress.js').IRemoteIngressPerformanceConfig;
|
|
181
184
|
};
|
|
182
185
|
|
|
183
186
|
/**
|
|
@@ -282,6 +285,7 @@ export class DcRouter {
|
|
|
282
285
|
// ACME configuration (DB-backed singleton, replaces tls.contactEmail)
|
|
283
286
|
public acmeConfigManager?: AcmeConfigManager;
|
|
284
287
|
public emailDomainManager?: EmailDomainManager;
|
|
288
|
+
public securityPolicyManager?: SecurityPolicyManager;
|
|
285
289
|
|
|
286
290
|
// Auto-discovered public IP (populated by generateAuthoritativeRecords)
|
|
287
291
|
public detectedPublicIp: string | null = null;
|
|
@@ -469,12 +473,36 @@ export class DcRouter {
|
|
|
469
473
|
);
|
|
470
474
|
}
|
|
471
475
|
|
|
476
|
+
// SecurityPolicyManager: optional, depends on DcRouterDb — owns IP intelligence
|
|
477
|
+
// and compiles the global block policy for SmartProxy and remote ingress edges.
|
|
478
|
+
if (this.options.dbConfig?.enabled !== false) {
|
|
479
|
+
this.serviceManager.addService(
|
|
480
|
+
new plugins.taskbuffer.Service('SecurityPolicyManager')
|
|
481
|
+
.optional()
|
|
482
|
+
.dependsOn('DcRouterDb')
|
|
483
|
+
.withStart(async () => {
|
|
484
|
+
this.securityPolicyManager = new SecurityPolicyManager({
|
|
485
|
+
onPolicyChanged: () => this.applySecurityPolicy(),
|
|
486
|
+
});
|
|
487
|
+
await this.securityPolicyManager.start();
|
|
488
|
+
})
|
|
489
|
+
.withStop(async () => {
|
|
490
|
+
if (this.securityPolicyManager) {
|
|
491
|
+
await this.securityPolicyManager.stop();
|
|
492
|
+
this.securityPolicyManager = undefined;
|
|
493
|
+
}
|
|
494
|
+
})
|
|
495
|
+
.withRetry({ maxRetries: 1, baseDelayMs: 500 }),
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
|
|
472
499
|
// SmartProxy: critical, depends on DcRouterDb + DnsManager + AcmeConfigManager (if enabled)
|
|
473
500
|
const smartProxyDeps: string[] = [];
|
|
474
501
|
if (this.options.dbConfig?.enabled !== false) {
|
|
475
502
|
smartProxyDeps.push('DcRouterDb');
|
|
476
503
|
smartProxyDeps.push('DnsManager');
|
|
477
504
|
smartProxyDeps.push('AcmeConfigManager');
|
|
505
|
+
smartProxyDeps.push('SecurityPolicyManager');
|
|
478
506
|
}
|
|
479
507
|
this.serviceManager.addService(
|
|
480
508
|
new plugins.taskbuffer.Service('SmartProxy')
|
|
@@ -570,12 +598,16 @@ export class DcRouter {
|
|
|
570
598
|
this.referenceResolver,
|
|
571
599
|
// Sync routes to RemoteIngressManager whenever routes change,
|
|
572
600
|
// then push updated derived ports to the Rust hub binary
|
|
573
|
-
(routes) => {
|
|
601
|
+
async (routes) => {
|
|
574
602
|
if (this.remoteIngressManager) {
|
|
575
603
|
this.remoteIngressManager.setRoutes(routes as any[]);
|
|
576
604
|
}
|
|
577
605
|
if (this.tunnelManager) {
|
|
578
|
-
|
|
606
|
+
try {
|
|
607
|
+
await this.tunnelManager.syncAllowedEdges();
|
|
608
|
+
} catch (err: unknown) {
|
|
609
|
+
logger.log('error', `Failed to sync Remote Ingress allowed edges: ${(err as Error).message}`);
|
|
610
|
+
}
|
|
579
611
|
}
|
|
580
612
|
},
|
|
581
613
|
undefined,
|
|
@@ -965,6 +997,12 @@ export class DcRouter {
|
|
|
965
997
|
logger.log('info', 'HTTP/3: Augmented qualifying HTTPS routes with QUIC/H3 configuration');
|
|
966
998
|
}
|
|
967
999
|
|
|
1000
|
+
const compiledSecurityPolicy = await this.securityPolicyManager?.compileSmartProxyPolicy();
|
|
1001
|
+
const mergedSecurityPolicy = this.mergeSecurityPolicies(
|
|
1002
|
+
(this.options.smartProxyConfig as any)?.securityPolicy,
|
|
1003
|
+
compiledSecurityPolicy,
|
|
1004
|
+
);
|
|
1005
|
+
|
|
968
1006
|
// If we have routes or need a basic SmartProxy instance, create it
|
|
969
1007
|
if (routes.length > 0 || this.options.smartProxyConfig) {
|
|
970
1008
|
logger.log('info', 'Setting up SmartProxy with combined configuration');
|
|
@@ -996,6 +1034,7 @@ export class DcRouter {
|
|
|
996
1034
|
// --- always set by dcrouter (after spread) ---
|
|
997
1035
|
routes,
|
|
998
1036
|
acme: acmeConfig,
|
|
1037
|
+
...(mergedSecurityPolicy ? { securityPolicy: mergedSecurityPolicy } as any : {}),
|
|
999
1038
|
certStore: {
|
|
1000
1039
|
loadAll: async () => {
|
|
1001
1040
|
const docs = await ProxyCertDoc.findAll();
|
|
@@ -1120,7 +1159,12 @@ export class DcRouter {
|
|
|
1120
1159
|
// to SmartProxy with PROXY protocol v1 headers to preserve client IPs.
|
|
1121
1160
|
if (this.options.remoteIngressConfig?.enabled) {
|
|
1122
1161
|
smartProxyConfig.acceptProxyProtocol = true;
|
|
1123
|
-
smartProxyConfig.proxyIPs
|
|
1162
|
+
if (!smartProxyConfig.proxyIPs) {
|
|
1163
|
+
smartProxyConfig.proxyIPs = [];
|
|
1164
|
+
}
|
|
1165
|
+
if (!smartProxyConfig.proxyIPs.includes('127.0.0.1')) {
|
|
1166
|
+
smartProxyConfig.proxyIPs.push('127.0.0.1');
|
|
1167
|
+
}
|
|
1124
1168
|
}
|
|
1125
1169
|
|
|
1126
1170
|
// VPN uses socket mode with PP v2 — SmartProxy must accept proxy protocol from localhost
|
|
@@ -1233,8 +1277,60 @@ export class DcRouter {
|
|
|
1233
1277
|
logger.log('info', `SmartProxy started with ${routes.length} routes`);
|
|
1234
1278
|
}
|
|
1235
1279
|
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1280
|
+
|
|
1281
|
+
public async applySecurityPolicy(): Promise<void> {
|
|
1282
|
+
if (!this.securityPolicyManager) {
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
const compiledSmartProxyPolicy = await this.securityPolicyManager.compileSmartProxyPolicy();
|
|
1287
|
+
const mergedSecurityPolicy = this.mergeSecurityPolicies(
|
|
1288
|
+
(this.options.smartProxyConfig as any)?.securityPolicy,
|
|
1289
|
+
compiledSmartProxyPolicy,
|
|
1290
|
+
);
|
|
1291
|
+
|
|
1292
|
+
if (this.smartProxy && mergedSecurityPolicy) {
|
|
1293
|
+
const smartProxyWithPolicyApi = this.smartProxy as any;
|
|
1294
|
+
if (typeof smartProxyWithPolicyApi.updateSecurityPolicy === 'function') {
|
|
1295
|
+
await smartProxyWithPolicyApi.updateSecurityPolicy(mergedSecurityPolicy);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
const firewallConfig = await this.securityPolicyManager.compileRemoteIngressFirewall();
|
|
1300
|
+
if (this.remoteIngressManager) {
|
|
1301
|
+
(this.remoteIngressManager as any).setFirewallConfig?.(firewallConfig);
|
|
1302
|
+
}
|
|
1303
|
+
if (this.tunnelManager) {
|
|
1304
|
+
await this.tunnelManager.syncAllowedEdges();
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
private mergeSecurityPolicies(
|
|
1309
|
+
...policies: Array<Partial<ISecurityCompiledPolicy> | undefined>
|
|
1310
|
+
): ISecurityCompiledPolicy | undefined {
|
|
1311
|
+
const blockedIps = new Set<string>();
|
|
1312
|
+
const blockedCidrs = new Set<string>();
|
|
1313
|
+
|
|
1314
|
+
for (const policy of policies) {
|
|
1315
|
+
for (const ip of policy?.blockedIps || []) {
|
|
1316
|
+
if (ip) blockedIps.add(ip);
|
|
1317
|
+
}
|
|
1318
|
+
for (const cidr of policy?.blockedCidrs || []) {
|
|
1319
|
+
if (cidr) blockedCidrs.add(cidr);
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
if (blockedIps.size === 0 && blockedCidrs.size === 0) {
|
|
1324
|
+
return undefined;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
return {
|
|
1328
|
+
blockedIps: [...blockedIps].sort(),
|
|
1329
|
+
blockedCidrs: [...blockedCidrs].sort(),
|
|
1330
|
+
};
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
|
|
1238
1334
|
|
|
1239
1335
|
/**
|
|
1240
1336
|
* Generate SmartProxy routes for email configuration
|
|
@@ -2221,6 +2317,9 @@ export class DcRouter {
|
|
|
2221
2317
|
// Initialize the edge registration manager
|
|
2222
2318
|
this.remoteIngressManager = new RemoteIngressManager();
|
|
2223
2319
|
await this.remoteIngressManager.initialize();
|
|
2320
|
+
this.remoteIngressManager.setFirewallConfig(
|
|
2321
|
+
await this.securityPolicyManager?.compileRemoteIngressFirewall(),
|
|
2322
|
+
);
|
|
2224
2323
|
|
|
2225
2324
|
// Pass current bootstrap routes so the manager can derive edge ports initially.
|
|
2226
2325
|
// Once RouteConfigManager applies the full DB set, the onRoutesApplied callback
|
|
@@ -2270,6 +2369,7 @@ export class DcRouter {
|
|
|
2270
2369
|
tunnelPort: riCfg.tunnelPort ?? 8443,
|
|
2271
2370
|
targetHost: '127.0.0.1',
|
|
2272
2371
|
tls: tlsConfig,
|
|
2372
|
+
performance: riCfg.performance,
|
|
2273
2373
|
});
|
|
2274
2374
|
await this.tunnelManager.start();
|
|
2275
2375
|
|
|
@@ -59,7 +59,7 @@ export class RouteConfigManager {
|
|
|
59
59
|
private getHttp3Config?: () => IHttp3Config | undefined,
|
|
60
60
|
private getVpnClientIpsForRoute?: (route: IDcRouterRouteConfig, routeId?: string) => TIpAllowEntry[],
|
|
61
61
|
private referenceResolver?: ReferenceResolver,
|
|
62
|
-
private onRoutesApplied?: (routes: plugins.smartproxy.IRouteConfig[]) => void
|
|
62
|
+
private onRoutesApplied?: (routes: plugins.smartproxy.IRouteConfig[]) => void | Promise<void>,
|
|
63
63
|
private getRuntimeRoutes?: () => plugins.smartproxy.IRouteConfig[],
|
|
64
64
|
private hydrateStoredRoute?: (storedRoute: IRoute) => plugins.smartproxy.IRouteConfig | undefined,
|
|
65
65
|
) {}
|
|
@@ -540,7 +540,7 @@ export class RouteConfigManager {
|
|
|
540
540
|
|
|
541
541
|
// Notify listeners (e.g. RemoteIngressManager) of the route set
|
|
542
542
|
if (this.onRoutesApplied) {
|
|
543
|
-
this.onRoutesApplied(enabledRoutes);
|
|
543
|
+
await this.onRoutesApplied(enabledRoutes);
|
|
544
544
|
}
|
|
545
545
|
|
|
546
546
|
logger.log('info', `Applied ${enabledRoutes.length} routes to SmartProxy (${this.routes.size} total)`);
|