feat(cli,tunnel,docs): full Windows support — OS routes + wintun audit

Windows is now first-class for client use:

- aura-cli::os_routes Windows path is no longer a stub. Real install via
  `route ADD <net> MASK <mask> <gw> METRIC 1` for DIRECT bypass (rollback:
  `route DELETE ...`) and `netsh interface ipv4 add route <cidr> "Aura"
  <tun_local_ip> store=active` for VPN default/CIDR (rollback: `netsh ...
  delete route ...`). Default-gateway detection by parsing `route print 0`
  output via parse_windows_route_print_default; rejects `On-link` rows. Dry
  run works on every host.
- aura-tunnel::tun wintun audit fixed a real bug: AuraTun was holding only
  Arc<Session> while Session does NOT keep Arc<Adapter> alive (only the
  Wintun DLL handle). On Drop the adapter was being closed under the
  session. Fixed by adding _adapter: Arc<wintun::Adapter> to AuraTun, with
  field order ensuring Session is dropped before Adapter so end-session
  precedes close-adapter. Also wired mtu into write_packet (hard limit) +
  read_packet (warn).
- Cross-compile verified: cargo check --target x86_64-pc-windows-gnu
  --workspace and clippy on the windows target are both clean (added
  mingw-w64 + x86_64-pc-windows-gnu via rustup).
- docs/deployment.md: §6 updated (Windows OS-routes now Done), new §8
  «Windows как клиент» with download wintun.dll, Admin run, [tunnel.os_routes]
  enabled, known no-ops (run_as, [server.nat]).

9 new tests (7 parser/plan/undo unit + 1 windows dry-run integration + 1
existing). Workspace: 293 tests passed (+9), clippy -D warnings clean, fmt
clean. macOS host + windows-gnu cross-target both green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
xah30
2026-05-27 21:14:23 +03:00
parent 1893e24174
commit 5ea643a9e5
4 changed files with 809 additions and 37 deletions
+188 -4
View File
@@ -426,12 +426,27 @@ aura status
слой QUIC и TCP использует настоящий CA-trusted сертификат вместо self-signed Aura cert;
внутренний Aura mutual-auth handshake продолжает аутентификацию против Aura CA.
### v3.3 — Windows-as-client стал first-class
-**Windows OS-маршруты реализованы.** `[tunnel.os_routes] enabled = true` теперь работает
на Windows: `route ADD <net> MASK <mask> <gw> METRIC 1` для DIRECT-обходов, `netsh interface
ipv4 add route <prefix> "Aura" <tun_local_ip> store=active` для VPN-маршрутов через wintun-
адаптер. Дефолт-GW автодетектится через `route print 0`. Rollback подменяет `ADD``DELETE` и
`add``delete` на обоих путях. Подробности и пошаговый запуск — в §8.
-**wintun audit.** Найден и устранён баг: `Arc<wintun::Adapter>` больше не дропается раньше
`Session` (поле `_adapter` в `AuraTun` держит адаптер живым на всё время сессии).
-**Cross-compile.** Весь workspace проверен под `cargo check --target
x86_64-pc-windows-gnu` без warnings.
### Остающиеся честные ограничения
- **TUN всё ещё требует root** для **создания** интерфейса (это OS-уровень). Privilege drop
минимизирует окно работы под root, но саму операцию обойти нельзя.
- **IPv6 в OS-маршрутах и iptables MASQUERADE** не реализован — только IPv4 (план v3.3).
- **Windows OS-маршруты** — заглушка с лог-warning (план v3.3). Windows admin pipe **работает**.
- **TUN всё ещё требует root / Администратор** для **создания** интерфейса (это OS-уровень). На
Linux/macOS privilege drop минимизирует окно работы под root; на Windows аналога нет — клиент
работает от Администратора до выхода (warning в логе).
- **IPv6 в OS-маршрутах и iptables MASQUERADE** не реализован — только IPv4 (план v3.4).
- **Windows-as-server не первоклассный.** `[server.nat]` (IP-форвардинг + MASQUERADE) на
Windows не реализован; роль сервера / relay лучше держать на Linux/macOS. Windows клиент
работает с любым сервером.
- **Нативного Go-клиента для телефона нет** — через sing-box (Option B нативный Go-outbound,
по `protocol.md` + KAT из Rust, см. [`sing-box.md`](sing-box.md)). Сейчас доступен только
десктоп-клиент / process-bridge. Это явно исключённый из v2 пункт.
@@ -679,3 +694,172 @@ exit, и они не пересекаются (см. `aura provision-client --ci
Перевыпускать сертификаты двух хопов не нужно — они остаются те же, меняется только wire-адрес
entry-узла. На сертификате entry-сервера должен быть SAN, совпадающий с `[client] sni`
(см. `aura pki issue-server --domain relay.example.ru`).
---
## 8. Windows как клиент
Windows-клиент стал first-class в v3.3. Сервер на Windows не поддерживается на уровне
автонастройки сети — `[server.nat]` (IP-форвардинг + MASQUERADE) реализован только для
Linux/macOS. Эта секция — про **клиент**.
### 8.1. Требования
- Windows 10 / 11 (или Server 2019+) с правами **Администратора** для процесса `aura.exe` —
поднятие wintun-адаптера и программирование таблицы маршрутов требуют привилегий.
- **wintun.dll** рядом с `aura.exe`. Скачать с официального сайта
[https://www.wintun.net/](https://www.wintun.net/) (драйвер от автора WireGuard);
распаковать `wintun/bin/amd64/wintun.dll` в каталог `aura.exe`.
### 8.2. Сборка / получение бинаря
Если у вас есть Rust toolchain на Windows — `cargo build --release` соберёт `target\release\aura.exe`.
С macOS / Linux можно собрать кросс-компиляцией (нужен mingw-w64):
```bash
rustup target add x86_64-pc-windows-gnu
# (на macOS) brew install mingw-w64
cargo build --release --target x86_64-pc-windows-gnu
# -> target/x86_64-pc-windows-gnu/release/aura.exe
```
### 8.3. PKI и провижининг
Команды `aura.exe pki ...` и `aura.exe provision-client ...` работают идентично Unix-версии
(см. §2.2). Бандл для клиента — те же три PEM-файла (`ca.crt`, `client.crt`, `client.key`)
плюс `client.toml`. PowerShell-форма:
```powershell
.\aura.exe pki init --ca-name "Aura Root CA" --out C:\ProgramData\Aura\pki
.\aura.exe pki issue-server --domain vpn.example.com --out C:\ProgramData\Aura\pki\server `
--ca C:\ProgramData\Aura\pki
.\aura.exe provision-client --id laptop-1 --out C:\Users\me\.aura
```
### 8.4. `client.toml` на Windows
Раскладка идентична §4.1. Имя TUN — это **отображаемое имя wintun-адаптера**: указанное в
`tun_name` имя становится `Display Name` адаптера в Device Manager (а также используется в
командах `netsh interface ipv4 add route ... "Aura"` — см. §8.5).
```toml
[client]
name = "laptop"
server_addr = "203.0.113.10:443"
sni = "vpn.example.com"
# run_as на Windows — no-op (нет аналога setresuid; warning в логе).
[pki]
ca_cert = "C:\\Users\\me\\.aura\\ca.crt"
cert = "C:\\Users\\me\\.aura\\client.crt"
key = "C:\\Users\\me\\.aura\\client.key"
[tunnel]
tun_name = "Aura" # имя wintun-адаптера; то же имя используется в netsh-командах ниже
local_ip = "10.7.0.2"
prefix = 24
mtu = 1420
[tunnel.split]
default = "VPN"
[[tunnel.split.direct]]
cidr = "192.168.0.0/16"
# v3.3: OS-уровень kill-switch теперь работает на Windows.
[tunnel.os_routes]
enabled = true
# Опционально: pin gateway + interface IP (читается `route print 0` если не задано).
# gateway = "192.168.1.1"
# egress_iface = "192.168.1.42"
[transport]
order = ["udp", "tcp", "quic"]
udp_port = 443
tcp_port = 443
quic_port = 444
```
### 8.5. Что делает `[tunnel.os_routes]` на Windows
На Linux/macOS клиент программирует системную таблицу маршрутов через `ip` / `route`. На
Windows — через `route ADD` (для DIRECT-обходов через исходный default-GW) и `netsh interface
ipv4 add route` (для VPN-маршрутов через wintun-адаптер).
**Auto-detect default GW:** клиент выполняет `route print 0` и парсит row `0.0.0.0 0.0.0.0
<gw> <interface_ip> <metric>` из IPv4 Active Routes. Если автодетект не сработал (например,
у машины несколько NIC и нет default'а в IPv4-таблице) — задайте `gateway` и `egress_iface`
явно в `[tunnel.os_routes]`. На Windows `egress_iface` — это **IP** upstream-интерфейса
(не имя), как в колонке `Interface` в `route print`.
**Что реально выполняется** (с пулом DIRECT `192.168.0.0/16` и default = VPN):
```
netsh interface ipv4 add route 0.0.0.0/0 "Aura" 10.7.0.2 store=active
route ADD 192.168.0.0 MASK 255.255.0.0 192.168.1.1 METRIC 1
```
**Что выполняется при выходе клиента** (Drop порядка LIFO):
```
route DELETE 192.168.0.0 MASK 255.255.0.0
netsh interface ipv4 delete route 0.0.0.0/0 "Aura"
```
`store=active` указывает Windows не сохранять маршрут в персистентном store — он привязан к
TUN, который исчезает на выходе клиента. Параметр `METRIC 1` обеспечивает приоритет
DIRECT-обхода над любыми существующими маршрутами с большей метрикой.
### 8.6. Запуск
PowerShell как Администратор:
```powershell
cd C:\Aura
.\aura.exe client --config .\client.toml
```
В логе при успехе:
```
INFO connected and authenticated to server peer=Some("vpn.example.com") mode=udp
INFO OS-level split-tunnel routes installed (DIRECT traffic now bypasses the TUN)
INFO running: netsh interface ipv4 add route 0.0.0.0/0 "Aura" 10.7.0.2 store=active
INFO running: route ADD 192.168.0.0 MASK 255.255.0.0 192.168.1.1 METRIC 1
```
Прервать через `Ctrl+C` — выводящийся guard корректно вызывает `route DELETE` / `netsh ...
delete route` и затем закрывает wintun-сессию + адаптер (см. §8.7).
### 8.7. Cleanup на Windows (что происходит при остановке клиента)
Порядок dropping:
1. **OsRouteGuard::drop** — выполняет rollback-команды в LIFO-порядке (`route DELETE ...`,
затем `netsh ... delete route ...`). Ошибки логируются warn-ом, дальнейший rollback
продолжается — один сбойный шаг не остановит зачистку остальных маршрутов.
2. **wintun::Session::drop**`WintunEndSession` завершает сессию (закрывает ring buffer).
3. **wintun::Adapter::drop**`WintunCloseAdapter` снимает адаптер с системы. Drop порядка
полей в `AuraTun` гарантирует, что Session завершается до Adapter (поле `inner` объявлено
раньше `_adapter`).
Если процесс упал без graceful shutdown (kill -9 / BSOD): wintun-адаптер останется
зарегистрированным в системе, и при следующем запуске `Adapter::create` найдёт его по имени и
переиспользует. Орфанных системных маршрутов в персистентном store не будет — все наши
маршруты идут через `store=active`, которые система очищает на reboot.
### 8.8. Известные ограничения Windows-клиента
- **`run_as`** на Windows — no-op. Аналога `setresuid` для безпрепятственного drop'а к
service-account во время работы нет; рекомендация — запустить `aura.exe` как Windows
Service от выделенной учётной записи (см. документацию `sc.exe create`), либо просто из
PowerShell-сессии Администратора.
- **`[server.nat]`** на Windows не реализован — Windows-as-server не первоклассный сценарий.
Используйте Linux/macOS для роли сервера / relay.
- **IPv6 routes** программируются через `netsh interface ipv6 add route` для VPN, но IPv6
DIRECT-обходы попадают в тот же `netsh ipv6` путь (а не в IPv4-only `route ADD`). Для
чистой IPv4-only установки это не имеет значения.
- **Mixed-mode** (часть транспортов в одну сеть, часть в другую) на Windows не тестировался
глубоко — `netsh ... store=active` маршруты могут конфликтовать с существующими VPN-
клиентами (WireGuard, OpenVPN) если те уже захватили default-route. Отключите конкурирующие
VPN перед запуском aura-клиента.