UNPKG

wireguard-utils

Version:

A comprehensive TypeScript library for WireGuard utilities including key generation, IP management, config building, QR code generation, config parsing, validation, templates, routing, tunnel management, and security features using proper Curve25519 crypt

777 lines (584 loc) 21.5 kB
# WireGuard Utils A TypeScript library for WireGuard utilities including key generation, IP management, config building, and QR code generation using proper Curve25519 cryptography. ## Features ### Core Cryptography - ✅ **Secure**: Uses the industry-standard `@noble/curves` library for Curve25519 cryptography - ✅ **Compatible**: Generates keys compatible with official WireGuard implementations - ✅ **TypeScript**: Full TypeScript support with type definitions - ✅ **Deterministic**: Same private key always generates the same public key ### Configuration Management - ✅ **IP Management**: Generate IP addresses for different network classes and subnets - ✅ **Pre-shared Keys**: Generate quantum-resistant pre-shared keys - ✅ **Config Builder**: Build complete WireGuard configurations from structured data - ✅ **Config Parser**: Parse existing WireGuard configuration files - ✅ **Config Validation**: Validate configuration syntax and security - ✅ **Config Templates**: Pre-built templates for common setups ### Network & Routing - ✅ **DNS Helpers**: Predefined DNS configurations (Cloudflare, Google, Quad9, etc.) - ✅ **Port Management**: Find available ports and check port status - ✅ **Advanced Routing**: Split tunneling and custom routing configurations - ✅ **Network Detection**: Automatic network class detection from CIDR ### Security & Management - ✅ **Key Rotation**: Automated key rotation with migration planning - ✅ **QR Code Generation**: Generate QR codes for mobile WireGuard app import - ✅ **Tunnel Management**: Start, stop, and monitor WireGuard tunnels - ✅ **Security Validation**: Configuration security analysis and suggestions ### Quality Assurance - ✅ **Validated**: Comprehensive test suite ensuring cryptographic correctness - ✅ **Production Ready**: Enterprise-grade error handling and validation ## Installation ```bash npm install wireguard-utils ``` ## Quick Start ```typescript import { generateWireguardKeyPair, generateIPInClass, generatePreSharedKey, buildWireGuardConfig, generateQRCode } from 'wireguard-utils'; // Generate everything needed for a complete setup const serverKeys = generateWireguardKeyPair(); const clientKeys = generateWireguardKeyPair(); const psk = generatePreSharedKey(); const serverIP = generateIPInClass('10.0.0.0/24'); const clientIP = generateIPInClass('10.0.0.0/24'); // Build structured config const clientConfig = { interface: { privateKey: clientKeys.privateKey, address: [`${clientIP}/24`] }, peers: [{ publicKey: serverKeys.publicKey, allowedIPs: ['0.0.0.0/0'], endpoint: 'vpn.example.com:51820', preSharedKey: psk }] }; // Generate config file and QR code const configText = buildWireGuardConfig(clientConfig); const qrCode = await generateQRCode(configText); console.log('Config ready for mobile import!'); ``` ## API Reference ### Key Generation Functions ### `generateWireguardKeyPair(): WireGuardKeyPair` Generates a complete WireGuard key pair with a random private key. **Returns:** Object with `privateKey` and `publicKey` properties (both base64 encoded) ```typescript const keyPair = generateWireguardKeyPair(); // { // privateKey: "nPse/4zbQGxOqAM14icWRru4I6g9s9xdhg9sCY2l3ck=", // publicKey: "Y3AdHf4MAZi3xgCFxiDfyPBNbBQKuTqTCoDI/XHrnQg=" // } ``` ### `generatePrivateKey(): string` Generates a random WireGuard private key. **Returns:** Base64 encoded private key (32 bytes) ```typescript const privateKey = generatePrivateKey(); // "nPse/4zbQGxOqAM14icWRru4I6g9s9xdhg9sCY2l3ck=" ``` ### `derivePublicKey(privateKey: string): string` Derives a WireGuard public key from a private key using Curve25519. **Parameters:** - `privateKey` - Base64 encoded private key **Returns:** Base64 encoded public key **Throws:** Error if private key is invalid ```typescript const privateKey = "nPse/4zbQGxOqAM14icWRru4I6g9s9xdhg9sCY2l3ck="; const publicKey = derivePublicKey(privateKey); // "Y3AdHf4MAZi3xgCFxiDfyPBNbBQKuTqTCoDI/XHrnQg=" // Same private key always generates same public key const publicKey2 = derivePublicKey(privateKey); console.log(publicKey === publicKey2); // true ``` ### `validatePublicKey(publicKey: string): boolean` Validates a WireGuard public key format. **Parameters:** - `publicKey` - Base64 encoded public key to validate **Returns:** `true` if valid, `false` otherwise ```typescript const isValid = validatePublicKey("Y3AdHf4MAZi3xgCFxiDfyPBNbBQKuTqTCoDI/XHrnQg="); console.log(isValid); // true const isInvalid = validatePublicKey("invalid-key"); console.log(isInvalid); // false ``` ### IP Generation Functions The `generateIPInClass` function is overloaded to support multiple usage patterns: ### `generateIPInClass(networkClass: 'A' | 'B' | 'C'): string` ### `generateIPInClass(subnet: string): string` ### `generateIPInClass(networkClass: 'A' | 'B' | 'C', subnet: string): string` Generates a random IP address within the specified network class or subnet. The function automatically detects the network class from CIDR notation when provided. **Parameters:** - `networkClass` - The IP class ('A', 'B', or 'C') - optional when subnet is provided - `subnet` - Subnet in CIDR notation (e.g., '192.168.1.0/24') - automatically detects class **Returns:** Generated IP address as string **Throws:** Error if subnet format is invalid or network class conflicts ```typescript // Generate IP in Class C range const classC_IP = generateIPInClass('C'); // "192.168.45.123" // Generate IP in specific subnet (auto-detects Class C) const subnetIP = generateIPInClass('192.168.1.0/24'); // "192.168.1.42" // Generate IP in Class A range const classA_IP = generateIPInClass('A'); // "10.234.56.78" // Generate IP in Class A subnet (auto-detects) const classA_subnet = generateIPInClass('10.5.0.0/24'); // "10.5.0.15" // Legacy usage (both class and subnet - validates they match) const legacyIP = generateIPInClass('C', '192.168.1.0/24'); // "192.168.1.89" ``` ### Security Functions ### `generatePreSharedKey(): string` Generates a cryptographically secure pre-shared key for additional quantum resistance. **Returns:** Base64 encoded pre-shared key (32 bytes) **Security:** Provides additional protection against quantum computing attacks when used with WireGuard ```typescript const psk = generatePreSharedKey(); // "F7cNX6PRPgOhFrN9eQnXBgvMhXFT8lh16+d0uPqhrtU=" // Use in WireGuard config const config = { interface: { /* ... */ }, peers: [{ publicKey: peerPublicKey, allowedIPs: ['10.0.0.2/32'], preSharedKey: psk // Enhanced security }] }; ``` ### Configuration Builder Functions ### `buildWireGuardConfig(config: WireGuardConfig): string` Builds a complete WireGuard configuration file from structured TypeScript data. **Parameters:** - `config` - Structured WireGuard configuration object **Returns:** WireGuard configuration file as string **Benefits:** Type-safe configuration building with validation ```typescript const serverConfig: WireGuardConfig = { interface: { privateKey: serverKeys.privateKey, address: ['10.0.0.1/24'], listenPort: 51820, dns: ['1.1.1.1', '1.0.0.1'] }, peers: [ { publicKey: clientKeys.publicKey, allowedIPs: ['10.0.0.2/32'], preSharedKey: psk } ] }; const configText = buildWireGuardConfig(serverConfig); // Generates proper WireGuard config file format ``` ### QR Code Functions ### `generateQRCode(configText: string, options?: QROptions): Promise<string>` Generates a QR code for WireGuard configuration that mobile apps can scan to import. **Parameters:** - `configText` - WireGuard configuration as string - `options` - Optional QR code generation options **Returns:** Promise resolving to base64 encoded PNG image **Mobile Import:** WireGuard mobile apps can scan these QR codes for instant setup ```typescript // Generate QR code with default options const qrCode = await generateQRCode(configText); // Generate QR code with custom options const customQR = await generateQRCode(configText, { width: 512, errorCorrectionLevel: 'H', margin: 2 }); // Save or display the QR code const imgSrc = `data:image/png;base64,${qrCode}`; ``` ### Type Definitions ### `WireGuardKeyPair` Interface ```typescript interface WireGuardKeyPair { privateKey: string; // Base64 encoded private key (32 bytes) publicKey: string; // Base64 encoded public key (32 bytes) } ``` ### `WireGuardConfig` Interface ```typescript interface WireGuardConfig { interface: WireGuardInterface; peers: WireGuardPeer[]; } interface WireGuardInterface { privateKey: string; address: string[]; // Multiple addresses supported listenPort?: number; // Optional for clients dns?: string[]; // Optional DNS servers preSharedKey?: string; // Optional interface-level PSK } interface WireGuardPeer { publicKey: string; allowedIPs: string[]; // Multiple IP ranges supported endpoint?: string; // Optional for server configs preSharedKey?: string; // Optional quantum-resistant security persistentKeepalive?: number; // Optional keepalive interval } ``` ### QR Code Options ```typescript interface QROptions { errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H'; // Error correction level width?: number; // QR code width in pixels margin?: number; // Margin around QR code } ``` ## Usage Examples ### Basic Key Generation ```typescript import { generateWireguardKeyPair } from 'wireguard-utils'; const keyPair = generateWireguardKeyPair(); console.log(`Private: ${keyPair.privateKey}`); console.log(`Public: ${keyPair.publicKey}`); ``` ### Key Derivation ```typescript import { generatePrivateKey, derivePublicKey } from 'wireguard-utils'; // Generate private key const privateKey = generatePrivateKey(); // Derive public key (deterministic) const publicKey = derivePublicKey(privateKey); console.log('Key pair:', { privateKey, publicKey }); ``` ### IP Address Generation ```typescript import { generateIPInClass } from 'wireguard-utils'; // Generate IPs for different classes const classA_IP = generateIPInClass('A'); const classC_IP = generateIPInClass('C'); // Generate IPs in specific subnets (auto-detects class) const serverIP = generateIPInClass('10.0.0.0/24'); const clientIP = generateIPInClass('10.0.0.0/24'); console.log('Class A IP:', classA_IP); console.log('Class C IP:', classC_IP); console.log('Server IP:', serverIP); console.log('Client IP:', clientIP); ``` ### Key Validation ```typescript import { validatePublicKey, generateWireguardKeyPair } from 'wireguard-utils'; const keyPair = generateWireguardKeyPair(); if (validatePublicKey(keyPair.publicKey)) { console.log('✅ Valid WireGuard public key'); } else { console.log('❌ Invalid key format'); } ``` ### Pre-shared Key Generation ```typescript import { generatePreSharedKey, generateWireguardKeyPair } from 'wireguard-utils'; // Generate quantum-resistant pre-shared key const psk = generatePreSharedKey(); console.log('Pre-shared key:', psk); // Enhanced security setup const serverKeys = generateWireguardKeyPair(); const clientKeys = generateWireguardKeyPair(); // PSK adds quantum resistance to the connection ``` ### Complete WireGuard Setup with All Features ```typescript import { generateWireguardKeyPair, generateIPInClass, generatePreSharedKey, buildWireGuardConfig, generateQRCode, WireGuardConfig } from 'wireguard-utils'; async function createCompleteWireGuardSetup() { // Generate all cryptographic material const serverKeys = generateWireguardKeyPair(); const clientKeys = generateWireguardKeyPair(); const psk = generatePreSharedKey(); // Quantum-resistant security // Generate IP addresses (auto-detects Class A from CIDR) const serverIP = generateIPInClass('10.0.0.0/24'); const clientIP = generateIPInClass('10.0.0.0/24'); // Build server config using structured approach const serverConfig: WireGuardConfig = { interface: { privateKey: serverKeys.privateKey, address: [`${serverIP}/24`], listenPort: 51820, dns: ['1.1.1.1', '1.0.0.1'] }, peers: [{ publicKey: clientKeys.publicKey, allowedIPs: [`${clientIP}/32`], preSharedKey: psk }] }; // Build client config for mobile import const clientConfig: WireGuardConfig = { interface: { privateKey: clientKeys.privateKey, address: [`${clientIP}/24`], dns: ['1.1.1.1'] }, peers: [{ publicKey: serverKeys.publicKey, allowedIPs: ['0.0.0.0/0'], endpoint: 'vpn.example.com:51820', preSharedKey: psk, persistentKeepalive: 25 }] }; // Generate configuration files const serverConfigText = buildWireGuardConfig(serverConfig); const clientConfigText = buildWireGuardConfig(clientConfig); // Generate QR code for easy mobile import const qrCode = await generateQRCode(clientConfigText, { width: 256, errorCorrectionLevel: 'M' }); return { serverConfig: serverConfigText, clientConfig: clientConfigText, qrCode: qrCode, setupInfo: { serverIP, clientIP, pskEnabled: true } }; } // Usage createCompleteWireGuardSetup().then(setup => { console.log('✅ Complete WireGuard setup generated!'); console.log('📄 Server config ready'); console.log('📱 Client config + QR code ready for mobile import'); console.log(`🔐 Enhanced security with pre-shared keys`); }); ``` ### QR Code Generation for Mobile Apps ```typescript import { buildWireGuardConfig, generateQRCode } from 'wireguard-utils'; // Build any WireGuard config const config = buildWireGuardConfig(clientConfig); // Generate QR code for mobile import const qrCode = await generateQRCode(config); // Use in web app const qrImageSrc = `data:image/png;base64,${qrCode}`; // Display in HTML document.getElementById('qr-code').innerHTML = `<img src="${qrImageSrc}" alt="WireGuard Config QR Code" />`; ``` ## Advanced Features ### DNS Configuration Helpers WireGuard Utils includes predefined DNS configurations for popular providers: ```typescript import { getDNSConfigs, getDNSByType } from 'wireguard-utils'; // Get all available DNS configurations const dnsProviders = getDNSConfigs(); console.log(dnsProviders.cloudflare.primary); // "1.1.1.1" // Filter by type const privacyDNS = getDNSByType('privacy'); const performanceDNS = getDNSByType('performance'); const securityDNS = getDNSByType('security'); // Available providers: // - Cloudflare (privacy) // - Google (performance) // - Quad9 (security) // - OpenDNS (family) // - AdGuard (privacy) ``` ### Config File Parser Parse existing WireGuard configuration files: ```typescript import { parseWireGuardConfig } from 'wireguard-utils'; const configText = ` [Interface] PrivateKey = ... Address = 10.0.0.1/24 ListenPort = 51820 [Peer] PublicKey = ... AllowedIPs = 10.0.0.2/32 Endpoint = example.com:51820 `; const parsed = parseWireGuardConfig(configText); console.log(`Found ${parsed.peers.length} peers`); console.log(`Listen port: ${parsed.interface.listenPort}`); ``` ### Config Validation Validate configuration security and syntax: ```typescript import { validateWireGuardConfig } from 'wireguard-utils'; const validation = validateWireGuardConfig(config); if (validation.valid) { console.log('✅ Configuration is valid'); } else { console.log('❌ Configuration errors:'); validation.errors.forEach(error => console.log(` - ${error}`)); } // Check warnings and suggestions validation.warnings.forEach(warning => console.log(`⚠️ ${warning}`)); validation.suggestions.forEach(suggestion => console.log(`💡 ${suggestion}`)); ``` ### Port Management Find available ports and check port status: ```typescript import { getRecommendedPorts, findAvailablePort, checkPortAvailability } from 'wireguard-utils'; // Get WireGuard-friendly ports const ports = getRecommendedPorts(); // [51820, 51821, 51822, 443, 53, 80] // Find an available port const port = await findAvailablePort(51820, 51900); console.log(`Available port: ${port}`); // Check specific port const status = await checkPortAvailability(51820); console.log(`Port 51820: ${status.available ? 'available' : 'in use'}`); ``` ### Key Rotation Automated key rotation with migration planning: ```typescript import { rotateKeys, generateKeyRotationPlan } from 'wireguard-utils'; // Rotate keys for a configuration const rotation = rotateKeys(currentConfig, true); // true = rotate PSK too console.log('Old private key:', rotation.oldKeys.privateKey); console.log('New private key:', rotation.newKeys.privateKey); console.log('New PSK:', rotation.newKeys.psk); // Use the new configuration const newConfig = rotation.newConfig; // Generate rotation plan for multiple configs const configs = [serverConfig, clientConfig1, clientConfig2]; const plan = generateKeyRotationPlan(configs); console.log('Rotation order:', plan.rotationOrder); console.log('Timeline:', plan.timeline); plan.instructions.forEach(step => console.log(step)); ``` ### Config Templates Pre-built templates for common WireGuard setups: ```typescript import { generateFromTemplate, getAvailableTemplates } from 'wireguard-utils'; // See available templates const templates = getAvailableTemplates(); // roadwarrior-server, roadwarrior-client, site-to-site, mesh-node, gateway, split-tunnel // Generate server config const serverConfig = generateFromTemplate('roadwarrior-server', { serverIP: '10.0.0.1', port: 443, dns: ['1.1.1.1', '1.0.0.1'] }); // Generate client config const clientConfig = generateFromTemplate('roadwarrior-client', { serverEndpoint: 'vpn.example.com:443' }); // Site-to-site VPN const siteConfig = generateFromTemplate('site-to-site', { serverEndpoint: 'office.example.com:51820' }); // Split tunneling (only private networks) const splitConfig = generateFromTemplate('split-tunnel', { serverEndpoint: 'vpn.example.com:51820' }); ``` ### Advanced Routing Configure split tunneling and custom routing: ```typescript import { generateAdvancedRouting, generateSplitTunnelConfig } from 'wireguard-utils'; // Full tunnel (route all traffic) const fullTunnel = generateAdvancedRouting({ networks: ['10.0.0.0/8'], defaultRoute: true }); // Split tunnel (specific networks only) const splitTunnel = generateAdvancedRouting({ networks: ['192.168.1.0/24', '10.0.0.0/8'], splitTunnel: true }); // Pre-configured split tunnel (private networks only) const privateSplit = generateSplitTunnelConfig(); // Routes: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 // Custom split tunnel const customSplit = generateSplitTunnelConfig( ['10.0.0.0/8'], // Private networks ['203.0.113.0/24', '198.51.100.0/24'] // Custom networks ); ``` ### Tunnel Management Start, stop, and monitor WireGuard tunnels: ```typescript import { startWireGuardTunnel, stopWireGuardTunnel, getTunnelStatus, listActiveTunnels } from 'wireguard-utils'; // Start a tunnel (requires sudo and WireGuard installation) try { const status = await startWireGuardTunnel('/path/to/config.conf', 'wg0'); console.log(`Tunnel ${status.name} started: ${status.active}`); } catch (error) { console.error('Failed to start tunnel:', error.message); } // Stop a tunnel try { await stopWireGuardTunnel('/path/to/config.conf', 'wg0'); console.log('Tunnel stopped'); } catch (error) { console.error('Failed to stop tunnel:', error.message); } // Check tunnel status const status = await getTunnelStatus('wg0'); console.log(`Tunnel: ${status.name}, Active: ${status.active}, Peers: ${status.peers}`); // List all active tunnels const tunnels = await listActiveTunnels(); tunnels.forEach(tunnel => { console.log(`${tunnel.name}: ${tunnel.peers} peers`); }); ``` **Tunnel Management Requirements:** - WireGuard installed (`wg-quick` command available) - Root/sudo privileges - Valid WireGuard configuration files - Network interface permissions ## Cryptographic Details - **Algorithm**: X25519 (Curve25519 for ECDH) - **Key Size**: 32 bytes (256 bits) - **Encoding**: Standard base64 with padding - **Library**: [@noble/curves](https://github.com/paulmillr/noble-curves) for cryptographic operations ## IP Address Generation - **Class A**: 10.0.0.0 - 10.255.255.255 (10.0.0.0/8) - **Class B**: 172.16.0.0 - 172.31.255.255 (172.16.0.0/12) - **Class C**: 192.168.0.0 - 192.168.255.255 (192.168.0.0/16) - **Custom Subnets**: Support for CIDR notation (e.g., 10.0.0.0/24) ## Requirements - Node.js 14+ - TypeScript 4+ (for development) ## License MIT License - see [LICENSE](./LICENSE) file for details. ## Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Run tests: `npm test` 5. Submit a pull request ## Security This library uses industry-standard cryptographic libraries and follows WireGuard's key generation specification. However, for production use, please: 1. Ensure proper random number generation in your environment 2. Store private keys securely 3. Follow WireGuard best practices for key management ## Support - 📝 [Documentation](https://github.com/princeomonu/wireguard-utils#readme) - 🐛 [Issues](https://github.com/princeomonu/wireguard-utils/issues) - 💬 [Discussions](https://github.com/princeomonu/wireguard-utils/discussions)