Both the code comment and the docs said the interface row is "14 columns for AWG 2.0, 28
for AWG 3.0". That reads as a version signal and it is not one. The width of the row is
decided by the version of amneziawg-tools doing the printing, not by which protocol
parameters the tunnel has configured: AWG 3.0 tools emit the wide row for an AWG 2.0
configuration too, with the newer fields simply zero, empty or (none). Any rule of the
form "N columns means version X" is wrong by construction.
The classifier never relied on column count for that purpose - it discriminates on the
allowed-ips column - so this is a correction to what the code claims about itself and to
what the docs would lead a future change to assume.
Five fixtures added from the audit's list, all previously uncovered:
- AWG 3.0 interface row with header protection disabled: the key column is (none) and the
range fields collapse to single values;
- an AWG 2.0 configuration read through AWG 3.0 tools, asserted to have the same width as
a native AWG 3.0 row and to still be rejected while its peer parses;
- a dump containing several interfaces, each with its own peers;
- an interface with no peers at all;
- malformed rows - truncated, non-numeric handshake, non-CIDR allowed-ips - which must be
skipped rather than partially interpreted.
Docs also pin what was verified and against which versions, rather than stating it as
timeless: AmneziaVPN 5.0.0.5 and the master branches of amneziawg-tools and amneziawg-go
at the time of the change.
amnezia-awg3 is now described as what it is - not a confirmed official name. AmneziaVPN
5.0.0.5 added AWG 3.0 support but still exposes only Awg and Awg2 container variants. It
stays in the example list on purpose, and the reasoning is written down: a name that does
not match costs nothing because the search continues down the list, while a name missing
from the list produces a silent "container not found". This is a deliberate deviation from
the audit's suggestion to build defaults only from names in use today.
cargo fmt --check, clippy -D warnings, and cargo test --locked --workspace --release all
clean: 163 + 4 passed.
Peer discovery is now the single owner of how wg is invoked and parsed.
wg.rs:
- resolve the binary through ordered amnezia.wg_binaries (default [awg, wg]);
awg is the real binary in the official image and wg is a symlink to it, so awg is
tried first and wg stays for plain WireGuard containers. No probe call: resolution
is a property of the command being run anyway.
- drop the nsenter fallback. AmneziaWG is userspace and its UAPI socket lives under
RUNSTATEDIR/amneziawg/ in the container mount namespace, while host wireguard-tools
looks under /var/run/wireguard/. nsenter -n enters only the network namespace, so
that path could never return peers.
- classify dump lines structurally instead of by column count. The AWG interface line
is longer than a peer line (14 columns on AWG 2.0, 28 on AWG 3.0) and its
handshake/rx/tx positions hold junk-packet sizes that parse as integers, so only the
allowed-ips column discriminates. Column 1 of an interface line is the device private
key, which the previous heuristic rejected only incidentally.
- fix allowed-ips parsing: `show all allowed-ips` separates a peer's addresses with
spaces, not commas, so peers with more than one allowed IP were shaped on their first
address only and the rest ran unlimited.
- collapse the three duplicated /32-in-CIDR filters into one tokenizer shared by the
allowed-ips, dump and pretty-print parsers.
config.rs:
- add amnezia.wg_binaries with serde default, validated as bare command names
(non-empty, no whitespace, no path separators) since they execute inside the
container. Existing deployed configs keep parsing unchanged.
- remove host wg from the required-tool preflight. It gated daemon startup on
wireguard-tools for a code path that produced nothing.
status.rs:
- discover peers once instead of twice per status call and degrade gracefully like the
neighbouring sections instead of aborting the whole output.
Tests: real AWG 3.0 / AWG 2.0 / plain WireGuard interface-line fixtures, AWG 3.0 range
keepalive, space-separated allowed-ips, binary resolution order, and a test that parses
and validates the shipped config.example.toml.
- Swap: допуск небольшой дельты usable size при verify/compare
- Firewall: поддержка Debian 13 dynamic set/add @set вместо только literal meter
- WG: приоритет docker exec для peer/runtime discovery с безопасным fallback