The awg3 card reused awg_desc, which talks about awg-go and S3/S4 — true
of 2.0 as well, so the card said nothing about what the newer protocol
actually changes. Give it its own key naming the 3.x additions: header
protection, content padding and randomized timings.
_t() falls back to the key itself rather than to English, so the string is
added to all five locales at once.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Installed protocols are rendered from static cards in the template that
applyInstalledAppsVisibility() only shows or hides, while the marketplace
builds its list dynamically from MARKETPLACE_APPS. With an entry in the
array but no static card, awg3 showed up as INSTALLED in Templates and
never got a tile on the server page.
Move the NEW badge to 3.1 as the newest protocol.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
With HeaderProtectionKey set, the kernel module rejects any junk size
S1-S4 below HEADER_PROTECTION_NONCE_SIZE (12) — see the per-field checks
in netlink.c. The generator drew them from randint(10, 50), so roughly one
install in six produced an 10 or 11 and failed.
The failure was silent: `awg setconf` only reports "Invalid argument",
because the kernel explains itself through net_dbg_ratelimited, which is
off by default. The panel reported the install as successful while the
interface never came up.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
AmneziaWG 3.1 adds a header protection key, content padding and randomized
protocol timings on top of the 2.0 obfuscation set. The panel generated only
the 2.0 parameters, so servers were always installed as 2.0.
Register awg3 as a separate protocol (container amnezia-awg3) instead of
extending awg2: existing installations keep byte-identical configs, and
clients that predate 3.1 are unaffected.
The parameters are defined once in AWG3_PARAM_MAP and reused by the server
config builder, the config parser and both client config builders. Parsing
matters as much as generation — client configs are rebuilt from the server
config, so a missing parser entry would silently drop the parameters and
break the handshake.
The amneziavpn/amneziawg-go image already ships amneziawg-tools 3.1, so no
image change is needed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
awg/wg show reports peer transfer counters from the SERVER's perspective:
- 'received' = bytes the client uploaded
- 'sent' = bytes the client downloaded
The template rendered them the other way around, so the download badge (down arrow) showed the client's upload and vice versa. Swap the badges so arrows match the client's perspective.
With 'Address = 10.8.1.1/24, fd42:8:1::1/64' the CIDR parser returned
'24, fd42:8:1::1', crashing int() in _get_subnet_base when adding a peer.
Both helpers now take only the first comma-separated (IPv4) component.
- install_protocol detects host IPv6 (default route or global address)
and configures a ULA subnet (fd42:8:1::/64) alongside IPv4 when present
- start.sh learns the IPv6 subnet from the config Address line and adds
ip6tables forwarding + NAT66 (MASQUERADE) rules; IPv4-only setups are
untouched
- clients deterministically get an IPv6 derived from their IPv4 last
octet (10.8.1.N -> fd42:8:1::<hex N>), so existing peers receive IPv6
automatically when their config is regenerated
- peer AllowedIPs and client Address become dual-stack; clientIpv6 is
stored in clientsTable; Cloudflare IPv6 DNS is added for v6 clients
- get_client_config and toggle_client re-add path handle IPv6 as well
xray api adu in Xray-core v26 builds a full inbound config from the
payload and silently adds 0 users (exit code 0) when port/listen are
missing. Include the inbound's port and listen in the adu payload and
treat "Added 0 user(s)" output as a failure so the caller falls back
to the restart-required error path instead of reporting success.
- _get_next_ip now returns the first free address in the subnet instead
of incrementing the last IP found in file order, which could hand out
duplicate IPs and never reused addresses freed by deleted clients
- new peers are inserted into the server config keeping [Peer] sections
sorted by AllowedIPs
- a timestamped backup of the config is created inside the container
before it is overwritten
start.sh was generated once at install time with a hardcoded
10.8.1.0/24 subnet in iptables/NAT rules. When the user changed
the Address field in the server config via the web panel, the
config and client configs updated correctly but start.sh kept
the old subnet — breaking NAT/forwarding for the new network.
Changes:
- start.sh now reads SUBNET from the config file at runtime
via grep instead of using a compile-time hardcoded value
- save_server_config() regenerates start.sh on every config save
so existing containers with old hardcoded scripts are fixed
- _get_next_ip() computes the base network address from the
live config instead of AWG_DEFAULTS
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>