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
Markdown
# 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)