Files
AWG2_harness/docs/PRODUCTION_EXAMPLE.md
T
founder 16214f3c66 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.
2026-08-06 15:32:26 +05:00

2.5 KiB

Production example (reference)

Этот пример фиксирует эталонный production-state после успешной установки и preflight. Значения обезличены и предназначены как reference для smoke-проверки.

SSH:
  host: <server-ip>
  port: 2323
  user: root

Amnezia:
  container: amnezia-awg2
  interface: awg0
  published UDP: 443
  peer CIDR: 10.8.1.0/24

AmneziaDNS:
  container: amnezia-dns
  status: healthy
  internal_ip: 172.29.172.254  # example value; verify with docker inspect
  exposed_ports: 53/tcp, 53/udp inside Docker only
  published_ports: none
  public_53: closed

Expected status:
  service: active
  network tuning drift: no
  traffic drift: no
  host firewall drift: no
  anti-torrent drift: no
  swap drift: no

Проверка ключевых сигналов:

systemctl status awg2-harness.service --no-pager -l
systemctl status awg2-reboot-scheduler.service --no-pager -l
awg2-harness --config /etc/awg2-harness/config.toml status

Проверка Docker/Amnezia runtime:

docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'
C="$(docker ps --format '{{.Names}}' | grep -E '^(amnezia-awg2|amnezia-awg3|amnezia-awg)$' | head -n1)"
docker port "$C"
docker exec "$C" awg show
docker inspect -f 'ports={{json .NetworkSettings.Ports}}' amnezia-dns

Проверка AWG-контракта внутри контейнера (без раскрытия секретов):

docker exec "$C" readlink -f /usr/bin/wg     # ожидается /usr/bin/awg
docker exec "$C" awg --version
docker exec "$C" ip -o link show awg0
docker exec "$C" awg show all allowed-ips
docker exec "$C" awg show all dump | awk -F '\t' '{ print "row=" NR, "fields=" NF, "interface=" $1 }'

Interface-строка awg show all dump даёт 14 полей на AWG 2.0 и 28 на AWG 3.0, peer-строки — 9. Полный вывод awg show all dump передавать нельзя: во второй колонке interface-строки находится приватный ключ устройства.

Проверка, что runtime config создан вручную (ожидаемое поведение):

test -f /etc/awg2-harness/config.toml && echo "runtime config present"

Если файл отсутствует после apt install, это корректно: создайте его вручную из /usr/share/doc/awg2-harness/repo/config.example.toml.