A TypeScript library for WireGuard utilities including key generation, IP management, config building, and QR code generation using proper Curve25519 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
- ✅ 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
- ✅ 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
- ✅ 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
- ✅ Validated: Comprehensive test suite ensuring cryptographic correctness
- ✅ Production Ready: Enterprise-grade error handling and validation
npm install wireguard-utils
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!');
Generates a complete WireGuard key pair with a random private key.
Returns: Object with privateKey
and publicKey
properties (both base64 encoded)
const keyPair = generateWireguardKeyPair();
// {
// privateKey: "nPse/4zbQGxOqAM14icWRru4I6g9s9xdhg9sCY2l3ck=",
// publicKey: "Y3AdHf4MAZi3xgCFxiDfyPBNbBQKuTqTCoDI/XHrnQg="
// }
Generates a random WireGuard private key.
Returns: Base64 encoded private key (32 bytes)
const privateKey = generatePrivateKey();
// "nPse/4zbQGxOqAM14icWRru4I6g9s9xdhg9sCY2l3ck="
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
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
Validates a WireGuard public key format.
Parameters:
-
publicKey
- Base64 encoded public key to validate
Returns: true
if valid, false
otherwise
const isValid = validatePublicKey("Y3AdHf4MAZi3xgCFxiDfyPBNbBQKuTqTCoDI/XHrnQg=");
console.log(isValid); // true
const isInvalid = validatePublicKey("invalid-key");
console.log(isInvalid); // false
The generateIPInClass
function is overloaded to support multiple usage patterns:
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
// 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"
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
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
}]
};
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
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
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
// 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}`;
interface WireGuardKeyPair {
privateKey: string; // Base64 encoded private key (32 bytes)
publicKey: string; // Base64 encoded public key (32 bytes)
}
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
}
interface QROptions {
errorCorrectionLevel?: 'L' | 'M' | 'Q' | 'H'; // Error correction level
width?: number; // QR code width in pixels
margin?: number; // Margin around QR code
}
import { generateWireguardKeyPair } from 'wireguard-utils';
const keyPair = generateWireguardKeyPair();
console.log(`Private: ${keyPair.privateKey}`);
console.log(`Public: ${keyPair.publicKey}`);
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 });
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);
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');
}
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
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`);
});
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" />`;
WireGuard Utils includes predefined DNS configurations for popular providers:
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)
Parse existing WireGuard configuration files:
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}`);
Validate configuration security and syntax:
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}`));
Find available ports and check port status:
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'}`);
Automated key rotation with migration planning:
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));
Pre-built templates for common WireGuard setups:
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'
});
Configure split tunneling and custom routing:
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
);
Start, stop, and monitor WireGuard tunnels:
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
- Algorithm: X25519 (Curve25519 for ECDH)
- Key Size: 32 bytes (256 bits)
- Encoding: Standard base64 with padding
- Library: @noble/curves for cryptographic operations
- 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)
- Node.js 14+
- TypeScript 4+ (for development)
MIT License - see LICENSE file for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
npm test
- Submit a pull request
This library uses industry-standard cryptographic libraries and follows WireGuard's key generation specification. However, for production use, please:
- Ensure proper random number generation in your environment
- Store private keys securely
- Follow WireGuard best practices for key management
- 📝 Documentation
- 🐛 Issues
- 💬 Discussions