119 lines
3.6 KiB
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
|
|
}
|
|
}
|
|
} |