29 KiB
AWG2 Harness 0.3.1 — отчёт о валидации
Даты проверок:
- 2026-08-28 — synthetic runtime validation;
- 2026-08-29 — clean production acceptance.
1. Назначение
Этот документ фиксирует фактически выполненные build-, package- и runtime-проверки AWG2 Harness 0.3.1 по сохранённым локальным логам оператора.
Он не заменяет ACCEPTANCE_CHECKLIST.md. Его задача — сохранить доказанный на практике baseline:
- какая ревизия проверялась;
- в каком окружении выполнялись проверки;
- какие свойства подтверждены реальным Linux runtime;
- какие проверки были negative/fail-closed;
- какие сценарии оставались после synthetic-прогона;
- какие из них затем закрыты clean production acceptance.
Сырой terminal dump намеренно не включён в репозиторий: в нём присутствуют public keys, container IDs и инфраструктурные детали. Ниже сохранены воспроизводимые команды, существенные наблюдения и границы результата.
2. Проверенные ревизии
Полный synthetic runtime-прогон выполнен для базовой ревизии:
7390d1fa2c0710cb189897728e1bc1bfed9fbc53
Финальная ревизия с изменениями production-кода, прошедшая повторный Linux build/package gate:
37573022c2ca56480e99bf7515dca1c68254690e
Версия пакета:
awg2-harness 0.3.1
Production delta между этими ревизиями затронул только traffic_core/src/swap/runtime.rs: вызов swapon переведён на документированную форму --show=NAME,TYPE,SIZE,PRIO. Изменение отдельно закрыто regression-тестом и smoke-тестом на реальном util-linux 2.41.5.
Таким образом, разделы с полным synthetic runtime относятся к 7390d1f, а build/package и swapon runtime-проверки после этого исправления — к 3757302.
3. Окружение
Build/runtime host:
- Debian 13 amd64;
- Linux
6.12.101+deb13-amd64; - Rust
1.95.0; - Cargo
1.95.0; - ShellCheck
0.10.0; - util-linux
2.41.5.
Synthetic runtime выполнялся на существующем контейнере AmneziaWG 2.0.
Контейнер использовался как локальный runtime fixture. Внешний VPN dataplane на сервере не являлся рабочим из-за известной внешней конфигурационной проблемы, не связанной с AWG2 Harness. Поэтому этот test run не является end-to-end acceptance AWG 3.1.
4. Build gate и упаковка
Для ревизии 3757302 команда tools/build.sh --package успешно выполнила обязательные gates:
cargo fmt --check;cargo clippy --locked --workspace --all-targets -- -D warnings;- release tests;
- release build;
- Cargo locked metadata validation;
- ShellCheck;
- проверку release-бинарников;
- Debian package assembly;
- package metadata/content checks;
- создание SHA256 manifest.
Linux release tests:
awg2-harness: 251 passed;awg2-reboot-scheduler: 4 passed;- failures: 0.
Собран пакет:
awg2-harness_0.3.1_amd64.deb
Подтверждено:
- package metadata: версия
0.3.1, архитектураamd64; - оба binary устанавливаются и выполняют
--help; - systemd units проходят
systemd-analyze verify; - production
config.tomlне создаётся автоматически; - после clean package state оба сервиса остаются disabled/inactive до явного включения оператором;
dist/SHA256SUMSуспешно проверяет пакет на builder.
Runtime config создаётся только вручную из config.example.toml.
5. Целостность перенесённого артефакта
Для пакета, собранного из 3757302 до добавления этого отчёта, Windows вычислил SHA-256:
9ffcc8f84e01ddf5b365d37d99c3efdbe0a130aa2017ba63476697bdaa216c4c
Это значение полностью совпало с записью в созданном на builder файле SHA256SUMS. Регистр шестнадцатеричных символов на значение digest не влияет.
Результат: перенос .deb через scp не повредил артефакт.
Документы docs/*.md входят в .deb, поэтому package, пересобранный после добавления этого отчёта, закономерно получит другой SHA-256. Его checksum должен проверяться по новому SHA256SUMS; изменение package hash само по себе не означает изменение бинарников.
6. Реальный smoke-тест swapon
На Debian 13 с util-linux 2.41.5 выполнен новый документированный вызов:
swapon --show=NAME,TYPE,SIZE,PRIO --bytes --raw --noheadings
Он успешно вернул ожидаемые четыре поля. После переустановки пакета команда status также успешно прочитала active swap, а foreign-swap fail-closed сохранился.
Результат: PASS.
Исправление проверено не только unit/regression-тестом, но и реальным Debian runtime.
Для расширенной ручной диагностики использовалась форма:
swapon --show=NAME,TYPE,SIZE,USED,PRIO,UUID
7. AWG discovery и topology parser
На реальном AmneziaWG 2.0 runtime успешно обнаружены:
- container;
- network namespace;
- interface
awg0; - 28 server-side peers.
Все server peer routes были корректно распознаны как IPv4 /32.
Это подтверждает работоспособность production parser не только на unit fixtures, но и на реальном выводе AWG. Поддерживаемый harness topology остаётся IPv4-only /32.
Результат: PASS.
8. Legacy traffic topology — fail-closed ownership
Перед применением 0.3.1 в network namespace существовала topology старой версии:
- root HTB на
awg0; ifb0;- per-peer HTB classes;
fq_codel;- legacy per-peer
u32filters; - peer limit 60 Mbit/s.
Legacy ifb0 не имел ownership marker:
alias awg2-harness:traffic
Команда apply-limits отказалась удалять такой IFB с ошибкой refusing to delete unowned IFB.
Результат: PASS.
Это подтверждает safety invariant: существования интерфейса с подходящими именем и типом недостаточно для destructive cleanup; требуется explicit ownership marker.
9. Traffic topology 0.3.1
После ручного удаления legacy topology apply-limits успешно создал новую topology. Повторный apply-limits завершился без ошибки и не изменил healthy state.
Подтверждено:
ifb0создан с aliasawg2-harness:traffic;- egress root: HTB;
- ingress redirect присутствует;
- IFB root: HTB;
- root rate: 500 Mbit/s;
- peer rate: 50 Mbit/s;
- peer ceil: 50 Mbit/s;
rate == ceilдля всех peers;- leaf qdisc:
fq_codel; - egress per-peer filters:
flower pref 10,dst_ip <peer>/32; - ingress per-peer filters:
flower pref 10,src_ip <peer>/32.
После reconciliation status сообщил Traffic actual: drift: no для всех 28 peers.
Результат: PASS.
10. Ingress redirect
На ingress awg0 реально присутствовал единственный catch-all u32 filter с действием:
mirred Egress Redirect to device ifb0
Таким образом, design contract сохранён:
u32используется только для ingress redirect;- per-peer classification выполняется через
flower.
Результат: PASS.
11. Peer traffic counters
Для peer 10.8.1.2 использовался HTB class 1:21.
Перед дополнительной генерацией трафика:
- 20 packets;
- 1680 bytes.
После ещё 20 ICMP packets:
- 40 packets;
- 3360 bytes.
status также показал для 10.8.1.2 значение Egress packets = 40.
Результат: PASS.
Это подтверждает, что peer counters читаются из фактических HTB class statistics. Отсутствие ICMP reply не является ошибкой harness: внешний VPN dataplane тестового AWG был нерабочим.
12. Host firewall
IPv4 и IPv6 проверены отдельно.
В обоих случаях harness установил единственный owned jump:
awg2-harness:host-firewall -> AWG2H_A
Managed chain содержит:
- loopback ACCEPT;
- RELATED/ESTABLISHED ACCEPT;
- TCP/2323 ACCEPT;
- ICMP или IPv6-ICMP ACCEPT;
- terminal DROP.
Built-in INPUT policy при этом остаётся ACCEPT.
Это ожидаемая архитектура: политика input_policy = "drop" реализуется terminal DROP внутри owned managed chain, а не изменением глобальной policy чужой INPUT chain.
После применения Host firewall: drift: no.
Результат: PASS.
13. Docker / AWG UDP port contract
При expected_host_udp_port = 2053 runtime сообщил:
- Docker published UDP: 2053;
- AWG listen UDP: 2053;
- host IPv4 binding:
0.0.0.0:2053; - host IPv6 binding:
[::]:2053; port_contract: ok.
Наличие host IPv6 Docker publication не означает поддержку IPv6 server-peer topology внутри AWG tunnel.
Результат: PASS.
14. Anti-torrent guard
Anti-torrent guard был применён повторно без ошибки.
В Amnezia network namespace подтверждены:
- harness-owned nftables table;
- IPv4 dynamic set;
- peer CIDR
10.8.1.0/24; ct state new;- threshold
ct count over 500; - named drop counter.
После применения Anti-torrent: drift: no.
Conntrack count читается из Amnezia network namespace, global max — с host.
Результат: PASS.
15. Network tuning и BBR-off policy
До reconcile присутствовал drift от старого persisted state. После apply-network-tuning получено:
- persisted sysctl matches desired state;
- obsolete harness BBR modules-load file отсутствует;
rmem_max = 67108864;wmem_max = 67108864;ip_forward = 1;drift: no.
Тестовый host уже имел runtime net.ipv4.tcp_congestion_control = bbr при конфигурации tcp_bbr = "off".
После reconcile runtime BBR остался активным, одновременно status сообщил:
bbr_desired: no;bbr_runtime_active: yes;drift: no.
Это ожидаемый policy contract. off означает, что harness не требует и не персистит BBR. Он не выполняет принудительное переключение существующего host TCP congestion control на другой алгоритм.
Результат: PASS.
16. IFB IPv6 observation
После создания IFB kernel автоматически назначил link-local IPv6 fe80::/64 и соответствующий link-local route. На IFB наблюдалось несколько direct packets.
На peer IPv4 path признаков обхода HTB не обнаружено: egress peer class counters корректно увеличивались при IPv4 traffic.
Эта проверка не заменяет production throughput test.
17. Swap — foreign ownership safety
На test host уже существовал /swapfile и запись в /etc/fstab, но ownership record новой версии harness отсутствовал.
ensure-swap дважды отказался изменять файл:
/swapfile already exists and there is no record of awg2-harness creating it; refusing to touch it
Результат: PASS для fail-closed ownership.
Подтверждено, что harness не усыновляет и не изменяет произвольный существующий swapfile только по совпадению path. После исправления argv swapon эта защита повторно проверена на ревизии 3757302 и сохранилась.
Положительный сценарий создания нового owned swapfile, resize/replacement и rollback в этом test run не выполнялся. Он остаётся частью clean-host production acceptance.
18. Reboot scheduler
awg2-reboot-scheduler.service успешно:
- стартовал;
- прочитал production-format config;
- выбрал случайный reboot timestamp внутри окна
01:00–02:00 UTC; - оставался active;
- штатно остановился по
systemctl stop.
Результат: PASS.
Фактическая перезагрузка в рамках этого synthetic test намеренно не ожидалась.
19. Daemon startup и periodic recovery
Попытка запуска awg2-harness.service завершилась fail-closed на startup swap reconcile, поскольку существующий /swapfile не принадлежал текущему harness.
Это ожидаемая защитная реакция, а не ошибка traffic reconciliation. Из-за завершения daemon последующий intentional deletion root HTB не мог быть автоматически восстановлен.
Статус:
daemon periodic drift recovery: NOT RUN
Причина:
BLOCKED BY EXPECTED FOREIGN-SWAP OWNERSHIP FAILURE
Для отдельного daemon recovery test необходимо использовать clean/owned swap state либо временно отключить [swap].
20. Сводный результат synthetic run
| Контур | Статус |
|---|---|
| Debian 13 build gate | PASS |
.deb packaging |
PASS |
| Artifact transfer integrity | PASS |
| Config validation | PASS |
| AWG runtime discovery | PASS |
| AWG 2.0 peer parser | PASS |
IPv4 /32 topology |
PASS |
| Foreign IFB fail-closed | PASS |
| HTB creation | PASS |
rate == ceil |
PASS |
fq_codel leaves |
PASS |
flower pref 10 |
PASS |
ingress u32 -> mirred -> IFB |
PASS |
| HTB peer counters | PASS |
repeated apply-limits |
PASS |
| IPv4 host firewall | PASS |
| IPv6 host firewall | PASS |
| Docker/AWG UDP contract | PASS |
| Anti-torrent / conntrack | PASS |
| Network tuning | PASS |
| BBR-off policy semantics | PASS |
Documented swapon argv on util-linux 2.41.5 |
PASS |
| Foreign swap protection | PASS |
| Reboot scheduler | PASS |
| Daemon periodic self-healing | NOT RUN |
| Owned swap create/resize | NOT RUN |
| Actual 50 Mbit throughput cap | NOT RUN |
| End-to-end VPN | NOT RUN |
| AWG 3.1 production acceptance | NOT RUN |
21. Что не доказал synthetic run
Не проверены:
- реальная пропускная способность peer под длительной нагрузкой;
- фактический hard cap около 50 Mbit/s на живом VPN client;
- simultaneous multi-peer fairness/latency;
- bidirectional ingress load;
- полноценный AWG handshake;
- end-to-end VPN connectivity;
- production AWG 3.1 runtime;
- positive swap create/resize/replacement path;
- periodic daemon self-healing.
Эти проверки остаются обязательной частью clean production AWG 3.1 acceptance.
22. Итог synthetic run
Для полного synthetic runtime-прогона на 7390d1f и отдельной финальной build/runtime-проверки swap delta на 3757302 подтверждены:
- Debian 13 build/package viability;
- целостность передачи собранного артефакта;
- AWG runtime discovery;
- IPv4 peer topology parser;
- ownership fail-closed;
- HTB/fq_codel/flower traffic topology;
- ingress IFB redirect;
- peer HTB counters;
- IPv4/IPv6 host firewall;
- Docker/AWG UDP port contract;
- nftables anti-torrent guard;
- network tuning reconciliation;
- reboot scheduler;
- документированный
swaponargv на реальном util-linux 2.41.5; - foreign swap protection после исправления.
Synthetic runtime validation: PASS for tested components.
Production AWG 3.1 acceptance в этом synthetic run: NOT RUN.
Окончательный production GO требует выполнения ACCEPTANCE_CHECKLIST.md на clean Debian 13 host с рабочим AWG 3.1 и реальным client traffic.
Требуемый clean production acceptance был выполнен 2026-08-29; результаты приведены в следующем разделе.
23. Clean production acceptance — Debian 13 / AmneziaWG 3.1
Дата проверки: 2026-08-29
Проверенный release artifact:
- tag:
v0.3.1; - package:
awg2-harness_0.3.1_amd64.deb; - SHA256:
90dc8bb85f60740ca3358e40c31592b5165e250f878169ad6d05bdee3656f1b8.
Проверка выполнена после публикации релиза. Этот раздел фиксирует post-release evidence и не изменяет tag или опубликованный artifact v0.3.1.
23.1. Окружение
- Debian GNU/Linux 13.6 (trixie);
- amd64;
- kernel:
6.12.105+deb13-amd64; - Docker:
26.1.5+dfsg1; - container:
amnezia-awg2; - AmneziaWG tools:
v3.1.20260812; - AWG interface:
awg0; - AWG peer CIDR:
10.8.1.0/24; - server peer
AllowedIPs: IPv4/32; - host UDP port:
2053; - SSH port:
2323.
Production limits:
- per-peer limit:
60mbit; - root rate:
600mbit; - anti-torrent connection limit:
500per peer.
23.2. Clean installation
До установки AWG2 Harness:
/etc/awg2-harnessотсутствовал;- harness iptables/ip6tables rules отсутствовали;
- harness nftables table отсутствовала;
ifb0отсутствовал;- swap отсутствовал;
- harness sysctl persistence files отсутствовали.
Установка release package завершилась успешно.
После установки:
- production config автоматически не создавался;
awg2-harness.serviceбылdisabled/inactive;awg2-reboot-scheduler.serviceбылdisabled/inactive.
Результат: PASS.
23.3. AmneziaWG 3.1 discovery
Runtime discovery определил:
- container
amnezia-awg2; - interface
awg0; - listen port
2053; - peer
10.8.1.1/32.
validate-config и validate-runtime завершились успешно.
Docker UDP contract:
0.0.0.0:2053;[::]:2053;- inner AWG listen port
2053; port_contract: ok.
Результат: PASS.
23.4. Swap — clean positive path
На исходном сервере active swap отсутствовал.
ensure-swap создал managed /swapfile:
- size: 2048 MiB;
- mode:
0600; - priority:
1; /etc/fstab:/swapfile none swap sw,pri=1 0 0;vm.swappiness = 1;- ownership record создан;
status:drift: no.
Повторный ensure-swap сохранил тот же inode, размер и содержимое /etc/fstab.
Результат: PASS.
23.5. Network tuning
До reconciliation:
net.core.rmem_max = 212992;net.core.wmem_max = 212992;net.ipv4.ip_forward = 1;- congestion control:
cubic.
После apply-network-tuning:
net.core.rmem_max = 67108864;net.core.wmem_max = 67108864;net.ipv4.ip_forward = 1;- persisted config совпадает с desired state;
tcp_bbr = "off"не включает и не персистит BBR;- runtime congestion control остался
cubic; drift: no.
Результат: PASS.
23.6. Traffic shaping — clean AWG 3.1
На исходном awg0 присутствовал только штатный root fq_codel. ifb0, HTB classes и peer filters отсутствовали.
Первый apply-limits построил managed topology. Повторный apply-limits был идемпотентным.
Получено:
- egress HTB root:
600Mbit; - ingress IFB HTB root:
600Mbit; - peer
10.8.1.1:- egress:
60Mbit/60Mbit; - ingress:
60Mbit/60Mbit;
- egress:
- per-peer egress filter:
flower pref 10, destination peer IPv4; - per-peer ingress filter:
flower pref 10, source peer IPv4; - AWG ingress redirect:
u32 -> mirred -> ifb0; - IFB alias:
awg2-harness:traffic; - leaf qdisc:
fq_codel; status:drift: no.
Результат: PASS.
23.7. Live peer and traffic classification
После подключения реального AmneziaWG 3.1 клиента:
- peer определён как
online; - endpoint определён;
- latest handshake корректно читается;
- AWG RX/TX корректно читаются;
- egress class counter растёт;
- ingress class counter растёт.
direct_packets_stat не рос пропорционально пользовательской нагрузке; IPv4 peer traffic проходил через managed peer classes.
Результат: PASS.
23.8. Real bandwidth enforcement
Speedtest через реального клиента:
- configured peer ceiling:
60 Mbit/s; - download:
57.81 Mbit/s; - upload:
55.26 Mbit/s.
Во время нагрузки:
- egress и ingress peer counters существенно выросли;
- HTB
overlimitsсущественно выросли; - topology сохранила
drift: no.
Результат: PASS.
23.9. Host firewall
Применены managed IPv4 и IPv6 INPUT chains.
Разрешены:
- loopback;
- ESTABLISHED/RELATED;
- TCP
2323; - ICMP / IPv6 ICMP.
Завершающее действие owned chain — DROP. Built-in INPUT policy не изменялась. Docker-managed FORWARD rules harness не изменял.
После применения подтверждены:
- новая SSH-сессия на TCP/2323;
- новый AWG handshake;
- работающий VPN dataplane;
Host firewall: drift: no;port_contract: ok.
Результат: PASS.
23.10. Anti-torrent guard
В AWG network namespace создана table inet awg2_harness.
Production rule использует:
- peer CIDR
10.8.1.0/24; ct state new;- dynamic IPv4 set;
ct count over 500;- named drop counter;
- terminal drop.
Inspector:
- enabled: true;
- max_connections_per_peer: 500;
drift: no.
Threshold load-test выше 500 соединений на production намеренно не выполнялся.
Результат: PASS для control-plane и production configuration.
23.11. Daemon startup and self-healing
После включения awg2-harness.service:
- service: active;
- startup network tuning reconcile: ok;
- startup swap reconcile: ok;
- startup traffic reconcile: ok;
- startup firewall reconcile: ok.
Для проверки periodic self-healing вручную удалён root HTB qdisc на awg0.
Сразу после удаления inspector зарегистрировал:
missing egress root htb qdisc
Через следующий daemon reconciliation root HTB был автоматически восстановлен, peer classes и filters появились снова, Traffic actual: drift: no.
Результат: PASS.
23.12. Reboot scheduler
awg2-reboot-scheduler.service:
- enabled;
- active;
- планирует reboot внутри configured UTC window
01:00–02:00.
Пример после production reboot:
planned_reboot_utc=2026-08-30T01:00:38Z
Фактического ожидания scheduler-triggered reboot в этом validation run не выполнялось.
Результат: PASS для startup/planning.
23.13. Reboot recovery
Выполнен ручной reboot production host.
После загрузки:
- Docker active;
amnezia-awg2active;awg2-harness.serviceactive;awg2-reboot-scheduler.serviceactive;- swap active с тем же UUID, размером 2 GiB и priority 1;
- network tuning:
drift: no; - traffic topology:
drift: no; - host firewall:
drift: no; - anti-torrent:
drift: no; - Docker/AWG UDP contract:
ok.
AWG client автоматически выполнил новый handshake после reboot, peer определён как online, traffic counters росли.
Результат: PASS.
23.14. Наблюдение за Docker FORWARD state
До reboot status показывал host_forward_policy_drop: true, после reboot — false. При этом docker_forward_rules_present: true, VPN dataplane после reboot работал, а port_contract оставался ok.
Harness по контракту не управляет built-in FORWARD policy и Docker-managed FORWARD rules. Наблюдаемое изменение host state после reboot не классифицируется как drift или regression AWG2 Harness.
23.15. Сводный результат clean production acceptance
| Контур | Статус |
|---|---|
| Debian 13 clean host | PASS |
Release .deb + SHA256 |
PASS |
| Clean package installation | PASS |
| AWG 3.1 discovery | PASS |
| AWG 3.1 real dataplane | PASS |
| UDP 2053 contract | PASS |
| Owned swap creation | PASS |
| Swap persistence / idempotence | PASS |
| Network tuning | PASS |
| HTB 600 Mbit root | PASS |
| 60 Mbit per-peer egress | PASS |
| 60 Mbit per-peer ingress | PASS |
| Flower classification | PASS |
| IFB ingress | PASS |
fq_codel |
PASS |
| No material direct bypass | PASS |
| Real download: 57.81 Mbps | PASS |
| Real upload: 55.26 Mbps | PASS |
| IPv4 host firewall | PASS |
| IPv6 host firewall | PASS |
| New SSH through firewall | PASS |
| New AWG handshake through firewall | PASS |
| Docker forwarding preserved | PASS |
Anti-torrent / ct count over 500 configuration |
PASS |
| Anti-torrent inspection | PASS |
| Daemon startup | PASS |
| Startup reconciliation | PASS |
| Periodic self-healing | PASS |
| Manual drift recovery | PASS |
| Service enablement | PASS |
| Manual reboot recovery | PASS |
| Post-reboot AWG handshake | PASS |
| Post-reboot traffic shaping | PASS |
| Post-reboot firewall | PASS |
| Post-reboot anti-torrent | PASS |
| Post-reboot swap | PASS |
| Post-reboot network tuning | PASS |
| Reboot scheduler startup/planning | PASS |
| Actual scheduled-time reboot | NOT OBSERVED |
| Multi-peer production load | NOT RE-RUN |
Production-critical функции, проверенные на реальном сервере:
- package installation;
- runtime discovery;
- swap lifecycle;
- network tuning;
- per-peer bidirectional shaping;
- real 60 Mbit/s enforcement;
- host firewall;
- Docker/AWG port contract;
- anti-torrent control-plane;
- daemon startup reconciliation;
- periodic drift self-healing;
- reboot persistence and recovery;
- reboot scheduler startup/planning.
Ограничения текущего validation:
- scheduler-triggered reboot не ожидался до фактического времени;
- multi-peer production load-test отдельно не повторялся;
- anti-torrent threshold выше 500 не создавался искусственно.
Эти ограничения зафиксированы как непроверенные сценарии и не признаны blockers для перевода пользователей на сервер: запуск и планирование scheduler проверены, обычный reboot и полное восстановление системы проверены отдельно.
Clean production acceptance: PASS.
Production GO: подтверждён.