AmneziaWG 3.0 readiness: centralize wg CLI contract, drop dead host-side fallback
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.
This commit is contained in:
+14
-20
@@ -48,27 +48,25 @@ pub fn print_status(cfg: &Config) -> anyhow::Result<()> {
|
||||
cfg.host_firewall.amnezia_port,
|
||||
);
|
||||
|
||||
let peers = wg::discover_peers(
|
||||
target.container_pid,
|
||||
&target.container_name,
|
||||
&cfg.amnezia.peer_ipv4_cidr,
|
||||
)?;
|
||||
// Peer discovery is one container round-trip, shared by both sections below.
|
||||
let peers = wg::discover_peers(cfg, &target);
|
||||
println!("Peers:");
|
||||
println!(" total: {}", peers.len());
|
||||
for p in peers {
|
||||
println!(" - {}", p.ipv4);
|
||||
match &peers {
|
||||
Ok(list) => {
|
||||
println!(" total: {}", list.len());
|
||||
for p in list {
|
||||
println!(" - {}", p.ipv4);
|
||||
}
|
||||
}
|
||||
Err(e) => println!(" unavailable ({e})"),
|
||||
}
|
||||
|
||||
println!("WireGuard clients:");
|
||||
println!(
|
||||
" IP State Latest handshake RX TX Public key Endpoint"
|
||||
);
|
||||
match wg::discover_peer_runtime(
|
||||
target.container_pid,
|
||||
&target.container_name,
|
||||
&cfg.amnezia.peer_ipv4_cidr,
|
||||
) {
|
||||
Ok(runtime_peers) => {
|
||||
match (&peers, wg::discover_peer_runtime(cfg, &target)) {
|
||||
(Ok(peers_sorted), Ok(runtime_peers)) => {
|
||||
let mut by_ip: BTreeMap<String, &wg::PeerRuntime> = BTreeMap::new();
|
||||
for rp in &runtime_peers {
|
||||
for ip in &rp.allowed_ips {
|
||||
@@ -76,11 +74,6 @@ pub fn print_status(cfg: &Config) -> anyhow::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
let peers_sorted = wg::discover_peers(
|
||||
target.container_pid,
|
||||
&target.container_name,
|
||||
&cfg.amnezia.peer_ipv4_cidr,
|
||||
)?;
|
||||
for p in peers_sorted {
|
||||
let ip = p.ipv4.to_string();
|
||||
if let Some(rp) = by_ip.get(&ip) {
|
||||
@@ -104,7 +97,8 @@ pub fn print_status(cfg: &Config) -> anyhow::Result<()> {
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => println!(" unavailable ({e})"),
|
||||
(Err(e), _) => println!(" unavailable ({e})"),
|
||||
(_, Err(e)) => println!(" unavailable ({e})"),
|
||||
}
|
||||
|
||||
println!("Traffic desired:");
|
||||
|
||||
Reference in New Issue
Block a user