import * as plugins from '../plugins.js'; import { VpnClientDoc } from '../db/index.js'; export interface IVpnManagerConfig { /** VPN subnet CIDR (default: '10.8.0.0/24') */ subnet?: string; /** WireGuard UDP listen port (default: 51820) */ wgListenPort?: number; /** DNS servers pushed to VPN clients */ dns?: string[]; /** Server endpoint hostname for client configs (e.g. 'vpn.example.com') */ serverEndpoint?: string; /** Pre-defined VPN clients created on startup (idempotent — skips already-persisted clients) */ initialClients?: Array<{ clientId: string; targetProfileIds?: string[]; description?: string; }>; /** Called when clients are created/deleted/toggled — triggers route re-application */ onClientChanged?: () => void; /** Called when a live VPN client's real source IP changes. */ onClientSourceIpsChanged?: () => void; /** Poll interval for live VPN client real source IP updates. Default: 10 seconds. */ clientSourceIpPollIntervalMs?: number; /** Destination routing policy override. Default: forceTarget to 127.0.0.1 */ destinationPolicy?: { default: 'forceTarget' | 'block' | 'allow'; target?: string; allowList?: string[]; blockList?: string[]; }; /** Compute per-client AllowedIPs based on the client's target profile IDs. * Called at config generation time (create/export). Returns CIDRs for WireGuard AllowedIPs. * When not set, defaults to [subnet]. */ getClientAllowedIPs?: (targetProfileIds: string[], clientId?: string, sourceIp?: string) => Promise; /** Resolve per-client destination allow-list IPs from target profile IDs. * Returns IP strings that should bypass forceTarget and go direct to the real destination. */ getClientDirectTargets?: (targetProfileIds: string[]) => string[]; /** Forwarding mode: 'socket' (default, userspace NAT), 'bridge' (L2 bridge to host LAN), * or 'hybrid' (socket default, bridge for clients with useHostIp=true) */ forwardingMode?: 'socket' | 'bridge' | 'hybrid'; /** LAN subnet CIDR for bridge mode (e.g., '192.168.1.0/24') */ bridgeLanSubnet?: string; /** Physical network interface for bridge mode (auto-detected if omitted) */ bridgePhysicalInterface?: string; /** Start of VPN client IP range in LAN subnet (host offset, default: 200) */ bridgeIpRangeStart?: number; /** End of VPN client IP range in LAN subnet (host offset, default: 250) */ bridgeIpRangeEnd?: number; } /** * Manages the SmartVPN server lifecycle and VPN client CRUD. * Persists server keys and client registrations via smartdata document classes. */ export declare class VpnManager { private config; private vpnServer?; private clients; private serverKeys?; private resolvedForwardingMode?; private forwardingModeOverride?; private clientSourceIps; private clientSourceIpPollTimer?; private clientSourceIpRefreshInFlight; constructor(config: IVpnManagerConfig); /** The VPN subnet CIDR. */ getSubnet(): string; /** Whether the VPN server is running. */ get running(): boolean; /** * Start the VPN server. * Loads or generates server keys, loads persisted clients, starts VpnServer. */ start(): Promise; /** * Stop the VPN server. */ stop(): Promise; /** * Create a new VPN client. Returns the config bundle (secrets only shown once). */ createClient(opts: { clientId: string; targetProfileIds?: string[]; description?: string; destinationAllowList?: string[]; destinationBlockList?: string[]; useHostIp?: boolean; useDhcp?: boolean; staticIp?: string; forceVlan?: boolean; vlanId?: number; }): Promise; /** * Remove a VPN client. */ removeClient(clientId: string): Promise; /** * List all registered clients (without secrets). */ listClients(): VpnClientDoc[]; /** * Enable a client. */ enableClient(clientId: string): Promise; /** * Disable a client. */ disableClient(clientId: string): Promise; /** * Update a client's metadata (description, target profiles) without rotating keys. */ updateClient(clientId: string, update: { description?: string; targetProfileIds?: string[]; destinationAllowList?: string[]; destinationBlockList?: string[]; useHostIp?: boolean; useDhcp?: boolean; staticIp?: string; forceVlan?: boolean; vlanId?: number; }): Promise; /** * Rotate a client's keys. Returns the new config bundle. */ rotateClientKey(clientId: string): Promise; /** * Export a client config. Injects stored WG private key and per-client AllowedIPs. */ exportClientConfig(clientId: string, format: 'smartvpn' | 'wireguard'): Promise; /** * Get server status. */ getStatus(): Promise; /** * Get server statistics. */ getStatistics(): Promise; /** * List currently connected clients. */ getConnectedClients(): Promise; getClientSourceIp(clientId: string): string | undefined; getClientSourceIpMap(): Map; refreshClientSourceIps(notifyOnChange?: boolean): Promise; static normalizeRemoteAddress(remoteAddress?: string): string | undefined; /** * Get telemetry for a specific client. */ getClientTelemetry(clientId: string): Promise; /** * Get server public keys (for display/info). */ getServerPublicKeys(): { noisePublicKey: string; wgPublicKey: string; } | null; /** * Build per-client security settings for the smartvpn daemon. * TargetProfile direct IP:port targets extend the effective allow-list. */ private buildClientSecurity; /** * Refresh all client security policies against the running daemon. * Call this when TargetProfiles change so destination allow-lists stay in sync. */ refreshAllClientSecurity(): Promise; private getWireGuardServerEndpoint; private rewriteWireGuardAllowedIPs; private loadOrGenerateServerKeys; private loadPersistedClients; private startClientSourceIpPolling; private stopClientSourceIpPolling; private sameSourceIpMap; private getResolvedForwardingMode; private hasHostIpClients; private getDesiredForwardingMode; private getDefaultDestinationPolicy; private getServerDestinationPolicy; private getBaseDestinationPolicy; private mergeDestinationLists; private normalizeClientRoutingSettings; private buildClientRuntimeUpdate; private restartWithForwardingMode; private ensureForwardingModeForNextClient; private reconcileForwardingMode; private persistClient; }