@push.rocks/smartvpn 1.21.0 → 2.0.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/assets/third-party-licenses.md +157 -0
- package/dist_rust/{smartvpn_daemon_linux_amd64 → smartvpn_daemon_linux_amd64_musl} +0 -0
- package/dist_rust/smartvpn_daemon_linux_amd64_musl.tsrust-build.json +14 -0
- package/dist_rust/{smartvpn_daemon_linux_arm64 → smartvpn_daemon_linux_arm64_musl} +0 -0
- package/dist_rust/smartvpn_daemon_linux_arm64_musl.tsrust-build.json +14 -0
- package/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/smartvpn.classes.vpnbridge.d.ts +3 -3
- package/dist_ts/smartvpn.classes.vpnbridge.js +13 -45
- package/dist_ts/smartvpn.classes.vpnclient.d.ts +5 -4
- package/dist_ts/smartvpn.classes.vpnclient.js +9 -5
- package/dist_ts/smartvpn.classes.vpnconfig.d.ts +1 -0
- package/dist_ts/smartvpn.classes.vpnconfig.js +52 -14
- package/dist_ts/smartvpn.classes.vpnserver.d.ts +17 -4
- package/dist_ts/smartvpn.classes.vpnserver.js +80 -40
- package/dist_ts/smartvpn.interfaces.d.ts +151 -16
- package/dist_ts/smartvpn.paths.d.ts +2 -0
- package/dist_ts/smartvpn.paths.js +14 -1
- package/notices/aho-corasick-license.txt +21 -0
- package/notices/cargo-dependencies.html +5202 -0
- package/notices/compiler-builtins-license.txt +275 -0
- package/notices/defmt-license.txt +25 -0
- package/notices/inventory.json +1427 -0
- package/notices/llvm-libunwind-license.txt +311 -0
- package/notices/mit-source-attributions.txt +31 -0
- package/notices/musl-copyright.txt +193 -0
- package/notices/proc-macro-error2-license.txt +21 -0
- package/notices/rust-standard-library.html +8266 -0
- package/notices/valuable-license.txt +25 -0
- package/package.json +8 -6
- package/readme.hints.md +69 -3
- package/readme.md +313 -5
- package/third-party-notices.md +81 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/smartvpn.classes.vpnbridge.ts +12 -50
- package/ts/smartvpn.classes.vpnclient.ts +9 -5
- package/ts/smartvpn.classes.vpnconfig.ts +49 -13
- package/ts/smartvpn.classes.vpnserver.ts +94 -40
- package/ts/smartvpn.interfaces.ts +155 -16
- package/ts/smartvpn.paths.ts +19 -0
|
@@ -21,18 +21,18 @@ export type TVpnTransportOptions = IVpnTransportStdio | IVpnTransportSocket;
|
|
|
21
21
|
// Client configuration
|
|
22
22
|
// ============================================================================
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
interface IVpnClientConfigBase {
|
|
25
25
|
/** Server WebSocket URL, e.g. wss://vpn.example.com/tunnel */
|
|
26
|
-
serverUrl
|
|
26
|
+
serverUrl?: string;
|
|
27
27
|
/** Server's static public key (base64) for Noise IK handshake */
|
|
28
28
|
serverPublicKey: string;
|
|
29
29
|
/** Client's Noise IK private key (base64) — required for SmartVPN native transport */
|
|
30
|
-
clientPrivateKey
|
|
30
|
+
clientPrivateKey?: string;
|
|
31
31
|
/** Client's Noise IK public key (base64) — for reference/display */
|
|
32
|
-
clientPublicKey
|
|
32
|
+
clientPublicKey?: string;
|
|
33
33
|
/** Optional DNS servers to use while connected */
|
|
34
34
|
dns?: string[];
|
|
35
|
-
/**
|
|
35
|
+
/** Inner TUN MTU in whole IP bytes, 576..65472 (default: 1420); not outer link MTU. */
|
|
36
36
|
mtu?: number;
|
|
37
37
|
/** Keepalive interval in seconds (default: 30) */
|
|
38
38
|
keepaliveIntervalSecs?: number;
|
|
@@ -41,7 +41,7 @@ export interface IVpnClientConfig {
|
|
|
41
41
|
/** For QUIC: SHA-256 hash of server certificate (base64) for cert pinning */
|
|
42
42
|
serverCertHash?: string;
|
|
43
43
|
/** Forwarding mode: 'tun' (TUN device, requires root) or 'testing' (no TUN).
|
|
44
|
-
* Default: 'testing'. */
|
|
44
|
+
* Default: native 'testing', WireGuard 'tun'. */
|
|
45
45
|
forwardingMode?: 'tun' | 'testing';
|
|
46
46
|
/** WireGuard: client private key (base64, X25519) */
|
|
47
47
|
wgPrivateKey?: string;
|
|
@@ -61,6 +61,30 @@ export interface IVpnClientConfig {
|
|
|
61
61
|
clientDefinedClientTags?: string[];
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
/** Native transports authenticate with Noise IK, independently of WireGuard. */
|
|
65
|
+
export interface IVpnNativeClientConfig extends IVpnClientConfigBase {
|
|
66
|
+
/** Explicit managed opt-in. Rejects a missing or differently bound server assignment. */
|
|
67
|
+
managedNetwork?: IManagedNetworkBinding;
|
|
68
|
+
transport?: 'auto' | 'websocket' | 'quic';
|
|
69
|
+
serverUrl: string;
|
|
70
|
+
clientPrivateKey: string;
|
|
71
|
+
clientPublicKey: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** WireGuard uses its own key and address; Noise credentials are not required. */
|
|
75
|
+
export interface IVpnWireguardClientConfig extends IVpnClientConfigBase {
|
|
76
|
+
transport: 'wireguard';
|
|
77
|
+
wgPrivateKey: string;
|
|
78
|
+
wgAddress: string;
|
|
79
|
+
wgEndpoint: string;
|
|
80
|
+
/** Explicit peer source/destination routing authority. Must not be empty. */
|
|
81
|
+
wgAllowedIps: string[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export type TVpnClientConfig = IVpnNativeClientConfig | IVpnWireguardClientConfig;
|
|
85
|
+
/** Retains the published config type name; both names enforce the transport union. */
|
|
86
|
+
export type IVpnClientConfig = TVpnClientConfig;
|
|
87
|
+
|
|
64
88
|
export interface IVpnClientOptions {
|
|
65
89
|
transport: TVpnTransportOptions;
|
|
66
90
|
config?: IVpnClientConfig;
|
|
@@ -85,7 +109,7 @@ export interface IVpnServerConfig {
|
|
|
85
109
|
subnet: string;
|
|
86
110
|
/** DNS servers pushed to clients */
|
|
87
111
|
dns?: string[];
|
|
88
|
-
/**
|
|
112
|
+
/** Inner TUN/forwarding packet ceiling in whole IP bytes, 576..65472 (default: 1420). */
|
|
89
113
|
mtu?: number;
|
|
90
114
|
/** Keepalive interval in seconds (default: 30) */
|
|
91
115
|
keepaliveIntervalSecs?: number;
|
|
@@ -93,8 +117,10 @@ export interface IVpnServerConfig {
|
|
|
93
117
|
enableNat?: boolean;
|
|
94
118
|
/** Forwarding mode: 'tun' (kernel TUN, requires root), 'socket' (userspace NAT),
|
|
95
119
|
* 'bridge' (L2 bridge to host LAN), 'hybrid' (per-client socket+bridge),
|
|
96
|
-
*
|
|
97
|
-
forwardingMode?: 'tun' | 'socket' | 'bridge' | 'hybrid' | 'testing';
|
|
120
|
+
* 'managed' (caller-owned node relay without host networking), or 'testing'. Default: 'testing'. */
|
|
121
|
+
forwardingMode?: 'tun' | 'socket' | 'bridge' | 'hybrid' | 'testing' | 'managed';
|
|
122
|
+
/** Required in managed mode. Bound to this process lifetime; not an authentication credential. */
|
|
123
|
+
managedAuthorityId?: string;
|
|
98
124
|
/** Default rate limit for new clients (bytes/sec). Omit for unlimited. */
|
|
99
125
|
defaultRateLimitBytesPerSec?: number;
|
|
100
126
|
/** Default burst size for new clients (bytes). Omit for unlimited. */
|
|
@@ -196,6 +222,8 @@ export type TVpnConnectionState =
|
|
|
196
222
|
| 'error';
|
|
197
223
|
|
|
198
224
|
export interface IVpnStatus {
|
|
225
|
+
/** Authenticated native assignment for this connection, absent after retirement. */
|
|
226
|
+
managedNetwork?: IManagedNetworkAssignment;
|
|
199
227
|
state: TVpnConnectionState;
|
|
200
228
|
assignedIp?: string;
|
|
201
229
|
serverAddr?: string;
|
|
@@ -276,11 +304,16 @@ export interface IVpnConnectionQuality {
|
|
|
276
304
|
// ============================================================================
|
|
277
305
|
|
|
278
306
|
export interface IVpnMtuInfo {
|
|
279
|
-
|
|
307
|
+
/** Actual inner TUN ceiling; null in testing mode because no TUN exists. */
|
|
308
|
+
tunMtu: number | null;
|
|
309
|
+
/** Enforced inner packet ceiling, not an estimated outer path MTU. */
|
|
280
310
|
effectiveMtu: number;
|
|
281
|
-
|
|
282
|
-
|
|
311
|
+
/** Null when the transport has not measured the outer link. */
|
|
312
|
+
linkMtu: number | null;
|
|
313
|
+
/** Null when the transport has not measured encapsulation overhead. */
|
|
314
|
+
overheadBytes: number | null;
|
|
283
315
|
oversizedPacketsDropped: number;
|
|
316
|
+
/** Feedback packets successfully written to the client TUN, not just generated. */
|
|
284
317
|
icmpTooBigSent: number;
|
|
285
318
|
}
|
|
286
319
|
|
|
@@ -384,6 +417,21 @@ export interface IClientEntry {
|
|
|
384
417
|
vlanId?: number;
|
|
385
418
|
}
|
|
386
419
|
|
|
420
|
+
/** Admin-writable settings. Omission preserves a setting; null clears it.
|
|
421
|
+
* Identity, keys, assignment and client-reported tags have separate owners.
|
|
422
|
+
* A supplied security object replaces the complete previous security object. */
|
|
423
|
+
export type TClientUpdateOptions = {
|
|
424
|
+
[TField in keyof Omit<
|
|
425
|
+
IClientEntry,
|
|
426
|
+
'clientId' | 'publicKey' | 'wgPublicKey' | 'assignedIp' | 'clientDefinedClientTags'
|
|
427
|
+
>]?: IClientEntry[TField] | null;
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
/** Creation generates server-owned keys and assignment; clientId is required. */
|
|
431
|
+
export interface IClientCreateOptions extends TClientUpdateOptions {
|
|
432
|
+
clientId: string;
|
|
433
|
+
}
|
|
434
|
+
|
|
387
435
|
/**
|
|
388
436
|
* Complete client config bundle — returned by createClient() and rotateClientKey().
|
|
389
437
|
* Contains everything the client needs to connect.
|
|
@@ -392,7 +440,7 @@ export interface IClientConfigBundle {
|
|
|
392
440
|
/** The server-side client entry */
|
|
393
441
|
entry: IClientEntry;
|
|
394
442
|
/** Ready-to-use SmartVPN client config (typed object) */
|
|
395
|
-
smartvpnConfig:
|
|
443
|
+
smartvpnConfig: IVpnNativeClientConfig;
|
|
396
444
|
/** Ready-to-use WireGuard .conf file content (string) */
|
|
397
445
|
wireguardConfig: string;
|
|
398
446
|
/** Client's private keys (ONLY returned at creation time, not stored server-side) */
|
|
@@ -441,10 +489,13 @@ export type TVpnClientCommands = {
|
|
|
441
489
|
getStatus: { params: Record<string, never>; result: IVpnStatus };
|
|
442
490
|
getStatistics: { params: Record<string, never>; result: IVpnStatistics };
|
|
443
491
|
getConnectionQuality: { params: Record<string, never>; result: IVpnConnectionQuality };
|
|
444
|
-
getMtuInfo: { params: Record<string, never>; result: IVpnMtuInfo };
|
|
492
|
+
getMtuInfo: { params: Record<string, never>; result: IVpnMtuInfo | null };
|
|
445
493
|
};
|
|
446
494
|
|
|
447
495
|
export type TVpnServerCommands = {
|
|
496
|
+
reconcileManagedNetwork: { params: { snapshot: IManagedNetworkSnapshot }; result: IManagedNetworkStatus };
|
|
497
|
+
getManagedNetworkStatus: { params: Record<string, never>; result: IManagedNetworkStatus };
|
|
498
|
+
getManagedNodeProjection: { params: { nodeId: string }; result: IManagedNodeProjection };
|
|
448
499
|
start: { params: { config: IVpnServerConfig }; result: void };
|
|
449
500
|
stop: { params: Record<string, never>; result: void };
|
|
450
501
|
getStatus: { params: Record<string, never>; result: IVpnStatus };
|
|
@@ -460,11 +511,11 @@ export type TVpnServerCommands = {
|
|
|
460
511
|
removeWgPeer: { params: { publicKey: string }; result: void };
|
|
461
512
|
listWgPeers: { params: Record<string, never>; result: { peers: IWgPeerInfo[] } };
|
|
462
513
|
// Client Registry (Hub) commands
|
|
463
|
-
createClient: { params: { client:
|
|
514
|
+
createClient: { params: { client: IClientCreateOptions }; result: IClientConfigBundle };
|
|
464
515
|
removeClient: { params: { clientId: string }; result: void };
|
|
465
516
|
getClient: { params: { clientId: string }; result: IClientEntry };
|
|
466
517
|
listRegisteredClients: { params: Record<string, never>; result: { clients: IClientEntry[] } };
|
|
467
|
-
updateClient: { params: { clientId: string; update:
|
|
518
|
+
updateClient: { params: { clientId: string; update: TClientUpdateOptions }; result: void };
|
|
468
519
|
enableClient: { params: { clientId: string }; result: void };
|
|
469
520
|
disableClient: { params: { clientId: string }; result: void };
|
|
470
521
|
rotateClientKey: { params: { clientId: string }; result: IClientConfigBundle };
|
|
@@ -472,6 +523,94 @@ export type TVpnServerCommands = {
|
|
|
472
523
|
generateClientKeypair: { params: Record<string, never>; result: IVpnKeypair };
|
|
473
524
|
};
|
|
474
525
|
|
|
526
|
+
/** Complete schema-v1 authority. No patch semantics or implicit/reverse grants. */
|
|
527
|
+
export interface IManagedNetworkSnapshot {
|
|
528
|
+
schemaVersion: 1;
|
|
529
|
+
authorityId: string;
|
|
530
|
+
/** Positive JSON-safe integer, monotonically increasing within the server lifetime. */
|
|
531
|
+
revision: number;
|
|
532
|
+
nodes: IManagedNetworkNode[];
|
|
533
|
+
grants: IManagedNetworkGrant[];
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export interface IManagedNetworkNode {
|
|
537
|
+
nodeId: string;
|
|
538
|
+
publicKey: string;
|
|
539
|
+
wgPublicKey?: string;
|
|
540
|
+
controlAddress: string;
|
|
541
|
+
controlPolicyDomain: string;
|
|
542
|
+
enabled: boolean;
|
|
543
|
+
expiresAt?: string;
|
|
544
|
+
workloadPrefixes: IManagedNetworkPrefix[];
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
export interface IManagedNetworkPrefix {
|
|
548
|
+
cidr: string;
|
|
549
|
+
policyDomain: string;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
export interface IManagedNetworkGrant {
|
|
553
|
+
sourceDomain: string;
|
|
554
|
+
destinationDomain: string;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
export interface IManagedNetworkStatus {
|
|
558
|
+
authorityId: string;
|
|
559
|
+
lifetimeId: string;
|
|
560
|
+
state: 'idle' | 'applying' | 'failed';
|
|
561
|
+
appliedRevision: number | null;
|
|
562
|
+
pendingRevision: number | null;
|
|
563
|
+
stage: 'draining' | 'preparingTransport' | null;
|
|
564
|
+
lastError: string | null;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export interface IManagedNodeProjection {
|
|
568
|
+
schemaVersion: 1;
|
|
569
|
+
authorityId: string;
|
|
570
|
+
lifetimeId: string;
|
|
571
|
+
appliedRevision: number | null;
|
|
572
|
+
nodeId: string;
|
|
573
|
+
/** Configuration is applied/admissible, not proof of connectivity or host readiness. */
|
|
574
|
+
ready: boolean;
|
|
575
|
+
config: IManagedNodeConfig | null;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export interface IManagedNetworkAssignment {
|
|
579
|
+
schemaVersion: 1;
|
|
580
|
+
authorityId: string;
|
|
581
|
+
lifetimeId: string;
|
|
582
|
+
appliedRevision: number;
|
|
583
|
+
nodeId: string;
|
|
584
|
+
ownedPrefixes: string[];
|
|
585
|
+
/** Remote destinations only; never local workload prefixes or a default route. */
|
|
586
|
+
routes: string[];
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
export interface IManagedNetworkBinding {
|
|
590
|
+
authorityId: string;
|
|
591
|
+
nodeId: string;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
export interface IManagedNodeConfig {
|
|
595
|
+
/** Caller-owned control address with /32; local workload prefixes are not hub routes. */
|
|
596
|
+
address: string;
|
|
597
|
+
gateway: string;
|
|
598
|
+
ownedPrefixes: IManagedNetworkPrefix[];
|
|
599
|
+
outgoingRoutes: string[];
|
|
600
|
+
incomingSources: string[];
|
|
601
|
+
mtu: number;
|
|
602
|
+
wireguard: IManagedWireGuardProjection | null;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
export interface IManagedWireGuardProjection {
|
|
606
|
+
publicKey: string;
|
|
607
|
+
serverPublicKey: string;
|
|
608
|
+
endpoint: string;
|
|
609
|
+
/** Union of remote outgoing/incoming prefixes plus hub MTU-feedback gateway /32.
|
|
610
|
+
* The hub still enforces directed grants. Never includes local workload prefixes. */
|
|
611
|
+
allowedIps: string[];
|
|
612
|
+
}
|
|
613
|
+
|
|
475
614
|
// ============================================================================
|
|
476
615
|
// Installer
|
|
477
616
|
// ============================================================================
|
package/ts/smartvpn.paths.ts
CHANGED
|
@@ -4,3 +4,22 @@ export const packageDir = plugins.path.join(
|
|
|
4
4
|
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
|
|
5
5
|
'../',
|
|
6
6
|
);
|
|
7
|
+
|
|
8
|
+
/** Select only an explicitly requested binary or this package's Linux musl artifact. */
|
|
9
|
+
export function getBinaryPath(
|
|
10
|
+
binaryName: string,
|
|
11
|
+
platform: NodeJS.Platform = process.platform,
|
|
12
|
+
arch: string = process.arch,
|
|
13
|
+
override: string | undefined = process.env.SMARTVPN_RUST_BINARY,
|
|
14
|
+
): string {
|
|
15
|
+
// Smartrust validates explicit paths, including empty/invalid overrides, without
|
|
16
|
+
// repairing their permissions or falling through to an unrelated executable.
|
|
17
|
+
if (override !== undefined) {
|
|
18
|
+
return override;
|
|
19
|
+
}
|
|
20
|
+
if (platform !== 'linux' || (arch !== 'x64' && arch !== 'arm64')) {
|
|
21
|
+
throw new Error(`SmartVPN does not bundle a daemon for ${platform}/${arch}; set SMARTVPN_RUST_BINARY to an explicitly built executable or use socket transport.`);
|
|
22
|
+
}
|
|
23
|
+
const suffix = arch === 'x64' ? 'linux_amd64_musl' : 'linux_arm64_musl';
|
|
24
|
+
return plugins.path.join(packageDir, 'dist_rust', `${binaryName}_${suffix}`);
|
|
25
|
+
}
|