Clients were created successfully but could not connect: the AmneziaWG
handshake requires the client's obfuscation params (Jc/Jmin/Jmax/S1-S4/
H1-H4/I1-I5) to EXACTLY match the server's, and they did not.
Two causes, both fixed:
- syncServerKeysFromContainer() read params from `wg show` first and only
accepted H1-H4 in the AWG-2.0 "a-b" range format, dropping the single-value
H1-H4 used by classic AmneziaWG servers (the official Amnezia image). It
also skipped the complete wg0.conf read once `wg show` returned partial
data. Now the server config file (awg0.conf/wg0.conf) is the primary,
format-agnostic source; `wg show` is a fallback that accepts single values
and ranges.
- create() filled any param missing from the (incomplete) sync with awg2
defaults — injecting H1-H4 ranges, S3/S4 and I1 onto a classic server that
uses none of them. Now client params mirror the server's synced params
verbatim; defaults are used only when nothing was synced at all. Empty
AWG lines (params the server does not use) are stripped from the rendered
config so the client carries exactly the server's set.
Verified end-to-end on a live server: a real amneziawg-go client built from
the generated config completes the handshake
("latest handshake: 14 seconds ago", bidirectional transfer) — params
(jc/s1/s2/h1-h4) match the server exactly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Live testing against an AmneziaWG 2.0 server revealed the actual root cause
of "Failed to generate client keys": the official Amnezia container image
ships the userspace tool only as `wg` (a patched AmneziaWG binary) and has
NO `awg` binary, while the panel hardcoded `awg` for AWG2. `awg genkey` then
failed with "sh: awg: not found". (amneziawg-go ships `awg` with `wg`
symlinked, so both names work there — but the Amnezia image does not.)
- generateClientKeys(): detect the tool inside the container
(`command -v awg || command -v wg`) instead of hardcoding `awg`.
- addClientToServer(): resolve the tool via new resolveWgTool() helper so
`wg set` / `wg-quick up` (peer apply) also work on the Amnezia image.
- executeServerCommand(): delegate to VpnServer::executeCommand so SSH key
auth + docker sudo auto-detection apply to all 19 call sites (it was
password-only before).
Verified end-to-end on a live AWG2 server: pre-fix code fails with
"Failed to generate client keys: sh: awg: not found"; fixed code creates
the client, generates keys, and the peer appears in `wg show wg0`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Issue #50 (AmneziaWG 2.0 / awg2): "Failed to generate client keys" when
creating clients, and "Invalid server response" on first install.
- VpnClient::generateClientKeys() built its own password-only SSH command
(PubkeyAuthentication=no, no sudo), bypassing VpnServer::executeCommand.
That broke key-based servers and hosts where docker requires sudo. Route
it through executeCommand so SSH-key auth and docker sudo auto-detection
apply, matching every other remote operation.
- VpnClient::getNextClientIP() read /opt/amnezia/awg/wg0.conf only; AWG2
uses awg0.conf. Read awg0.conf first, fall back to wg0.conf.
- deploy route: lift PHP time limit (set_time_limit(0) + ignore_user_abort)
so the multi-minute awg2 docker build is not killed mid-request, which
produced the truncated, non-JSON "Invalid server response".
- migration 070: drop `--no-cache` from the awg2 docker build so layers are
reused, making installs and retries fast and idempotent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Implemented migration 067 to set up Cloudflare WARP with automatic routing for VPN client TCP traffic through a redsocks proxy.
- Included installation scripts for WARP and redsocks, along with iptables rules for traffic redirection.
- Added detection for X-Ray and patching of its outbound configuration.
- Created uninstall scripts to clean up configurations and remove installed packages.
fix(migrations): Enhance WARP install script for heredoc compatibility
- Implemented migration 068 to fix nested heredoc conflicts and streamline the WARP installation script for panel compatibility.
- Removed duplicate `set -eo pipefail` and adjusted formatting for better readability.
feat(migrations): Auto-detect AIVPN subnet for routing in WARP setup
- Implemented migration 069 to enhance the WARP installation script by adding detection for AIVPN subnets alongside existing AWG container detection.
- Updated routing logic to handle both container IPs and host-level VPN subnets.
- Ensured proper configuration of iptables for seamless traffic routing through the WARP proxy.
- Introduced AIVPN server detection and statistics fetching in ServerMonitoring.
- Implemented AIVPN client statistics handling in VpnClient, including raw and offset counters for traffic.
- Enhanced AWG parameters to include S3 and S4.
- Updated database schema to accommodate new AIVPN statistics fields.
- Added a script for remote reset and reinstallation of protocols.
- Improved client view template to ensure proper display of connection instructions.
- Added translations for connection instructions in multiple languages.
- Ensured host-level NAT for AWG subnet in VpnServer.