Final piece of "connects but no traffic": with the reduced client MTU (1280)
the upload direction fits, but full-size download packets (web pages, TLS
responses) still exceeded the AmneziaWG tunnel and were dropped — handshake
and small packets worked, browsing stalled. Confirmed on a live server: the
client's encrypted packets reached the server but large return packets never
made it back. Adding a server-side TCP MSS clamp to 1240 (= 1280 - 40) made
real traffic flow (verified: 1.6 MiB transferred, FORWARD/MASQUERADE counters
incrementing).
- VpnClient::addClientToServer(): after applying the peer, idempotently ensure
net.ipv4.ip_forward=1 and a `mangle FORWARD ... TCPMSS --set-mss 1240` rule
(-C then -A). Re-applied on every client creation, so it survives container
restarts/reinstalls and covers adopted native Amnezia containers.
- migrations/072 + 064: add the same MSS clamp to the awg2 install script
PostUp (and remove it in PostDown) for panel-installed servers.
Verified end-to-end: removing the rule and creating a client via the panel
re-adds it automatically; the live phone client now browses normally.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Issue #50: AWG2 clients connect (handshake OK) but no traffic flows. The
awg2 client output_template lost its "MTU = 1280" line when migration 064
rewrote it (migration 058 had it). With no explicit MTU the client defaults
to 1420, which is too large once AmneziaWG obfuscation overhead (Jc junk
packets, S1/S2 padding) is added on top of WireGuard's: small packets (the
handshake) pass, larger packets (TLS, web pages) are dropped — tunnel
"connected" but unusable. 1280 is the official Amnezia app default.
- migrations/071: add "MTU = 1280" to the awg2 output_template (existing DBs).
- migrations/064: add the MTU line to the template source (fresh installs).
- buildClientConfig(): emit MTU = 1280 in the fallback path too.
Server-side NAT/forwarding/ip_forward were verified correct on a live server,
so this is purely a client-config regression. Generated client config now
contains "MTU = 1280" and mirrors the server's obfuscation params exactly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>
- 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.
Without interface reload, AWG obfuscation params (Jc, S1, S2, H1-H4) are not
applied to the kernel, and connections fail because client uses AWG but
server uses standard WireGuard protocol.
- Modified migrations/048_enable_xray_stats.sql to accept existing keys via env vars (PRIVATE_KEY, SHORT_ID)
- Updated InstallProtocolManager.php to extract and store reality_private_key after XRay installation
- Added key restoration logic in buildExports() to reuse saved keys during reinstallation
- Fixed VpnClient.php to correctly parse JSON stats output from XRay API
- Security fix: removed exposed port 2375 from docker-compose.yml (dind container)
- Added InstallProtocolManager::addClient and fallback logic for X-Ray VLESS
to update server configuration (server.json) and restart container.
- Updated VpnClient::create to invoke InstallProtocolManager::addClient for
scripted protocols, enabling dynamic user addition.
- Ensured UUID generation for X-Ray clients.
Instead of generating a JSON config for X-Ray, pass the raw VLESS URI string
wrapped in a JSON object inside .
This matches the behavior of WireGuard config handling in the master branch
and is likely the expected format for Amnezia Android X-Ray import.
- Fix docker run command in install script (use single line instead of
backslash continuations which break when stored in MySQL)
- Handle new xray x25519 output format that uses 'Password' instead of 'Public key'
- Make addClientToServer method public for backup restore functionality
- Created migration 046 with complete fix for X-Ray VLESS protocol
- Added a new PHP script for collecting server metrics every 30 seconds.
- Created a ServerMonitoring class to handle metrics collection for CPU, RAM, Disk, and Network.
- Introduced database tables for storing server and client metrics.
- Updated server view template to display real-time metrics using Chart.js.
- Added translations for monitoring UI elements.
- Created a new monitoring template for detailed server metrics visualization.
- Implemented client speed tracking and display in the monitoring UI.