@push.rocks/smartvpn 1.17.0 → 1.18.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.
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartvpn',
6
- version: '1.17.0',
6
+ version: '1.18.0',
7
7
  description: 'A VPN solution with TypeScript control plane and Rust data plane daemon'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLFFBQVE7SUFDakIsV0FBVyxFQUFFLHlFQUF5RTtDQUN2RixDQUFBIn0=
@@ -76,7 +76,7 @@ export interface IVpnServerConfig {
76
76
  enableNat?: boolean;
77
77
  /** Forwarding mode: 'tun' (kernel TUN, requires root), 'socket' (userspace NAT),
78
78
  * or 'testing' (monitoring only). Default: 'testing'. */
79
- forwardingMode?: 'tun' | 'socket' | 'testing';
79
+ forwardingMode?: 'tun' | 'socket' | 'bridge' | 'testing';
80
80
  /** Default rate limit for new clients (bytes/sec). Omit for unlimited. */
81
81
  defaultRateLimitBytesPerSec?: number;
82
82
  /** Default burst size for new clients (bytes). Omit for unlimited. */
@@ -120,6 +120,19 @@ export interface IVpnServerConfig {
120
120
  * Controls what traffic the client routes through the VPN tunnel.
121
121
  * Defaults to ['0.0.0.0/0'] (full tunnel). Set to e.g. ['10.8.0.0/24'] for split tunnel. */
122
122
  clientAllowedIPs?: string[];
123
+ /** LAN subnet CIDR for bridge mode (e.g. '192.168.1.0/24').
124
+ * VPN clients get IPs from this subnet instead of the VPN subnet.
125
+ * Required when forwardingMode is 'bridge'. */
126
+ bridgeLanSubnet?: string;
127
+ /** Physical network interface to bridge (e.g. 'eth0').
128
+ * Auto-detected from the default route if omitted. */
129
+ bridgePhysicalInterface?: string;
130
+ /** Start of VPN client IP range within the LAN subnet (host offset, e.g. 200 for .200).
131
+ * Default: 200. */
132
+ bridgeIpRangeStart?: number;
133
+ /** End of VPN client IP range within the LAN subnet (host offset, e.g. 250 for .250).
134
+ * Default: 250. */
135
+ bridgeIpRangeEnd?: number;
123
136
  }
124
137
  /**
125
138
  * Destination routing policy for VPN client traffic.
@@ -253,6 +266,10 @@ export interface IClientSecurity {
253
266
  maxConnections?: number;
254
267
  /** Per-client rate limiting. */
255
268
  rateLimit?: IClientRateLimit;
269
+ /** Per-client destination routing policy override.
270
+ * When set, overrides the server-level destinationPolicy for this client's traffic.
271
+ * Supports the same options: forceTarget, block, allow with allow/block lists. */
272
+ destinationPolicy?: IDestinationPolicy;
256
273
  }
257
274
  /**
258
275
  * Server-side client definition — the central config object for the Hub.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartvpn",
3
- "version": "1.17.0",
3
+ "version": "1.18.0",
4
4
  "private": false,
5
5
  "description": "A VPN solution with TypeScript control plane and Rust data plane daemon",
6
6
  "type": "module",
package/readme.md CHANGED
@@ -9,7 +9,8 @@ A high-performance VPN solution with a **TypeScript control plane** and a **Rust
9
9
  📊 **Per-transport metrics**: active clients and total connections broken down by websocket, QUIC, and WireGuard
10
10
  🔄 **Hub API**: one `createClient()` call generates keys, assigns IP, returns both SmartVPN + WireGuard configs
11
11
  📡 **Real-time telemetry**: RTT, jitter, loss ratio, link health — all via typed APIs
12
- 🌐 **Unified forwarding pipeline**: all transports share the same engine — TUN (kernel), userspace NAT (no root), or testing mode
12
+ 🌐 **Unified forwarding pipeline**: all transports share the same engine — TUN (kernel), userspace NAT (no root), L2 bridge, or testing mode
13
+ 🏠 **Bridge mode**: VPN clients get IPs from your LAN subnet — seamlessly bridge remote clients onto a physical network
13
14
  🎯 **Destination routing policy**: force-target, block, or allow traffic per destination with nftables integration
14
15
  ⚡ **Handshake-driven WireGuard state**: peers appear as "connected" only after a successful WireGuard handshake, and auto-disconnect on idle timeout
15
16
 
@@ -84,7 +85,7 @@ await server.start({
84
85
  publicKey: '<server-noise-public-key-base64>',
85
86
  subnet: '10.8.0.0/24',
86
87
  transportMode: 'all', // WebSocket + QUIC + WireGuard simultaneously (default)
87
- forwardingMode: 'tun', // 'tun' (kernel), 'socket' (userspace NAT), or 'testing'
88
+ forwardingMode: 'tun', // 'tun' | 'socket' | 'bridge' | 'testing'
88
89
  wgPrivateKey: '<server-wg-private-key-base64>', // required for WireGuard transport
89
90
  enableNat: true,
90
91
  dns: ['1.1.1.1', '8.8.8.8'],
@@ -237,6 +238,21 @@ In **TUN mode**, destination policies are enforced via **nftables** rules (using
237
238
 
238
239
  In **socket mode**, the policy is evaluated in the userspace NAT engine before per-client ACLs.
239
240
 
241
+ **Per-client override** — individual clients can have their own destination policy that overrides the server-level default:
242
+
243
+ ```typescript
244
+ await server.createClient({
245
+ clientId: 'restricted-client',
246
+ security: {
247
+ destinationPolicy: {
248
+ default: 'block', // block everything by default
249
+ allowList: ['10.0.0.0/8'], // except internal network
250
+ },
251
+ // ... other security settings
252
+ },
253
+ });
254
+ ```
255
+
240
256
  ### 🔗 Socket Forward Proxy Protocol
241
257
 
242
258
  When using `forwardingMode: 'socket'` (userspace NAT), you can prepend **PROXY protocol v2 headers** on outbound TCP connections. This conveys the VPN client's tunnel IP as the source address to downstream services (e.g., SmartProxy):
@@ -251,12 +267,13 @@ await server.start({
251
267
 
252
268
  ### 📦 Packet Forwarding Modes
253
269
 
254
- SmartVPN supports three forwarding modes, configurable per-server and per-client:
270
+ SmartVPN supports four forwarding modes, configurable per-server and per-client:
255
271
 
256
272
  | Mode | Flag | Description | Root Required |
257
273
  |------|------|-------------|---------------|
258
274
  | **TUN** | `'tun'` | Kernel TUN device — real packet forwarding with system routing | ✅ Yes |
259
275
  | **Userspace NAT** | `'socket'` | Userspace TCP/UDP proxy via `connect(2)` — no TUN, no root needed | ❌ No |
276
+ | **Bridge** | `'bridge'` | L2 bridge — VPN clients get IPs from a physical LAN subnet | ✅ Yes |
260
277
  | **Testing** | `'testing'` | Monitoring only — packets are counted but not forwarded | ❌ No |
261
278
 
262
279
  ```typescript
@@ -267,6 +284,16 @@ await server.start({
267
284
  enableNat: true,
268
285
  });
269
286
 
287
+ // Server with bridge mode — VPN clients appear on the LAN
288
+ await server.start({
289
+ // ...
290
+ forwardingMode: 'bridge',
291
+ bridgeLanSubnet: '192.168.1.0/24', // LAN subnet to bridge into
292
+ bridgePhysicalInterface: 'eth0', // auto-detected if omitted
293
+ bridgeIpRangeStart: 200, // clients get .200–.250 (defaults)
294
+ bridgeIpRangeEnd: 250,
295
+ });
296
+
270
297
  // Client with TUN device
271
298
  const { assignedIp } = await client.connect({
272
299
  // ...
@@ -274,7 +301,9 @@ const { assignedIp } = await client.connect({
274
301
  });
275
302
  ```
276
303
 
277
- The userspace NAT mode extracts destination IP/port from IP packets, opens a real socket to the destination, and relays data — supporting both TCP streams and UDP datagrams without requiring `CAP_NET_ADMIN` or root privileges.
304
+ The **userspace NAT** mode extracts destination IP/port from IP packets, opens a real socket to the destination, and relays data — supporting both TCP streams and UDP datagrams without requiring `CAP_NET_ADMIN` or root privileges.
305
+
306
+ The **bridge** mode assigns VPN clients IPs from a real LAN subnet instead of a virtual VPN subnet. Clients appear as if they're directly on the physical network — perfect for remote access to home labs, office networks, or IoT devices.
278
307
 
279
308
  ### 📊 Telemetry & QoS
280
309
 
@@ -444,10 +473,10 @@ server.on('reconnected', () => { /* socket transport reconnected */ });
444
473
 
445
474
  | Interface | Purpose |
446
475
  |-----------|---------|
447
- | `IVpnServerConfig` | Server configuration (listen addr, keys, subnet, transport mode, forwarding mode, clients, proxy protocol, destination policy) |
476
+ | `IVpnServerConfig` | Server configuration (listen addr, keys, subnet, transport mode, forwarding mode incl. bridge, clients, proxy protocol, destination policy) |
448
477
  | `IVpnClientConfig` | Client configuration (server URL, keys, transport, forwarding mode, WG options, client-defined tags) |
449
478
  | `IClientEntry` | Server-side client definition (ID, keys, security, priority, server/client tags, expiry) |
450
- | `IClientSecurity` | Per-client ACLs and rate limits (SmartProxy-aligned naming) |
479
+ | `IClientSecurity` | Per-client ACLs, rate limits, and destination policy override (SmartProxy-aligned naming) |
451
480
  | `IClientRateLimit` | Rate limiting config (bytesPerSec, burstBytes) |
452
481
  | `IClientConfigBundle` | Full config bundle returned by `createClient()` — includes SmartVPN config, WireGuard .conf, and secrets |
453
482
  | `IVpnClientInfo` | Connected client info (IP, stats, authenticated key, remote addr, transport type) |
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartvpn',
6
- version: '1.17.0',
6
+ version: '1.18.0',
7
7
  description: 'A VPN solution with TypeScript control plane and Rust data plane daemon'
8
8
  }
@@ -93,7 +93,7 @@ export interface IVpnServerConfig {
93
93
  enableNat?: boolean;
94
94
  /** Forwarding mode: 'tun' (kernel TUN, requires root), 'socket' (userspace NAT),
95
95
  * or 'testing' (monitoring only). Default: 'testing'. */
96
- forwardingMode?: 'tun' | 'socket' | 'testing';
96
+ forwardingMode?: 'tun' | 'socket' | 'bridge' | 'testing';
97
97
  /** Default rate limit for new clients (bytes/sec). Omit for unlimited. */
98
98
  defaultRateLimitBytesPerSec?: number;
99
99
  /** Default burst size for new clients (bytes). Omit for unlimited. */
@@ -137,6 +137,22 @@ export interface IVpnServerConfig {
137
137
  * Controls what traffic the client routes through the VPN tunnel.
138
138
  * Defaults to ['0.0.0.0/0'] (full tunnel). Set to e.g. ['10.8.0.0/24'] for split tunnel. */
139
139
  clientAllowedIPs?: string[];
140
+
141
+ // Bridge mode configuration (forwardingMode: 'bridge')
142
+
143
+ /** LAN subnet CIDR for bridge mode (e.g. '192.168.1.0/24').
144
+ * VPN clients get IPs from this subnet instead of the VPN subnet.
145
+ * Required when forwardingMode is 'bridge'. */
146
+ bridgeLanSubnet?: string;
147
+ /** Physical network interface to bridge (e.g. 'eth0').
148
+ * Auto-detected from the default route if omitted. */
149
+ bridgePhysicalInterface?: string;
150
+ /** Start of VPN client IP range within the LAN subnet (host offset, e.g. 200 for .200).
151
+ * Default: 200. */
152
+ bridgeIpRangeStart?: number;
153
+ /** End of VPN client IP range within the LAN subnet (host offset, e.g. 250 for .250).
154
+ * Default: 250. */
155
+ bridgeIpRangeEnd?: number;
140
156
  }
141
157
 
142
158
  /**
@@ -310,6 +326,10 @@ export interface IClientSecurity {
310
326
  maxConnections?: number;
311
327
  /** Per-client rate limiting. */
312
328
  rateLimit?: IClientRateLimit;
329
+ /** Per-client destination routing policy override.
330
+ * When set, overrides the server-level destinationPolicy for this client's traffic.
331
+ * Supports the same options: forceTarget, block, allow with allow/block lists. */
332
+ destinationPolicy?: IDestinationPolicy;
313
333
  }
314
334
 
315
335
  /**