Files
AWG2_harness/docs/VALIDATION_0.3.1.md
T

418 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AWG2 Harness 0.3.1 — отчёт о валидации
Дата проверки: 2026-08-28
## 1. Назначение
Этот документ фиксирует фактически выполненные build-, package- и runtime-проверки AWG2 Harness 0.3.1 по сохранённым локальным логам оператора.
Он не заменяет [`ACCEPTANCE_CHECKLIST.md`](ACCEPTANCE_CHECKLIST.md). Его задача — сохранить доказанный на практике baseline:
- какая ревизия проверялась;
- в каком окружении выполнялись проверки;
- какие свойства подтверждены реальным Linux runtime;
- какие проверки были negative/fail-closed;
- какие сценарии остаются до 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 выполнен новый документированный вызов:
```bash
swapon --show=NAME,TYPE,SIZE,PRIO --bytes --raw --noheadings
```
Он успешно вернул ожидаемые четыре поля. После переустановки пакета команда `status` также успешно прочитала active swap, а foreign-swap fail-closed сохранился.
Результат: PASS.
Исправление проверено не только unit/regression-тестом, но и реальным Debian runtime.
Для расширенной ручной диагностики использовалась форма:
```bash
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 `u32` filters;
- 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` создан с alias `awg2-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. Сводный результат
| Контур | Статус |
| --- | --- |
| 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. Что этим test 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 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;
- документированный `swapon` argv на реальном util-linux 2.41.5;
- foreign swap protection после исправления.
**Synthetic runtime validation: PASS for tested components.**
**Production AWG 3.1 acceptance: NOT RUN.**
Окончательный production GO требует выполнения [`ACCEPTANCE_CHECKLIST.md`](ACCEPTANCE_CHECKLIST.md) на clean Debian 13 host с рабочим AWG 3.1 и реальным client traffic.