import 'dart:convert'; import 'dart:io'; class WireGuardService { static const String interfaceName = 'wg0'; static const String configPath = '/etc/wireguard/wg0.conf'; static const String serverIP = '10.0.0.1/24'; static const int serverPort = 51820; static Future initializeServer() async { try { // Check if wg0 interface already exists if (await _interfaceExists()) { print('WireGuard interface $interfaceName already exists.'); return; } print('Initializing WireGuard server interface...'); // Generate server keys if they don't exist final serverKeys = await _getOrCreateServerKeys(); // Create server config await _createServerConfig(serverKeys['privateKey']!); // Bring up the interface await _bringUpInterface(); print('WireGuard server interface $interfaceName initialized successfully.'); } catch (e) { throw Exception('Failed to initialize WireGuard server: $e'); } } static Future _interfaceExists() async { try { final result = await Process.run('wg', ['show', interfaceName]); return result.exitCode == 0; } catch (e) { return false; } } static Future> _getOrCreateServerKeys() async { try { // Try to get existing keys from running interface final pubResult = await Process.run('wg', ['show', interfaceName, 'public-key']); final privResult = await Process.run('wg', ['show', interfaceName, 'private-key']); if (pubResult.exitCode == 0 && privResult.exitCode == 0) { return { 'publicKey': pubResult.stdout.toString().trim(), 'privateKey': privResult.stdout.toString().trim(), }; } } catch (e) { // Keys don't exist, generate new ones } // Generate new keys final privateKeyResult = await Process.run('wg', ['genkey']); if (privateKeyResult.exitCode != 0) { throw Exception('Failed to generate private key'); } final privateKey = privateKeyResult.stdout.toString().trim(); // Generate public key from private key final pubProcess = await Process.start('wg', ['pubkey']); pubProcess.stdin.writeln(privateKey); await pubProcess.stdin.close(); final publicKey = await pubProcess.stdout.transform(utf8.decoder).join(); return { 'privateKey': privateKey, 'publicKey': publicKey.trim(), }; } static Future _createServerConfig(String privateKey) async { final config = ''' [Interface] PrivateKey = $privateKey Address = $serverIP ListenPort = $serverPort PostUp = iptables -A FORWARD -i $interfaceName -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i $interfaceName -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE '''; // Ensure config directory exists final configDir = Directory('/etc/wireguard'); if (!await configDir.exists()) { await configDir.create(recursive: true); } // Write config file final configFile = File(configPath); await configFile.writeAsString(config); // Set proper permissions (600) await Process.run('chmod', ['600', configPath]); } static Future _bringUpInterface() async { // Start WireGuard interface final result = await Process.run('wg-quick', ['up', interfaceName]); if (result.exitCode != 0) { throw Exception('Failed to bring up WireGuard interface: ${result.stderr}'); } } static Future stopInterface() async { try { await Process.run('wg-quick', ['down', interfaceName]); } catch (e) { // Interface might not be running, ignore } } }