@serve.zone/dcrouter 11.18.0 → 11.19.1
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 +1 -1
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/vpn/classes.vpn-manager.js +6 -18
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/package.json +2 -2
- package/readme.md +111 -29
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/vpn/classes.vpn-manager.ts +5 -30
- package/ts_web/00_commitinfo_data.ts +1 -1
package/dist_serve/bundle.js
CHANGED
|
@@ -43361,4 +43361,4 @@ ibantools/jsnext/ibantools.js:
|
|
|
43361
43361
|
* @preferred
|
|
43362
43362
|
*)
|
|
43363
43363
|
*/
|
|
43364
|
-
//# sourceMappingURL=bundle-
|
|
43364
|
+
//# sourceMappingURL=bundle-1774894531013.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '11.
|
|
6
|
+
version: '11.19.1',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFNBQVM7SUFDbEIsV0FBVyxFQUFFLDBFQUEwRTtDQUN4RixDQUFBIn0=
|
|
@@ -67,6 +67,10 @@ export class VpnManager {
|
|
|
67
67
|
socketForwardProxyProtocol: true,
|
|
68
68
|
destinationPolicy: this.config.destinationPolicy
|
|
69
69
|
?? { default: 'forceTarget', target: '127.0.0.1' },
|
|
70
|
+
serverEndpoint: this.config.serverEndpoint
|
|
71
|
+
? `${this.config.serverEndpoint}:${wgListenPort}`
|
|
72
|
+
: undefined,
|
|
73
|
+
clientAllowedIPs: [subnet],
|
|
70
74
|
};
|
|
71
75
|
await this.vpnServer.start(serverConfig);
|
|
72
76
|
// Create initial clients from config (idempotent — skip already-persisted)
|
|
@@ -113,11 +117,6 @@ export class VpnManager {
|
|
|
113
117
|
serverDefinedClientTags: opts.serverDefinedClientTags,
|
|
114
118
|
description: opts.description,
|
|
115
119
|
});
|
|
116
|
-
// Update WireGuard config endpoint if serverEndpoint is configured
|
|
117
|
-
if (this.config.serverEndpoint && bundle.wireguardConfig) {
|
|
118
|
-
const wgPort = this.config.wgListenPort ?? 51820;
|
|
119
|
-
bundle.wireguardConfig = bundle.wireguardConfig.replace(/Endpoint\s*=\s*.+/, `Endpoint = ${this.config.serverEndpoint}:${wgPort}`);
|
|
120
|
-
}
|
|
121
120
|
// Persist client entry (without private keys)
|
|
122
121
|
const persisted = {
|
|
123
122
|
clientId: bundle.entry.clientId,
|
|
@@ -191,11 +190,6 @@ export class VpnManager {
|
|
|
191
190
|
if (!this.vpnServer)
|
|
192
191
|
throw new Error('VPN server not running');
|
|
193
192
|
const bundle = await this.vpnServer.rotateClientKey(clientId);
|
|
194
|
-
// Update endpoint in WireGuard config
|
|
195
|
-
if (this.config.serverEndpoint && bundle.wireguardConfig) {
|
|
196
|
-
const wgPort = this.config.wgListenPort ?? 51820;
|
|
197
|
-
bundle.wireguardConfig = bundle.wireguardConfig.replace(/Endpoint\s*=\s*.+/, `Endpoint = ${this.config.serverEndpoint}:${wgPort}`);
|
|
198
|
-
}
|
|
199
193
|
// Update persisted entry with new public keys
|
|
200
194
|
const client = this.clients.get(clientId);
|
|
201
195
|
if (client) {
|
|
@@ -212,13 +206,7 @@ export class VpnManager {
|
|
|
212
206
|
async exportClientConfig(clientId, format) {
|
|
213
207
|
if (!this.vpnServer)
|
|
214
208
|
throw new Error('VPN server not running');
|
|
215
|
-
|
|
216
|
-
// Update endpoint in WireGuard config
|
|
217
|
-
if (format === 'wireguard' && this.config.serverEndpoint) {
|
|
218
|
-
const wgPort = this.config.wgListenPort ?? 51820;
|
|
219
|
-
config = config.replace(/Endpoint\s*=\s*.+/, `Endpoint = ${this.config.serverEndpoint}:${wgPort}`);
|
|
220
|
-
}
|
|
221
|
-
return config;
|
|
209
|
+
return this.vpnServer.exportClientConfig(clientId, format);
|
|
222
210
|
}
|
|
223
211
|
// ── Tag-based access control ───────────────────────────────────────────
|
|
224
212
|
/**
|
|
@@ -326,4 +314,4 @@ export class VpnManager {
|
|
|
326
314
|
await this.storageManager.setJSON(`${STORAGE_PREFIX_CLIENTS}${client.clientId}`, client);
|
|
327
315
|
}
|
|
328
316
|
}
|
|
329
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy52cG4tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Zwbi9jbGFzc2VzLnZwbi1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHdEMsTUFBTSxtQkFBbUIsR0FBRyxrQkFBa0IsQ0FBQztBQUMvQyxNQUFNLHNCQUFzQixHQUFHLGVBQWUsQ0FBQztBQWtEL0M7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFDYixjQUFjLENBQWlCO0lBQy9CLE1BQU0sQ0FBb0I7SUFDMUIsU0FBUyxDQUE4QjtJQUN2QyxPQUFPLEdBQWtDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDbkQsVUFBVSxDQUF3QjtJQUUxQyxZQUFZLGNBQThCLEVBQUUsTUFBeUI7UUFDbkUsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7UUFDckMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVELDJCQUEyQjtJQUNwQixTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sSUFBSSxhQUFhLENBQUM7SUFDN0MsQ0FBQztJQUVELHlDQUF5QztJQUN6QyxJQUFXLE9BQU87UUFDaEIsT0FBTyxJQUFJLENBQUMsU0FBUyxFQUFFLE9BQU8sSUFBSSxLQUFLLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7T0FHRztJQUNJLEtBQUssQ0FBQyxLQUFLO1FBQ2hCLCtCQUErQjtRQUMvQixJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFFeEQseUJBQXlCO1FBQ3pCLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFFbEMsc0NBQXNDO1FBQ3RDLE1BQU0sYUFBYSxHQUFvQyxFQUFFLENB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
|
|
317
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy52cG4tbWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Zwbi9jbGFzc2VzLnZwbi1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHdEMsTUFBTSxtQkFBbUIsR0FBRyxrQkFBa0IsQ0FBQztBQUMvQyxNQUFNLHNCQUFzQixHQUFHLGVBQWUsQ0FBQztBQWtEL0M7OztHQUdHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFDYixjQUFjLENBQWlCO0lBQy9CLE1BQU0sQ0FBb0I7SUFDMUIsU0FBUyxDQUE4QjtJQUN2QyxPQUFPLEdBQWtDLElBQUksR0FBRyxFQUFFLENBQUM7SUFDbkQsVUFBVSxDQUF3QjtJQUUxQyxZQUFZLGNBQThCLEVBQUUsTUFBeUI7UUFDbkUsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7UUFDckMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVELDJCQUEyQjtJQUNwQixTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sSUFBSSxhQUFhLENBQUM7SUFDN0MsQ0FBQztJQUVELHlDQUF5QztJQUN6QyxJQUFXLE9BQU87UUFDaEIsT0FBTyxJQUFJLENBQUMsU0FBUyxFQUFFLE9BQU8sSUFBSSxLQUFLLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7T0FHRztJQUNJLEtBQUssQ0FBQyxLQUFLO1FBQ2hCLCtCQUErQjtRQUMvQixJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFFeEQseUJBQXlCO1FBQ3pCLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFFbEMsc0NBQXNDO1FBQ3RDLE1BQU0sYUFBYSxHQUFvQyxFQUFFLENB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
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@serve.zone/dcrouter',
|
|
6
|
-
version: '11.
|
|
6
|
+
version: '11.19.1',
|
|
7
7
|
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHNfd2ViLzAwX2NvbW1pdGluZm9fZGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUNILE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRztJQUN4QixJQUFJLEVBQUUsc0JBQXNCO0lBQzVCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLFdBQVcsRUFBRSwwRUFBMEU7Q0FDeEYsQ0FBQSJ9
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serve.zone/dcrouter",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "11.
|
|
4
|
+
"version": "11.19.1",
|
|
5
5
|
"description": "A multifaceted routing service handling mail and SMS delivery functions.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"@push.rocks/smartrx": "^3.0.10",
|
|
60
60
|
"@push.rocks/smartstate": "^2.3.0",
|
|
61
61
|
"@push.rocks/smartunique": "^3.0.9",
|
|
62
|
-
"@push.rocks/smartvpn": "1.
|
|
62
|
+
"@push.rocks/smartvpn": "1.16.1",
|
|
63
63
|
"@push.rocks/taskbuffer": "^8.0.2",
|
|
64
64
|
"@serve.zone/catalog": "^2.9.0",
|
|
65
65
|
"@serve.zone/interfaces": "^5.3.0",
|
package/readme.md
CHANGED
|
@@ -77,10 +77,13 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
|
|
|
77
77
|
### 🔐 VPN Access Control (powered by [smartvpn](https://code.foss.global/push.rocks/smartvpn))
|
|
78
78
|
- **WireGuard + native transports** — standard WireGuard clients (iOS, Android, macOS, Windows, Linux) plus custom WebSocket/QUIC tunnels
|
|
79
79
|
- **Route-level VPN gating** — mark any route with `vpn: { required: true }` to restrict access to VPN clients only
|
|
80
|
-
- **
|
|
81
|
-
- **
|
|
80
|
+
- **Tag-based access control** — assign `serverDefinedClientTags` to clients and restrict routes with `allowedServerDefinedClientTags`
|
|
81
|
+
- **Constructor-defined clients** — pre-define VPN clients with tags in config for declarative, code-driven setup
|
|
82
|
+
- **Rootless operation** — uses userspace NAT (smoltcp) with no root required
|
|
83
|
+
- **Destination policy** — configurable `forceTarget`, `block`, or `allow` with allowList/blockList for granular traffic control
|
|
84
|
+
- **Client management** — create, enable, disable, rotate keys, export WireGuard/SmartVPN configs via OpsServer API and dashboard
|
|
82
85
|
- **IP-based enforcement** — VPN clients get IPs from a configurable subnet; SmartProxy enforces `ipAllowList` per route
|
|
83
|
-
- **PROXY protocol v2** —
|
|
86
|
+
- **PROXY protocol v2** — the NAT engine sends PP v2 on outbound connections to preserve VPN client identity
|
|
84
87
|
|
|
85
88
|
### ⚡ High Performance
|
|
86
89
|
- **Rust-powered proxy engine** via SmartProxy for maximum throughput
|
|
@@ -261,7 +264,9 @@ const router = new DcRouter({
|
|
|
261
264
|
vpnConfig: {
|
|
262
265
|
enabled: true,
|
|
263
266
|
serverEndpoint: 'vpn.example.com',
|
|
264
|
-
|
|
267
|
+
clients: [
|
|
268
|
+
{ clientId: 'dev-laptop', serverDefinedClientTags: ['engineering'] },
|
|
269
|
+
],
|
|
265
270
|
},
|
|
266
271
|
|
|
267
272
|
// Persistent storage
|
|
@@ -367,8 +372,8 @@ graph TB
|
|
|
367
372
|
|
|
368
373
|
DcRouter acts purely as an **orchestrator** — it doesn't implement protocols itself. Instead, it wires together best-in-class packages for each protocol:
|
|
369
374
|
|
|
370
|
-
1. **On `start()`**: DcRouter initializes OpsServer (default port 3000, configurable via `opsServerPort`), then spins up SmartProxy, smartmta, SmartDNS, SmartRadius, and
|
|
371
|
-
2. **During operation**: Each service handles its own protocol independently. SmartProxy uses a Rust-powered engine for maximum throughput. smartmta uses a hybrid TypeScript + Rust architecture for reliable email delivery. RemoteIngress runs a Rust data plane for edge tunnel networking. SmartAcme v9 handles all certificate operations with built-in concurrency control and rate limiting.
|
|
375
|
+
1. **On `start()`**: DcRouter initializes OpsServer (default port 3000, configurable via `opsServerPort`), then spins up SmartProxy, smartmta, SmartDNS, SmartRadius, RemoteIngress, and SmartVPN based on which configs are provided. Services start in dependency order via `ServiceManager`.
|
|
376
|
+
2. **During operation**: Each service handles its own protocol independently. SmartProxy uses a Rust-powered engine for maximum throughput. smartmta uses a hybrid TypeScript + Rust architecture for reliable email delivery. RemoteIngress runs a Rust data plane for edge tunnel networking. SmartVPN runs a Rust data plane for WireGuard and custom transports. SmartAcme v9 handles all certificate operations with built-in concurrency control and rate limiting.
|
|
372
377
|
3. **On `stop()`**: All services are gracefully shut down in parallel, including cleanup of HTTP agents and DNS clients.
|
|
373
378
|
|
|
374
379
|
### Rust-Powered Architecture
|
|
@@ -381,6 +386,7 @@ DcRouter itself is a pure TypeScript orchestrator, but several of its core sub-c
|
|
|
381
386
|
| **smartmta** | `mailer-bin` | SMTP server + client, DKIM/SPF/DMARC, content scanning, IP reputation |
|
|
382
387
|
| **SmartDNS** | `smartdns-bin` | DNS server (UDP + DNS-over-HTTPS), DNSSEC, DNS client resolution |
|
|
383
388
|
| **RemoteIngress** | `remoteingress-bin` | Edge tunnel data plane, multiplexed streams, heartbeat management |
|
|
389
|
+
| **SmartVPN** | `smartvpn_daemon` | WireGuard (boringtun), Noise IK handshake, QUIC/WS transports, userspace NAT (smoltcp) |
|
|
384
390
|
| **SmartRadius** | — | Pure TypeScript (no Rust component) |
|
|
385
391
|
|
|
386
392
|
## Configuration Reference
|
|
@@ -456,7 +462,17 @@ interface IDcRouterOptions {
|
|
|
456
462
|
wgListenPort?: number; // default: 51820
|
|
457
463
|
dns?: string[]; // DNS servers pushed to VPN clients
|
|
458
464
|
serverEndpoint?: string; // Hostname in generated client configs
|
|
459
|
-
|
|
465
|
+
clients?: Array<{ // Pre-defined VPN clients
|
|
466
|
+
clientId: string;
|
|
467
|
+
serverDefinedClientTags?: string[];
|
|
468
|
+
description?: string;
|
|
469
|
+
}>;
|
|
470
|
+
destinationPolicy?: { // Traffic routing policy
|
|
471
|
+
default: 'forceTarget' | 'block' | 'allow';
|
|
472
|
+
target?: string; // IP for forceTarget (default: '127.0.0.1')
|
|
473
|
+
allowList?: string[]; // Pass through directly
|
|
474
|
+
blockList?: string[]; // Always block (overrides allowList)
|
|
475
|
+
};
|
|
460
476
|
};
|
|
461
477
|
|
|
462
478
|
// ── HTTP/3 (QUIC) ────────────────────────────────────────────
|
|
@@ -1014,17 +1030,34 @@ DcRouter integrates [`@push.rocks/smartvpn`](https://code.foss.global/push.rocks
|
|
|
1014
1030
|
|
|
1015
1031
|
1. **SmartVPN daemon** runs inside dcrouter with a Rust data plane (WireGuard via `boringtun`, custom protocol via Noise IK)
|
|
1016
1032
|
2. Clients connect and get assigned an IP from the VPN subnet (e.g. `10.8.0.0/24`)
|
|
1017
|
-
3.
|
|
1018
|
-
4.
|
|
1033
|
+
3. **Split tunnel** by default — generated WireGuard configs only route VPN subnet traffic through the tunnel (`AllowedIPs = 10.8.0.0/24`), so regular internet traffic stays direct
|
|
1034
|
+
4. Routes with `vpn: { required: true }` get `security.ipAllowList` automatically injected
|
|
1035
|
+
5. When `allowedServerDefinedClientTags` is set, only matching client IPs are injected (not the whole subnet)
|
|
1036
|
+
6. SmartProxy enforces the allowlist — only authorized VPN clients can access protected routes
|
|
1037
|
+
7. All VPN traffic is forced through SmartProxy via userspace NAT with PROXY protocol v2 — no root required
|
|
1019
1038
|
|
|
1020
|
-
###
|
|
1039
|
+
### Destination Policy
|
|
1021
1040
|
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1041
|
+
By default, VPN client traffic is redirected to localhost (SmartProxy) via `forceTarget`. You can customize this with a destination policy:
|
|
1042
|
+
|
|
1043
|
+
```typescript
|
|
1044
|
+
// Default: all traffic → SmartProxy
|
|
1045
|
+
destinationPolicy: { default: 'forceTarget', target: '127.0.0.1' }
|
|
1046
|
+
|
|
1047
|
+
// Allow direct access to a backend subnet
|
|
1048
|
+
destinationPolicy: {
|
|
1049
|
+
default: 'forceTarget',
|
|
1050
|
+
target: '127.0.0.1',
|
|
1051
|
+
allowList: ['192.168.190.*'], // direct access to this subnet
|
|
1052
|
+
blockList: ['192.168.190.1'], // except the gateway
|
|
1053
|
+
}
|
|
1026
1054
|
|
|
1027
|
-
|
|
1055
|
+
// Block everything except specific IPs
|
|
1056
|
+
destinationPolicy: {
|
|
1057
|
+
default: 'block',
|
|
1058
|
+
allowList: ['10.0.0.*', '192.168.1.*'],
|
|
1059
|
+
}
|
|
1060
|
+
```
|
|
1028
1061
|
|
|
1029
1062
|
### Configuration
|
|
1030
1063
|
|
|
@@ -1032,26 +1065,47 @@ DcRouter auto-detects: if running as root, it uses TUN mode; otherwise, it falls
|
|
|
1032
1065
|
const router = new DcRouter({
|
|
1033
1066
|
vpnConfig: {
|
|
1034
1067
|
enabled: true,
|
|
1035
|
-
subnet: '10.8.0.0/24',
|
|
1036
|
-
wgListenPort: 51820,
|
|
1068
|
+
subnet: '10.8.0.0/24', // VPN client IP pool (default)
|
|
1069
|
+
wgListenPort: 51820, // WireGuard UDP port (default)
|
|
1037
1070
|
serverEndpoint: 'vpn.example.com', // Hostname in generated client configs
|
|
1038
|
-
dns: ['1.1.1.1', '8.8.8.8'],
|
|
1039
|
-
|
|
1071
|
+
dns: ['1.1.1.1', '8.8.8.8'], // DNS servers pushed to clients
|
|
1072
|
+
|
|
1073
|
+
// Pre-define VPN clients with server-defined tags
|
|
1074
|
+
clients: [
|
|
1075
|
+
{ clientId: 'alice-laptop', serverDefinedClientTags: ['engineering'], description: 'Dev laptop' },
|
|
1076
|
+
{ clientId: 'bob-phone', serverDefinedClientTags: ['engineering', 'mobile'] },
|
|
1077
|
+
{ clientId: 'carol-desktop', serverDefinedClientTags: ['finance'] },
|
|
1078
|
+
],
|
|
1079
|
+
|
|
1080
|
+
// Optional: customize destination policy (default: forceTarget → localhost)
|
|
1081
|
+
// destinationPolicy: { default: 'forceTarget', target: '127.0.0.1', allowList: ['192.168.1.*'] },
|
|
1040
1082
|
},
|
|
1041
1083
|
smartProxyConfig: {
|
|
1042
1084
|
routes: [
|
|
1043
|
-
//
|
|
1085
|
+
// 🔐 VPN-only: any VPN client can access
|
|
1044
1086
|
{
|
|
1045
|
-
name: '
|
|
1046
|
-
match: { domains: ['
|
|
1087
|
+
name: 'internal-app',
|
|
1088
|
+
match: { domains: ['internal.example.com'], ports: [443] },
|
|
1047
1089
|
action: {
|
|
1048
1090
|
type: 'forward',
|
|
1049
1091
|
targets: [{ host: '192.168.1.50', port: 8080 }],
|
|
1050
1092
|
tls: { mode: 'terminate', certificate: 'auto' },
|
|
1051
1093
|
},
|
|
1052
|
-
vpn: { required: true },
|
|
1094
|
+
vpn: { required: true },
|
|
1053
1095
|
},
|
|
1054
|
-
//
|
|
1096
|
+
// 🔐 VPN + tag-restricted: only 'engineering' tagged clients
|
|
1097
|
+
{
|
|
1098
|
+
name: 'eng-dashboard',
|
|
1099
|
+
match: { domains: ['eng.example.com'], ports: [443] },
|
|
1100
|
+
action: {
|
|
1101
|
+
type: 'forward',
|
|
1102
|
+
targets: [{ host: '192.168.1.51', port: 8080 }],
|
|
1103
|
+
tls: { mode: 'terminate', certificate: 'auto' },
|
|
1104
|
+
},
|
|
1105
|
+
vpn: { required: true, allowedServerDefinedClientTags: ['engineering'] },
|
|
1106
|
+
// → alice + bob can access, carol cannot
|
|
1107
|
+
},
|
|
1108
|
+
// 🌐 Public: no VPN required
|
|
1055
1109
|
{
|
|
1056
1110
|
name: 'public-site',
|
|
1057
1111
|
match: { domains: ['example.com'], ports: [443] },
|
|
@@ -1066,17 +1120,29 @@ const router = new DcRouter({
|
|
|
1066
1120
|
});
|
|
1067
1121
|
```
|
|
1068
1122
|
|
|
1069
|
-
### Client
|
|
1123
|
+
### Client Tags
|
|
1070
1124
|
|
|
1071
|
-
|
|
1125
|
+
SmartVPN distinguishes between two types of client tags:
|
|
1126
|
+
|
|
1127
|
+
| Tag Type | Set By | Purpose |
|
|
1128
|
+
|----------|--------|---------|
|
|
1129
|
+
| `serverDefinedClientTags` | Admin (via config or API) | **Trusted** — used for route access control |
|
|
1130
|
+
| `clientDefinedClientTags` | Connecting client | **Informational** — displayed in dashboard, never used for security |
|
|
1131
|
+
|
|
1132
|
+
Routes with `allowedServerDefinedClientTags` only permit VPN clients whose admin-assigned tags match. Clients cannot influence their own server-defined tags.
|
|
1133
|
+
|
|
1134
|
+
### Client Management via OpsServer
|
|
1135
|
+
|
|
1136
|
+
The OpsServer dashboard and API provide full VPN client lifecycle management:
|
|
1072
1137
|
|
|
1073
1138
|
- **Create client** — generates WireGuard keypairs, assigns IP, returns a ready-to-use `.conf` file
|
|
1074
1139
|
- **Enable / Disable** — toggle client access without deleting
|
|
1075
1140
|
- **Rotate keys** — generate fresh keypairs (invalidates old ones)
|
|
1076
|
-
- **Export config** —
|
|
1141
|
+
- **Export config** — download in WireGuard (`.conf`) or SmartVPN (`.json`) format
|
|
1077
1142
|
- **Telemetry** — per-client bytes sent/received, keepalives, rate limiting
|
|
1143
|
+
- **Delete** — remove a client and revoke access
|
|
1078
1144
|
|
|
1079
|
-
Standard WireGuard clients on any platform (iOS, Android, macOS, Windows, Linux) can connect using the generated `.conf` file
|
|
1145
|
+
Standard WireGuard clients on any platform (iOS, Android, macOS, Windows, Linux) can connect using the generated `.conf` file — no custom VPN software needed.
|
|
1080
1146
|
|
|
1081
1147
|
## Certificate Management
|
|
1082
1148
|
|
|
@@ -1252,8 +1318,12 @@ The OpsServer provides a web-based management interface served on port 3000 by d
|
|
|
1252
1318
|
| 📊 **Overview** | Real-time server stats, CPU/memory, connection counts, email throughput |
|
|
1253
1319
|
| 🌐 **Network** | Active connections, top IPs, throughput rates, SmartProxy metrics |
|
|
1254
1320
|
| 📧 **Email** | Queue monitoring (queued/sent/failed), bounce records, security incidents |
|
|
1321
|
+
| 🛣️ **Routes** | Merged route list (hardcoded + programmatic), create/edit/toggle/override routes |
|
|
1322
|
+
| 🔑 **API Tokens** | Token management with scopes, create/revoke/roll/toggle |
|
|
1255
1323
|
| 🔐 **Certificates** | Domain-centric certificate overview, status, backoff info, reprovisioning, import/export |
|
|
1256
1324
|
| 🌍 **RemoteIngress** | Edge node management, connection status, token generation, enable/disable |
|
|
1325
|
+
| 🔐 **VPN** | VPN client management, server status, create/toggle/export/rotate/delete clients |
|
|
1326
|
+
| 📡 **RADIUS** | NAS client management, VLAN mappings, session monitoring, accounting |
|
|
1257
1327
|
| 📜 **Logs** | Real-time log viewer with level filtering and search |
|
|
1258
1328
|
| ⚙️ **Configuration** | Read-only view of current system configuration |
|
|
1259
1329
|
| 🛡️ **Security** | IP reputation, rate limit status, blocked connections |
|
|
@@ -1318,6 +1388,17 @@ All management is done via TypedRequest over HTTP POST to `/typedrequest`:
|
|
|
1318
1388
|
'getRecentLogs' // Retrieve system logs with filtering
|
|
1319
1389
|
'getLogStream' // Stream live logs
|
|
1320
1390
|
|
|
1391
|
+
// VPN
|
|
1392
|
+
'getVpnClients' // List all registered VPN clients
|
|
1393
|
+
'getVpnStatus' // VPN server status (running, subnet, port, keys)
|
|
1394
|
+
'createVpnClient' // Create client → returns WireGuard config (shown once)
|
|
1395
|
+
'deleteVpnClient' // Remove a VPN client
|
|
1396
|
+
'enableVpnClient' // Enable a disabled client
|
|
1397
|
+
'disableVpnClient' // Disable a client
|
|
1398
|
+
'rotateVpnClientKey' // Generate new keys (invalidates old ones)
|
|
1399
|
+
'exportVpnClientConfig' // Export WireGuard (.conf) or SmartVPN (.json) config
|
|
1400
|
+
'getVpnClientTelemetry' // Per-client bytes sent/received, keepalives
|
|
1401
|
+
|
|
1321
1402
|
// RADIUS
|
|
1322
1403
|
'getRadiusSessions' // Active RADIUS sessions
|
|
1323
1404
|
'getRadiusClients' // List NAS clients
|
|
@@ -1435,6 +1516,7 @@ const router = new DcRouter(options: IDcRouterOptions);
|
|
|
1435
1516
|
| `radiusServer` | `RadiusServer` | RADIUS server instance |
|
|
1436
1517
|
| `remoteIngressManager` | `RemoteIngressManager` | Edge registration CRUD manager |
|
|
1437
1518
|
| `tunnelManager` | `TunnelManager` | Tunnel lifecycle and status manager |
|
|
1519
|
+
| `vpnManager` | `VpnManager` | VPN server lifecycle and client CRUD manager |
|
|
1438
1520
|
| `storageManager` | `StorageManager` | Storage backend |
|
|
1439
1521
|
| `opsServer` | `OpsServer` | OpsServer/dashboard instance |
|
|
1440
1522
|
| `metricsManager` | `MetricsManager` | Metrics collector |
|
|
@@ -1575,7 +1657,7 @@ The Docker build supports multi-platform (`linux/amd64`, `linux/arm64`) via [tsd
|
|
|
1575
1657
|
|
|
1576
1658
|
## License and Legal Information
|
|
1577
1659
|
|
|
1578
|
-
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [
|
|
1660
|
+
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](./license) file.
|
|
1579
1661
|
|
|
1580
1662
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
|
1581
1663
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -127,6 +127,10 @@ export class VpnManager {
|
|
|
127
127
|
socketForwardProxyProtocol: true,
|
|
128
128
|
destinationPolicy: this.config.destinationPolicy
|
|
129
129
|
?? { default: 'forceTarget' as const, target: '127.0.0.1' },
|
|
130
|
+
serverEndpoint: this.config.serverEndpoint
|
|
131
|
+
? `${this.config.serverEndpoint}:${wgListenPort}`
|
|
132
|
+
: undefined,
|
|
133
|
+
clientAllowedIPs: [subnet],
|
|
130
134
|
};
|
|
131
135
|
|
|
132
136
|
await this.vpnServer.start(serverConfig);
|
|
@@ -184,15 +188,6 @@ export class VpnManager {
|
|
|
184
188
|
description: opts.description,
|
|
185
189
|
});
|
|
186
190
|
|
|
187
|
-
// Update WireGuard config endpoint if serverEndpoint is configured
|
|
188
|
-
if (this.config.serverEndpoint && bundle.wireguardConfig) {
|
|
189
|
-
const wgPort = this.config.wgListenPort ?? 51820;
|
|
190
|
-
bundle.wireguardConfig = bundle.wireguardConfig.replace(
|
|
191
|
-
/Endpoint\s*=\s*.+/,
|
|
192
|
-
`Endpoint = ${this.config.serverEndpoint}:${wgPort}`,
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
191
|
// Persist client entry (without private keys)
|
|
197
192
|
const persisted: IPersistedClient = {
|
|
198
193
|
clientId: bundle.entry.clientId,
|
|
@@ -270,15 +265,6 @@ export class VpnManager {
|
|
|
270
265
|
if (!this.vpnServer) throw new Error('VPN server not running');
|
|
271
266
|
const bundle = await this.vpnServer.rotateClientKey(clientId);
|
|
272
267
|
|
|
273
|
-
// Update endpoint in WireGuard config
|
|
274
|
-
if (this.config.serverEndpoint && bundle.wireguardConfig) {
|
|
275
|
-
const wgPort = this.config.wgListenPort ?? 51820;
|
|
276
|
-
bundle.wireguardConfig = bundle.wireguardConfig.replace(
|
|
277
|
-
/Endpoint\s*=\s*.+/,
|
|
278
|
-
`Endpoint = ${this.config.serverEndpoint}:${wgPort}`,
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
268
|
// Update persisted entry with new public keys
|
|
283
269
|
const client = this.clients.get(clientId);
|
|
284
270
|
if (client) {
|
|
@@ -296,18 +282,7 @@ export class VpnManager {
|
|
|
296
282
|
*/
|
|
297
283
|
public async exportClientConfig(clientId: string, format: 'smartvpn' | 'wireguard'): Promise<string> {
|
|
298
284
|
if (!this.vpnServer) throw new Error('VPN server not running');
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
// Update endpoint in WireGuard config
|
|
302
|
-
if (format === 'wireguard' && this.config.serverEndpoint) {
|
|
303
|
-
const wgPort = this.config.wgListenPort ?? 51820;
|
|
304
|
-
config = config.replace(
|
|
305
|
-
/Endpoint\s*=\s*.+/,
|
|
306
|
-
`Endpoint = ${this.config.serverEndpoint}:${wgPort}`,
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
return config;
|
|
285
|
+
return this.vpnServer.exportClientConfig(clientId, format);
|
|
311
286
|
}
|
|
312
287
|
|
|
313
288
|
// ── Tag-based access control ───────────────────────────────────────────
|