Files
waylume_server/lib/services/wireguard_service.dart

119 lines
3.6 KiB
Dart

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<void> 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<bool> _interfaceExists() async {
try {
final result = await Process.run('wg', ['show', interfaceName]);
return result.exitCode == 0;
} catch (e) {
return false;
}
}
static Future<Map<String, String>> _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<void> _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<void> _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<void> stopInterface() async {
try {
await Process.run('wg-quick', ['down', interfaceName]);
} catch (e) {
// Interface might not be running, ignore
}
}
}