feat(server): add bridge forwarding mode and per-client destination policy overrides
This commit is contained in:
41
readme.md
41
readme.md
@@ -9,7 +9,8 @@ A high-performance VPN solution with a **TypeScript control plane** and a **Rust
|
||||
📊 **Per-transport metrics**: active clients and total connections broken down by websocket, QUIC, and WireGuard
|
||||
🔄 **Hub API**: one `createClient()` call generates keys, assigns IP, returns both SmartVPN + WireGuard configs
|
||||
📡 **Real-time telemetry**: RTT, jitter, loss ratio, link health — all via typed APIs
|
||||
🌐 **Unified forwarding pipeline**: all transports share the same engine — TUN (kernel), userspace NAT (no root), or testing mode
|
||||
🌐 **Unified forwarding pipeline**: all transports share the same engine — TUN (kernel), userspace NAT (no root), L2 bridge, or testing mode
|
||||
🏠 **Bridge mode**: VPN clients get IPs from your LAN subnet — seamlessly bridge remote clients onto a physical network
|
||||
🎯 **Destination routing policy**: force-target, block, or allow traffic per destination with nftables integration
|
||||
⚡ **Handshake-driven WireGuard state**: peers appear as "connected" only after a successful WireGuard handshake, and auto-disconnect on idle timeout
|
||||
|
||||
@@ -84,7 +85,7 @@ await server.start({
|
||||
publicKey: '<server-noise-public-key-base64>',
|
||||
subnet: '10.8.0.0/24',
|
||||
transportMode: 'all', // WebSocket + QUIC + WireGuard simultaneously (default)
|
||||
forwardingMode: 'tun', // 'tun' (kernel), 'socket' (userspace NAT), or 'testing'
|
||||
forwardingMode: 'tun', // 'tun' | 'socket' | 'bridge' | 'testing'
|
||||
wgPrivateKey: '<server-wg-private-key-base64>', // required for WireGuard transport
|
||||
enableNat: true,
|
||||
dns: ['1.1.1.1', '8.8.8.8'],
|
||||
@@ -237,6 +238,21 @@ In **TUN mode**, destination policies are enforced via **nftables** rules (using
|
||||
|
||||
In **socket mode**, the policy is evaluated in the userspace NAT engine before per-client ACLs.
|
||||
|
||||
**Per-client override** — individual clients can have their own destination policy that overrides the server-level default:
|
||||
|
||||
```typescript
|
||||
await server.createClient({
|
||||
clientId: 'restricted-client',
|
||||
security: {
|
||||
destinationPolicy: {
|
||||
default: 'block', // block everything by default
|
||||
allowList: ['10.0.0.0/8'], // except internal network
|
||||
},
|
||||
// ... other security settings
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 🔗 Socket Forward Proxy Protocol
|
||||
|
||||
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({
|
||||
|
||||
### 📦 Packet Forwarding Modes
|
||||
|
||||
SmartVPN supports three forwarding modes, configurable per-server and per-client:
|
||||
SmartVPN supports four forwarding modes, configurable per-server and per-client:
|
||||
|
||||
| Mode | Flag | Description | Root Required |
|
||||
|------|------|-------------|---------------|
|
||||
| **TUN** | `'tun'` | Kernel TUN device — real packet forwarding with system routing | ✅ Yes |
|
||||
| **Userspace NAT** | `'socket'` | Userspace TCP/UDP proxy via `connect(2)` — no TUN, no root needed | ❌ No |
|
||||
| **Bridge** | `'bridge'` | L2 bridge — VPN clients get IPs from a physical LAN subnet | ✅ Yes |
|
||||
| **Testing** | `'testing'` | Monitoring only — packets are counted but not forwarded | ❌ No |
|
||||
|
||||
```typescript
|
||||
@@ -267,6 +284,16 @@ await server.start({
|
||||
enableNat: true,
|
||||
});
|
||||
|
||||
// Server with bridge mode — VPN clients appear on the LAN
|
||||
await server.start({
|
||||
// ...
|
||||
forwardingMode: 'bridge',
|
||||
bridgeLanSubnet: '192.168.1.0/24', // LAN subnet to bridge into
|
||||
bridgePhysicalInterface: 'eth0', // auto-detected if omitted
|
||||
bridgeIpRangeStart: 200, // clients get .200–.250 (defaults)
|
||||
bridgeIpRangeEnd: 250,
|
||||
});
|
||||
|
||||
// Client with TUN device
|
||||
const { assignedIp } = await client.connect({
|
||||
// ...
|
||||
@@ -274,7 +301,9 @@ const { assignedIp } = await client.connect({
|
||||
});
|
||||
```
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
### 📊 Telemetry & QoS
|
||||
|
||||
@@ -444,10 +473,10 @@ server.on('reconnected', () => { /* socket transport reconnected */ });
|
||||
|
||||
| Interface | Purpose |
|
||||
|-----------|---------|
|
||||
| `IVpnServerConfig` | Server configuration (listen addr, keys, subnet, transport mode, forwarding mode, clients, proxy protocol, destination policy) |
|
||||
| `IVpnServerConfig` | Server configuration (listen addr, keys, subnet, transport mode, forwarding mode incl. bridge, clients, proxy protocol, destination policy) |
|
||||
| `IVpnClientConfig` | Client configuration (server URL, keys, transport, forwarding mode, WG options, client-defined tags) |
|
||||
| `IClientEntry` | Server-side client definition (ID, keys, security, priority, server/client tags, expiry) |
|
||||
| `IClientSecurity` | Per-client ACLs and rate limits (SmartProxy-aligned naming) |
|
||||
| `IClientSecurity` | Per-client ACLs, rate limits, and destination policy override (SmartProxy-aligned naming) |
|
||||
| `IClientRateLimit` | Rate limiting config (bytesPerSec, burstBytes) |
|
||||
| `IClientConfigBundle` | Full config bundle returned by `createClient()` — includes SmartVPN config, WireGuard .conf, and secrets |
|
||||
| `IVpnClientInfo` | Connected client info (IP, stats, authenticated key, remote addr, transport type) |
|
||||
|
||||
Reference in New Issue
Block a user