442 lines
17 KiB
TypeScript
442 lines
17 KiB
TypeScript
// ============================================================================
|
|
// Transport options
|
|
// ============================================================================
|
|
|
|
export interface IVpnTransportStdio {
|
|
transport: 'stdio';
|
|
}
|
|
|
|
export interface IVpnTransportSocket {
|
|
transport: 'socket';
|
|
socketPath: string;
|
|
autoReconnect?: boolean;
|
|
reconnectBaseDelayMs?: number;
|
|
reconnectMaxDelayMs?: number;
|
|
maxReconnectAttempts?: number;
|
|
}
|
|
|
|
export type TVpnTransportOptions = IVpnTransportStdio | IVpnTransportSocket;
|
|
|
|
// ============================================================================
|
|
// Client configuration
|
|
// ============================================================================
|
|
|
|
export interface IVpnClientConfig {
|
|
/** Server WebSocket URL, e.g. wss://vpn.example.com/tunnel */
|
|
serverUrl: string;
|
|
/** Server's static public key (base64) for Noise IK handshake */
|
|
serverPublicKey: string;
|
|
/** Client's Noise IK private key (base64) — required for SmartVPN native transport */
|
|
clientPrivateKey: string;
|
|
/** Client's Noise IK public key (base64) — for reference/display */
|
|
clientPublicKey: string;
|
|
/** Optional DNS servers to use while connected */
|
|
dns?: string[];
|
|
/** Optional MTU for the TUN device */
|
|
mtu?: number;
|
|
/** Keepalive interval in seconds (default: 30) */
|
|
keepaliveIntervalSecs?: number;
|
|
/** Transport protocol: 'auto' (default, tries QUIC then WS), 'websocket', 'quic', or 'wireguard' */
|
|
transport?: 'auto' | 'websocket' | 'quic' | 'wireguard';
|
|
/** For QUIC: SHA-256 hash of server certificate (base64) for cert pinning */
|
|
serverCertHash?: string;
|
|
/** Forwarding mode: 'tun' (TUN device, requires root) or 'testing' (no TUN).
|
|
* Default: 'testing'. */
|
|
forwardingMode?: 'tun' | 'testing';
|
|
/** WireGuard: client private key (base64, X25519) */
|
|
wgPrivateKey?: string;
|
|
/** WireGuard: client TUN address (e.g. 10.8.0.2) */
|
|
wgAddress?: string;
|
|
/** WireGuard: client TUN address prefix length (default: 24) */
|
|
wgAddressPrefix?: number;
|
|
/** WireGuard: preshared key (base64, optional) */
|
|
wgPresharedKey?: string;
|
|
/** WireGuard: persistent keepalive interval in seconds */
|
|
wgPersistentKeepalive?: number;
|
|
/** WireGuard: server endpoint (host:port, e.g. vpn.example.com:51820) */
|
|
wgEndpoint?: string;
|
|
/** WireGuard: allowed IPs (CIDR strings, e.g. ['0.0.0.0/0']) */
|
|
wgAllowedIps?: string[];
|
|
/** Client-defined tags reported to the server after connection (informational, not for access control) */
|
|
clientDefinedClientTags?: string[];
|
|
}
|
|
|
|
export interface IVpnClientOptions {
|
|
transport: TVpnTransportOptions;
|
|
config?: IVpnClientConfig;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Server configuration
|
|
// ============================================================================
|
|
|
|
export interface IVpnServerConfig {
|
|
/** Listen address for WebSocket, e.g. 0.0.0.0:443 */
|
|
listenAddr: string;
|
|
/** TLS certificate PEM (optional — can be behind reverse proxy) */
|
|
tlsCert?: string;
|
|
/** TLS private key PEM */
|
|
tlsKey?: string;
|
|
/** Server's Noise static private key (base64) */
|
|
privateKey: string;
|
|
/** Server's Noise static public key (base64) */
|
|
publicKey: string;
|
|
/** IP subnet for VPN clients, e.g. 10.8.0.0/24 */
|
|
subnet: string;
|
|
/** DNS servers pushed to clients */
|
|
dns?: string[];
|
|
/** MTU for TUN device */
|
|
mtu?: number;
|
|
/** Keepalive interval in seconds (default: 30) */
|
|
keepaliveIntervalSecs?: number;
|
|
/** Enable NAT/masquerade for client traffic */
|
|
enableNat?: boolean;
|
|
/** Forwarding mode: 'tun' (kernel TUN, requires root), 'socket' (userspace NAT),
|
|
* or 'testing' (monitoring only). Default: 'testing'. */
|
|
forwardingMode?: 'tun' | 'socket' | 'testing';
|
|
/** Default rate limit for new clients (bytes/sec). Omit for unlimited. */
|
|
defaultRateLimitBytesPerSec?: number;
|
|
/** Default burst size for new clients (bytes). Omit for unlimited. */
|
|
defaultBurstBytes?: number;
|
|
/** Transport mode: 'all' (default, WS+QUIC+WG if configured), 'both' (WS+QUIC),
|
|
* 'websocket', 'quic', or 'wireguard' */
|
|
transportMode?: 'websocket' | 'quic' | 'both' | 'all' | 'wireguard';
|
|
/** QUIC listen address (host:port). Defaults to listenAddr. */
|
|
quicListenAddr?: string;
|
|
/** QUIC idle timeout in seconds (default: 30) */
|
|
quicIdleTimeoutSecs?: number;
|
|
/** WireGuard: server X25519 private key (base64). Required when transport includes WG. */
|
|
wgPrivateKey?: string;
|
|
/** WireGuard: UDP listen port (default: 51820) */
|
|
wgListenPort?: number;
|
|
/** WireGuard: configured peers */
|
|
wgPeers?: IWgPeerConfig[];
|
|
/** Pre-registered clients for Noise IK authentication */
|
|
clients?: IClientEntry[];
|
|
/** Enable PROXY protocol v2 on incoming WebSocket connections.
|
|
* Required when behind a reverse proxy that sends PP v2 headers (HAProxy, SmartProxy).
|
|
* SECURITY: Must be false when accepting direct client connections. */
|
|
proxyProtocol?: boolean;
|
|
/** Server-level IP block list — applied at TCP accept, before Noise handshake.
|
|
* Supports exact IPs, CIDR, wildcards, ranges. */
|
|
connectionIpBlockList?: string[];
|
|
/** When true and forwardingMode is 'socket', the userspace NAT engine prepends
|
|
* PROXY protocol v2 headers on outbound TCP connections, conveying the VPN client's
|
|
* tunnel IP as the source address. This allows downstream services (e.g. SmartProxy)
|
|
* to see the real VPN client identity instead of 127.0.0.1. */
|
|
socketForwardProxyProtocol?: boolean;
|
|
/** Destination routing policy for VPN client traffic (socket mode).
|
|
* Controls where decrypted traffic goes: allow through, block, or redirect to a target.
|
|
* Default: all traffic passes through (backward compatible). */
|
|
destinationPolicy?: IDestinationPolicy;
|
|
}
|
|
|
|
/**
|
|
* Destination routing policy for VPN client traffic.
|
|
* Evaluated per-packet in the NAT engine before per-client ACLs.
|
|
*/
|
|
export interface IDestinationPolicy {
|
|
/** Default action for traffic not matching allow/block lists */
|
|
default: 'forceTarget' | 'block' | 'allow';
|
|
/** Target IP address for 'forceTarget' mode (e.g. '127.0.0.1'). Required when default is 'forceTarget'. */
|
|
target?: string;
|
|
/** Destinations that pass through directly — not rewritten, not blocked.
|
|
* Supports: exact IP, CIDR, wildcards (192.168.190.*), ranges. */
|
|
allowList?: string[];
|
|
/** Destinations that are always blocked. Overrides allowList (deny wins).
|
|
* Supports: exact IP, CIDR, wildcards, ranges. */
|
|
blockList?: string[];
|
|
}
|
|
|
|
export interface IVpnServerOptions {
|
|
transport: TVpnTransportOptions;
|
|
config?: IVpnServerConfig;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Status and statistics
|
|
// ============================================================================
|
|
|
|
export type TVpnConnectionState =
|
|
| 'disconnected'
|
|
| 'connecting'
|
|
| 'handshaking'
|
|
| 'connected'
|
|
| 'reconnecting'
|
|
| 'error';
|
|
|
|
export interface IVpnStatus {
|
|
state: TVpnConnectionState;
|
|
assignedIp?: string;
|
|
serverAddr?: string;
|
|
connectedSince?: string;
|
|
lastError?: string;
|
|
}
|
|
|
|
export interface IVpnStatistics {
|
|
bytesSent: number;
|
|
bytesReceived: number;
|
|
packetsSent: number;
|
|
packetsReceived: number;
|
|
keepalivesSent: number;
|
|
keepalivesReceived: number;
|
|
uptimeSeconds: number;
|
|
quality?: IVpnConnectionQuality;
|
|
}
|
|
|
|
export interface IVpnClientInfo {
|
|
clientId: string;
|
|
assignedIp: string;
|
|
connectedSince: string;
|
|
bytesSent: number;
|
|
bytesReceived: number;
|
|
packetsDropped: number;
|
|
bytesDropped: number;
|
|
lastKeepaliveAt?: string;
|
|
keepalivesReceived: number;
|
|
rateLimitBytesPerSec?: number;
|
|
burstBytes?: number;
|
|
/** Client's authenticated Noise IK public key (base64) */
|
|
authenticatedKey: string;
|
|
/** Registered client ID from the client registry */
|
|
registeredClientId: string;
|
|
/** Real client IP:port (from PROXY protocol or direct TCP connection) */
|
|
remoteAddr?: string;
|
|
/** Transport used: "websocket", "quic", or "wireguard" */
|
|
transportType: string;
|
|
}
|
|
|
|
export interface IVpnServerStatistics extends IVpnStatistics {
|
|
activeClients: number;
|
|
totalConnections: number;
|
|
}
|
|
|
|
export interface IVpnKeypair {
|
|
publicKey: string;
|
|
privateKey: string;
|
|
}
|
|
|
|
// ============================================================================
|
|
// QoS: Connection quality
|
|
// ============================================================================
|
|
|
|
export type TVpnLinkHealth = 'healthy' | 'degraded' | 'critical';
|
|
|
|
export interface IVpnConnectionQuality {
|
|
srttMs: number;
|
|
jitterMs: number;
|
|
minRttMs: number;
|
|
maxRttMs: number;
|
|
lossRatio: number;
|
|
consecutiveTimeouts: number;
|
|
linkHealth: TVpnLinkHealth;
|
|
currentKeepaliveIntervalSecs: number;
|
|
}
|
|
|
|
// ============================================================================
|
|
// QoS: MTU info
|
|
// ============================================================================
|
|
|
|
export interface IVpnMtuInfo {
|
|
tunMtu: number;
|
|
effectiveMtu: number;
|
|
linkMtu: number;
|
|
overheadBytes: number;
|
|
oversizedPacketsDropped: number;
|
|
icmpTooBigSent: number;
|
|
}
|
|
|
|
// ============================================================================
|
|
// QoS: Client telemetry (server-side per-client)
|
|
// ============================================================================
|
|
|
|
export interface IVpnClientTelemetry {
|
|
clientId: string;
|
|
assignedIp: string;
|
|
lastKeepaliveAt?: string;
|
|
keepalivesReceived: number;
|
|
packetsDropped: number;
|
|
bytesDropped: number;
|
|
bytesReceived: number;
|
|
bytesSent: number;
|
|
rateLimitBytesPerSec?: number;
|
|
burstBytes?: number;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Client Registry (Hub) types — aligned with SmartProxy IRouteSecurity pattern
|
|
// ============================================================================
|
|
|
|
/** Per-client rate limiting. */
|
|
export interface IClientRateLimit {
|
|
/** Max throughput in bytes/sec */
|
|
bytesPerSec: number;
|
|
/** Burst allowance in bytes */
|
|
burstBytes: number;
|
|
}
|
|
|
|
/**
|
|
* Per-client security settings.
|
|
* Mirrors SmartProxy's IRouteSecurity: ipAllowList/ipBlockList naming + deny-overrides-allow.
|
|
* Adds VPN-specific destination filtering.
|
|
*/
|
|
export interface IClientSecurity {
|
|
/** Source IPs/CIDRs the client may connect FROM (empty = any).
|
|
* Supports: exact IP, CIDR, wildcard (192.168.1.*), ranges (1.1.1.1-1.1.1.5). */
|
|
ipAllowList?: string[];
|
|
/** Source IPs blocked — overrides ipAllowList (deny wins). */
|
|
ipBlockList?: string[];
|
|
/** Destination IPs/CIDRs the client may reach through the VPN (empty = all). */
|
|
destinationAllowList?: string[];
|
|
/** Destination IPs blocked — overrides destinationAllowList (deny wins). */
|
|
destinationBlockList?: string[];
|
|
/** Max concurrent connections from this client. */
|
|
maxConnections?: number;
|
|
/** Per-client rate limiting. */
|
|
rateLimit?: IClientRateLimit;
|
|
}
|
|
|
|
/**
|
|
* Server-side client definition — the central config object for the Hub.
|
|
* Naming and structure aligned with SmartProxy's IRouteConfig / IRouteSecurity.
|
|
*/
|
|
export interface IClientEntry {
|
|
/** Human-readable client ID (e.g. "alice-laptop") */
|
|
clientId: string;
|
|
/** Client's Noise IK public key (base64) — for SmartVPN native transport */
|
|
publicKey: string;
|
|
/** Client's WireGuard public key (base64) — for WireGuard transport */
|
|
wgPublicKey?: string;
|
|
/** Security settings (ACLs, rate limits) */
|
|
security?: IClientSecurity;
|
|
/** Traffic priority (lower = higher priority, default: 100) */
|
|
priority?: number;
|
|
/** Whether this client is enabled (default: true) */
|
|
enabled?: boolean;
|
|
/** Tags assigned by the server admin — trusted, used for access control (e.g. ["engineering", "office"]) */
|
|
serverDefinedClientTags?: string[];
|
|
/** Tags reported by the connecting client — informational only, never used for access control */
|
|
clientDefinedClientTags?: string[];
|
|
/** @deprecated Use serverDefinedClientTags instead. Legacy field kept for backward compatibility. */
|
|
tags?: string[];
|
|
/** Optional description */
|
|
description?: string;
|
|
/** Optional expiry (ISO 8601 timestamp, omit = never expires) */
|
|
expiresAt?: string;
|
|
/** Assigned VPN IP address (set by server) */
|
|
assignedIp?: string;
|
|
}
|
|
|
|
/**
|
|
* Complete client config bundle — returned by createClient() and rotateClientKey().
|
|
* Contains everything the client needs to connect.
|
|
*/
|
|
export interface IClientConfigBundle {
|
|
/** The server-side client entry */
|
|
entry: IClientEntry;
|
|
/** Ready-to-use SmartVPN client config (typed object) */
|
|
smartvpnConfig: IVpnClientConfig;
|
|
/** Ready-to-use WireGuard .conf file content (string) */
|
|
wireguardConfig: string;
|
|
/** Client's private keys (ONLY returned at creation time, not stored server-side) */
|
|
secrets: {
|
|
noisePrivateKey: string;
|
|
wgPrivateKey: string;
|
|
};
|
|
}
|
|
|
|
// ============================================================================
|
|
// WireGuard-specific types
|
|
// ============================================================================
|
|
|
|
export interface IWgPeerConfig {
|
|
/** Peer's public key (base64, X25519) */
|
|
publicKey: string;
|
|
/** Optional preshared key (base64) */
|
|
presharedKey?: string;
|
|
/** Allowed IP ranges (CIDR strings) */
|
|
allowedIps: string[];
|
|
/** Peer endpoint (host:port) — optional for server peers, required for client */
|
|
endpoint?: string;
|
|
/** Persistent keepalive interval in seconds */
|
|
persistentKeepalive?: number;
|
|
}
|
|
|
|
export interface IWgPeerInfo {
|
|
publicKey: string;
|
|
allowedIps: string[];
|
|
endpoint?: string;
|
|
persistentKeepalive?: number;
|
|
bytesSent: number;
|
|
bytesReceived: number;
|
|
packetsSent: number;
|
|
packetsReceived: number;
|
|
lastHandshakeTime?: string;
|
|
}
|
|
|
|
// ============================================================================
|
|
// IPC Command maps (used by smartrust RustBridge<TCommands>)
|
|
// ============================================================================
|
|
|
|
export type TVpnClientCommands = {
|
|
connect: { params: { config: IVpnClientConfig }; result: { assignedIp: string } };
|
|
disconnect: { params: Record<string, never>; result: void };
|
|
getStatus: { params: Record<string, never>; result: IVpnStatus };
|
|
getStatistics: { params: Record<string, never>; result: IVpnStatistics };
|
|
getConnectionQuality: { params: Record<string, never>; result: IVpnConnectionQuality };
|
|
getMtuInfo: { params: Record<string, never>; result: IVpnMtuInfo };
|
|
};
|
|
|
|
export type TVpnServerCommands = {
|
|
start: { params: { config: IVpnServerConfig }; result: void };
|
|
stop: { params: Record<string, never>; result: void };
|
|
getStatus: { params: Record<string, never>; result: IVpnStatus };
|
|
getStatistics: { params: Record<string, never>; result: IVpnServerStatistics };
|
|
listClients: { params: Record<string, never>; result: { clients: IVpnClientInfo[] } };
|
|
disconnectClient: { params: { clientId: string }; result: void };
|
|
generateKeypair: { params: Record<string, never>; result: IVpnKeypair };
|
|
setClientRateLimit: { params: { clientId: string; rateBytesPerSec: number; burstBytes: number }; result: void };
|
|
removeClientRateLimit: { params: { clientId: string }; result: void };
|
|
getClientTelemetry: { params: { clientId: string }; result: IVpnClientTelemetry };
|
|
generateWgKeypair: { params: Record<string, never>; result: IVpnKeypair };
|
|
addWgPeer: { params: { peer: IWgPeerConfig }; result: void };
|
|
removeWgPeer: { params: { publicKey: string }; result: void };
|
|
listWgPeers: { params: Record<string, never>; result: { peers: IWgPeerInfo[] } };
|
|
// Client Registry (Hub) commands
|
|
createClient: { params: { client: Partial<IClientEntry> }; result: IClientConfigBundle };
|
|
removeClient: { params: { clientId: string }; result: void };
|
|
getClient: { params: { clientId: string }; result: IClientEntry };
|
|
listRegisteredClients: { params: Record<string, never>; result: { clients: IClientEntry[] } };
|
|
updateClient: { params: { clientId: string; update: Partial<IClientEntry> }; result: void };
|
|
enableClient: { params: { clientId: string }; result: void };
|
|
disableClient: { params: { clientId: string }; result: void };
|
|
rotateClientKey: { params: { clientId: string }; result: IClientConfigBundle };
|
|
exportClientConfig: { params: { clientId: string; format: 'smartvpn' | 'wireguard' }; result: { config: string } };
|
|
generateClientKeypair: { params: Record<string, never>; result: IVpnKeypair };
|
|
};
|
|
|
|
// ============================================================================
|
|
// Installer
|
|
// ============================================================================
|
|
|
|
export type TVpnPlatform = 'linux' | 'macos' | 'windows' | 'unknown';
|
|
|
|
export interface IVpnServiceUnit {
|
|
platform: TVpnPlatform;
|
|
content: string;
|
|
installPath: string;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Events emitted by VpnClient / VpnServer
|
|
// ============================================================================
|
|
|
|
export interface IVpnEventMap {
|
|
'status': IVpnStatus;
|
|
'error': { message: string; code?: string };
|
|
'client-connected': IVpnClientInfo;
|
|
'client-disconnected': { clientId: string; reason?: string };
|
|
'exit': { code: number | null; signal: string | null };
|
|
'reconnected': void;
|
|
}
|