From 326421f07b2a4e937b87126f4d6eff6418097cdf Mon Sep 17 00:00:00 2001 From: infosave2007 Date: Sat, 4 Apr 2026 16:02:11 +0300 Subject: [PATCH] feat: enhance AWG2 protocol handling by adding config directory management and fixing empty peer block in install script --- inc/InstallProtocolManager.php | 9 +++++-- inc/VpnClient.php | 27 ++++++++++--------- migrations/058_add_awg2_protocol.sql | 10 ------- ..._fix_awg2_empty_peer_in_install_script.sql | 14 ++++++++++ 4 files changed, 36 insertions(+), 24 deletions(-) create mode 100644 migrations/063_fix_awg2_empty_peer_in_install_script.sql diff --git a/inc/InstallProtocolManager.php b/inc/InstallProtocolManager.php index 51caf99..b0ebc3d 100644 --- a/inc/InstallProtocolManager.php +++ b/inc/InstallProtocolManager.php @@ -1093,6 +1093,10 @@ class InstallProtocolManager $metadata = $protocol['definition']['metadata'] ?? []; $serverData = $server->getData(); $containerName = $serverData['container_name'] ?? ($metadata['container_name'] ?? 'amnezia-awg'); + $configDir = trim((string) ($metadata['config_dir'] ?? '')); + if ($configDir === '') { + $configDir = (($protocol['slug'] ?? '') === 'awg2') ? '/opt/amnezia/awg2' : '/opt/amnezia/awg'; + } $candidateNames = array_values(array_unique(array_filter([ is_string($containerName) ? trim($containerName) : '', is_string($metadata['container_name'] ?? null) ? trim((string) $metadata['container_name']) : '', @@ -1111,10 +1115,11 @@ class InstallProtocolManager $server->executeCommand("docker rm -fv {$arg} 2>/dev/null || true", true); } // Remove known images (best-effort) - $server->executeCommand("docker rmi amneziavpn/amnezia-wg amneziavpn/amnezia-awg 2>/dev/null || true", true); + $server->executeCommand("docker rmi amneziavpn/amnezia-wg amneziavpn/amnezia-awg amnezia-awg2 2>/dev/null || true", true); // Attempt to remove amnezia-dns-net network if present (best-effort) $server->executeCommand("docker network rm amnezia-dns-net 2>/dev/null || true", true); - // Remove on-disk data for AWG + // Remove on-disk data for AWG protocol config to avoid stale restore paths. + $server->executeCommand("rm -rf " . escapeshellarg($configDir) . " 2>/dev/null || true", true); $server->executeCommand("rm -rf /opt/amnezia/amnezia-awg 2>/dev/null || true", true); // Clear server deployment metadata in database for this server diff --git a/inc/VpnClient.php b/inc/VpnClient.php index 6361926..d58084d 100644 --- a/inc/VpnClient.php +++ b/inc/VpnClient.php @@ -675,17 +675,9 @@ class VpnClient private static function generateClientKeys(array $serverData, string $clientName): array { $containerName = $serverData['container_name']; - $token = bin2hex(random_bytes(8)); - $cmd = sprintf( - "docker exec -i %s sh -c \"umask 077; wg genkey | tee /tmp/%s_priv.key | wg pubkey > /tmp/%s_pub.key; cat /tmp/%s_priv.key; echo '---'; cat /tmp/%s_pub.key; rm -f /tmp/%s_priv.key /tmp/%s_pub.key\"", - $containerName, - $token, - $token, - $token, - $token, - $token, - $token + "docker exec -i %s sh -lc 'set -e; umask 077; priv=$(wg genkey); pub=$(printf %s \"$priv\" | wg pubkey); printf \"%%s\\n---\\n%%s\\n\" \"$priv\" \"$pub\"'", + escapeshellarg($containerName) ); $escaped = escapeshellarg($cmd); @@ -705,9 +697,15 @@ class VpnClient throw new Exception("Failed to generate client keys"); } + $private = trim((string) $parts[0]); + $public = trim((string) $parts[1]); + if ($private === '' || $public === '') { + throw new Exception('Failed to generate client keys: empty key output'); + } + return [ - 'private' => trim($parts[0]), - 'public' => trim($parts[1]) + 'private' => $private, + 'public' => $public ]; } @@ -984,6 +982,11 @@ class VpnClient { $containerName = $serverData['container_name']; $presharedKey = $serverData['preshared_key']; + $publicKey = trim($publicKey); + + if ($publicKey === '') { + throw new Exception('Refusing to add client with empty public key'); + } // 1. Create temp file for PSK (to avoid shell escaping issues) $pskFile = '/tmp/' . bin2hex(random_bytes(8)) . '.psk'; diff --git a/migrations/058_add_awg2_protocol.sql b/migrations/058_add_awg2_protocol.sql index 1d2e856..7256398 100644 --- a/migrations/058_add_awg2_protocol.sql +++ b/migrations/058_add_awg2_protocol.sql @@ -119,11 +119,6 @@ H3 = $H3_VAL H4 = $H4_VAL PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE - -[Peer] -PublicKey = -PresharedKey = $PRESHARED_KEY -AllowedIPs = 10.8.1.2/32 EOF echo "$PRIVATE_KEY" > /opt/amnezia/awg2/wireguard_server_private_key.key @@ -310,11 +305,6 @@ H3 = $H3_VAL H4 = $H4_VAL PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE - -[Peer] -PublicKey = -PresharedKey = $PRESHARED_KEY -AllowedIPs = 10.8.1.2/32 EOF echo "$PRIVATE_KEY" > /opt/amnezia/awg2/wireguard_server_private_key.key diff --git a/migrations/063_fix_awg2_empty_peer_in_install_script.sql b/migrations/063_fix_awg2_empty_peer_in_install_script.sql new file mode 100644 index 0000000..7c8b8ec --- /dev/null +++ b/migrations/063_fix_awg2_empty_peer_in_install_script.sql @@ -0,0 +1,14 @@ +-- Remove invalid empty peer block from AWG2 install script. +-- The old script generated wg0.conf with: +-- [Peer] +-- PublicKey = +-- which causes awg setconf parse errors and restart loops. + +UPDATE protocols +SET install_script = REPLACE( + install_script, + '\n[Peer]\nPublicKey = \nPresharedKey = $PRESHARED_KEY\nAllowedIPs = 10.8.1.2/32\n', + '\n' +) +WHERE slug = 'awg2' + AND install_script LIKE '%[Peer]%PublicKey = %PresharedKey = $PRESHARED_KEY%AllowedIPs = 10.8.1.2/32%';