5ea643a9e5
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>
866 lines
49 KiB
Markdown
866 lines
49 KiB
Markdown
# Развёртывание Aura VPN
|
||
|
||
Этот документ — пошаговое руководство, по которому вы поднимаете сервер Aura на удалённой машине,
|
||
провижините на нём сертификат для клиента и подключаете клиент (десктоп) к этому серверу. Все
|
||
команды и поля конфигов взяты из фактического кода и поставляемых примеров в `config/`.
|
||
|
||
> Полезные сопутствующие документы: [`protocol.md`](protocol.md) (wire-протокол),
|
||
> [`pki.md`](pki.md) (CA и сертификаты), [`split-tunnel.md`](split-tunnel.md) (правила
|
||
> маршрутизации), [`sing-box.md`](sing-box.md) (интеграция с sing-box, план).
|
||
|
||
---
|
||
|
||
## 1. Обзор схемы
|
||
|
||
Сервер Aura на удалённой машине провижинит сертификат для клиента (десктопа или, в будущем,
|
||
телефона через sing-box), отдаёт клиенту бандл сертификатов и трастового якоря, и клиент
|
||
подключается к серверу по протоколу AuraVPN.
|
||
|
||
На проводе по умолчанию используется **собственный UDP-транспорт Aura с пост-квантовой
|
||
криптографией** (без QUIC и без внешнего TLS на основном пути); fallback'и — это TCP/443 и QUIC.
|
||
Всё рукопожатие пост-квантовое: **гибридное X25519 + ML-KEM-768** с взаимной X.509-аутентификацией.
|
||
Для данных используется AEAD **ChaCha20-Poly1305** с explicit-nonce. Обфускация — это паддинг
|
||
датаграмм до «корзин» размера, характерных для HTTPS.
|
||
|
||
```
|
||
[клиент-десктоп] [удалённый сервер aura]
|
||
client.toml + PEM-бандл server.toml + PKI (CA + server leaf)
|
||
| |
|
||
| UDP (основной) / TCP/443 / QUIC |
|
||
| гибридное PQ-рукопожатие |
|
||
| ChaCha20-Poly1305 |
|
||
+--------------------------------------->
|
||
AuraVPN
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Сервер (удалённый хост)
|
||
|
||
### 2.1. Установка бинаря
|
||
|
||
В корне репозитория:
|
||
|
||
```bash
|
||
cargo build --release
|
||
# -> target/release/aura
|
||
```
|
||
|
||
Скопируйте получившийся бинарь `target/release/aura` на сервер (например в `/usr/local/bin/aura`)
|
||
либо соберите его прямо на сервере (требуется Rust toolchain).
|
||
|
||
### 2.2. Поднять PKI
|
||
|
||
Эти три команды создают CA и выпускают листовые сертификаты для сервера и клиента. Все они
|
||
проверены против реализации в `crates/aura-pki/src/{ca,cert,store}.rs` и
|
||
`crates/aura-cli/src/pki.rs`.
|
||
|
||
```bash
|
||
# 1) Создать CA Aura.
|
||
aura pki init --ca-name "Aura Root CA" --out /etc/aura/pki
|
||
# -> /etc/aura/pki/ca.crt
|
||
# -> /etc/aura/pki/ca.key # секрет, защищайте правами файловой системы
|
||
|
||
# 2) Выпустить сертификат сервера. --domain должен совпадать с тем именем,
|
||
# которое клиент будет ожидать в [client] sni (это же имя проверяется по SAN).
|
||
aura pki issue-server \
|
||
--domain vpn.example.com \
|
||
--out /etc/aura/pki/server \
|
||
--ca /etc/aura/pki
|
||
# -> /etc/aura/pki/server/server.crt
|
||
# -> /etc/aura/pki/server/server.key # секрет
|
||
|
||
# 3) Выпустить сертификат клиента (по одному на устройство).
|
||
# --id становится Common Name'ом и проверенным peer_id, который видит сервер.
|
||
aura pki issue-client \
|
||
--id phone-1 \
|
||
--out /etc/aura/clients/phone-1 \
|
||
--ca /etc/aura/pki
|
||
# -> /etc/aura/clients/phone-1/client.crt
|
||
# -> /etc/aura/clients/phone-1/client.key # секрет
|
||
```
|
||
|
||
Подробности (включая `aura pki revoke` / `list`) — см. [`pki.md`](pki.md).
|
||
|
||
### 2.3. `server.toml`
|
||
|
||
Раскладка ниже взята из `config/server.toml.example` и поставляемых serde-структур
|
||
(`crates/aura-cli/src/config.rs`). Скопируйте пример и поправьте под себя.
|
||
|
||
```toml
|
||
[server]
|
||
# Человекочитаемое имя (также внутренняя identity сервера в рукопожатии).
|
||
name = "aura-edge-1"
|
||
# UDP/TCP listen-сокет. ":443" мимикрирует под HTTPS; для его биндинга нужны привилегии.
|
||
# IP отсюда переиспользуется как listen-IP для каждого включённого транспорта.
|
||
listen = "0.0.0.0:443"
|
||
# Число accept-воркеров (в v1 носит совещательный характер).
|
||
workers = 4
|
||
|
||
[pki]
|
||
# Trust anchor (Aura CA) и листовая пара сервера, все PEM.
|
||
ca_cert = "/etc/aura/pki/ca.crt"
|
||
cert = "/etc/aura/pki/server/server.crt"
|
||
key = "/etc/aura/pki/server/server.key"
|
||
|
||
[tunnel]
|
||
# Адресный пул для клиентов; в v1 на сервере один общий TUN в этой сети.
|
||
pool_cidr = "10.7.0.0/24"
|
||
# MTU TUN-устройства (запас под QUIC + framing Aura).
|
||
mtu = 1420
|
||
# DNS, анонсируемый клиентам (в v1 информационно).
|
||
dns = "10.7.0.1"
|
||
|
||
[mimicry]
|
||
# Hostname, под который мимикрирует внешний TLS-слой (для QUIC).
|
||
sni = "cdn.example.com"
|
||
# Паддинг для размытия размеров пакетов под «корзины» HTTPS.
|
||
padding = true
|
||
|
||
[transport]
|
||
# Набор и порядок транспортов, биндящихся одновременно. UDP — основной; TCP/443 и
|
||
# QUIC (мимикрия H3) — fallback'и. При отсутствии всей секции включаются udp/tcp/quic
|
||
# на 443/443/444.
|
||
order = ["udp", "tcp", "quic"]
|
||
# UDP-транспорт и QUIC оба используют UDP, поэтому udp_port и quic_port ДОЛЖНЫ
|
||
# различаться. TCP может занимать тот же номер порта (другой протокол).
|
||
udp_port = 443
|
||
tcp_port = 443
|
||
quic_port = 444
|
||
# UDP: дополнять датаграммы до «корзин» размера HTTPS, чтобы размыть распределение размеров.
|
||
obfuscate = true
|
||
# TCP: добавлять минимальный HTTP/1.1-преамбулу (Host = [mimicry] sni), чтобы открытие
|
||
# выглядело как обычный HTTP.
|
||
masquerade = true
|
||
```
|
||
|
||
Пути могут начинаться с `~` (раскрывается в домашнюю директорию).
|
||
|
||
### 2.4. Сеть на сервере
|
||
|
||
#### Файрвол
|
||
|
||
Откройте те порты, которые перечислены у вас в `[transport]`. С приведённой выше конфигурацией:
|
||
|
||
- UDP **443** — основной транспорт Aura.
|
||
- TCP **443** — fallback Aura поверх TCP.
|
||
- UDP **444** — fallback Aura поверх QUIC.
|
||
|
||
Важно: UDP-транспорт и QUIC — это **оба UDP**, поэтому их порты обязательно должны различаться
|
||
(в примере: udp_port=443, quic_port=444). Конфиг-валидатор `transport.modes()` отвергает совпадение.
|
||
|
||
#### IP-форвардинг и NAT (для выхода клиентов в интернет)
|
||
|
||
В v1 настройка egress на стороне сервера — **обязательный ручной шаг**. На Linux:
|
||
|
||
```bash
|
||
# 1) Включить IP-форвардинг.
|
||
sudo sysctl -w net.ipv4.ip_forward=1
|
||
# (для постоянства добавьте в /etc/sysctl.conf или /etc/sysctl.d/*)
|
||
|
||
# 2) MASQUERADE для исходящего трафика клиентов на интернет-интерфейсе (например eth0).
|
||
sudo iptables -t nat -A POSTROUTING \
|
||
-s 10.7.0.0/24 \
|
||
-o eth0 \
|
||
-j MASQUERADE
|
||
```
|
||
|
||
Подставьте свой `pool_cidr` и имя интернет-интерфейса.
|
||
|
||
### 2.5. Запуск сервера
|
||
|
||
```bash
|
||
sudo aura server --config /etc/aura/server.toml
|
||
```
|
||
|
||
`sudo` нужен для создания TUN-устройства и для биндинга привилегированных портов (`:443`).
|
||
|
||
Можно опционально указать путь admin-сокета:
|
||
|
||
```bash
|
||
sudo aura server \
|
||
--config /etc/aura/server.toml \
|
||
--admin-socket /var/run/aura-admin.sock
|
||
```
|
||
|
||
По умолчанию admin-сокет — `/tmp/aura-admin.sock`.
|
||
|
||
---
|
||
|
||
## 3. Что вы получаете для клиента (бандл)
|
||
|
||
Отдайте клиенту **три PEM-файла**:
|
||
|
||
- `ca.crt` (из `/etc/aura/pki/ca.crt`) — trust anchor;
|
||
- `client.crt` (из `/etc/aura/clients/<id>/client.crt`) — листовой сертификат клиента;
|
||
- `client.key` (из `/etc/aura/clients/<id>/client.key`) — **секрет**, приватный ключ клиента.
|
||
|
||
И сообщите ему два параметра:
|
||
|
||
- **Адрес сервера** (например `203.0.113.10`).
|
||
- **`sni`** — то DNS-имя, которое вы указали в `aura pki issue-server --domain`. Оно же
|
||
ожидается в SAN серверного сертификата и проверяется в `verify_server_cert`.
|
||
|
||
Эти три файла плюс два параметра — это всё, что нужно клиенту для подключения.
|
||
|
||
---
|
||
|
||
## 4. Клиент (десктоп)
|
||
|
||
Путь для телефона — через sing-box; пока нативного клиента нет, см. раздел 6 ниже.
|
||
|
||
### 4.1. `client.toml`
|
||
|
||
Раскладка взята из `config/client.toml.example` и `crates/aura-cli/src/config.rs`.
|
||
|
||
```toml
|
||
[client]
|
||
# Человекочитаемое имя/id клиента.
|
||
name = "laptop"
|
||
# UDP-сокет сервера. IP отсюда переиспользуется как server-IP для каждого транспорта.
|
||
server_addr = "203.0.113.10:443"
|
||
# Внешний TLS-SNI (hostname-камуфляж), предъявляемый серверу. Он же проверяется
|
||
# внутри рукопожатия Aura против SAN серверного сертификата.
|
||
sni = "cdn.example.com"
|
||
|
||
[pki]
|
||
# Trust anchor (Aura CA) и листовая пара клиента, все PEM.
|
||
ca_cert = "~/.aura/ca.crt"
|
||
cert = "~/.aura/client.crt"
|
||
key = "~/.aura/client.key"
|
||
|
||
[tunnel]
|
||
# Запрошенное имя TUN-интерфейса (на macOS совещательно — ядро назначает utunN).
|
||
tun_name = "aura0"
|
||
# Локальный адрес для TUN и длина префикса.
|
||
local_ip = "10.7.0.2"
|
||
prefix = 24
|
||
# MTU TUN.
|
||
mtu = 1420
|
||
# DNS, используемый туннельным резолвером (в v1 информационно; реально используется
|
||
# системный резолвер).
|
||
dns = "10.7.0.1"
|
||
|
||
# Split-tunnel: действие по умолчанию плюс точечные правила.
|
||
[tunnel.split]
|
||
default = "VPN"
|
||
|
||
[[tunnel.split.direct]]
|
||
cidr = "192.168.0.0/16"
|
||
|
||
[[tunnel.split.direct]]
|
||
cidr = "10.0.0.0/8"
|
||
|
||
[[tunnel.split.direct]]
|
||
domain = "intranet.example.com"
|
||
|
||
# Более узкий префикс возвращает поддиапазон обратно в VPN (longest-prefix бьёт /8).
|
||
[[tunnel.split.vpn]]
|
||
cidr = "10.7.0.0/24"
|
||
|
||
[mimicry]
|
||
padding = false
|
||
|
||
[transport]
|
||
# Порядок fallback'а (handover), пробуется слева направо: первый удавшийся побеждает.
|
||
# При отсутствии всей секции — ["udp","tcp","quic"] на 443/443/444.
|
||
order = ["udp", "tcp", "quic"]
|
||
udp_port = 443
|
||
tcp_port = 443
|
||
quic_port = 444
|
||
obfuscate = true
|
||
masquerade = true
|
||
```
|
||
|
||
Подробности про `[tunnel.split]` — в [`split-tunnel.md`](split-tunnel.md).
|
||
|
||
### 4.2. Запуск клиента
|
||
|
||
```bash
|
||
sudo aura client --config client.toml
|
||
```
|
||
|
||
`sudo` нужен для поднятия TUN-устройства. Клиент:
|
||
|
||
1. Загружает PEM-файлы из `[pki]` и строит `aura_proto::ClientConfig`.
|
||
2. Строит таблицу маршрутизации из `[tunnel.split]`.
|
||
3. Дозванивается до сервера, перебирая транспорты в `[transport] order`
|
||
(handover UDP → TCP → QUIC); первый, который удался, побеждает.
|
||
4. Разрезолвит доменные правила split-tunnel'а в host-маршруты (best-effort).
|
||
5. Создаёт TUN, передаёт его маршрутизатору и начинает гонять трафик.
|
||
|
||
В логе при успехе вы увидите строку с выбранным транспортом:
|
||
|
||
```
|
||
INFO connected and authenticated to server peer=Some("cdn.example.com") mode=udp
|
||
```
|
||
|
||
`mode` принимает значения `udp`, `tcp` или `quic`.
|
||
|
||
### 4.3. Управление на лету
|
||
|
||
После запуска клиента (или сервера) admin-сокет позволяет менять правила и смотреть статус без
|
||
перезапуска:
|
||
|
||
```bash
|
||
# Добавить CIDR на лету.
|
||
aura route add --cidr 8.8.8.0/24 --action direct
|
||
|
||
# Завернуть домен через VPN.
|
||
aura route add --domain example.com --action vpn
|
||
|
||
# Перечислить правила.
|
||
aura route list
|
||
|
||
# Удалить CIDR-правило.
|
||
aura route remove --cidr 8.8.8.0/24
|
||
|
||
# Статус и счётчики.
|
||
aura status
|
||
# Aura tunnel status
|
||
# peer: cdn.example.com
|
||
# default: vpn
|
||
# rules: 2
|
||
# rx packets: 0
|
||
# tx packets: 0
|
||
```
|
||
|
||
Если сокет лежит не там, добавьте `--admin-socket <PATH>` к каждой команде. Полная спецификация
|
||
команд и wire-протокола admin'а — в [`split-tunnel.md`](split-tunnel.md).
|
||
|
||
---
|
||
|
||
## 5. Что идёт по проводу (резюме)
|
||
|
||
- **Основной**: собственный UDP-транспорт Aura (в примере — `443/udp`). Один UDP-сокет несёт
|
||
обе фазы, различимые по первому байту:
|
||
- `0x01` HS — рукопожатие с надёжным DTLS-подобным слоем поверх (повторы, ack, упорядочивание);
|
||
- `0x02` DATA — датаграммы данных с explicit-nonce AEAD; обфускация = паддинг до «корзин»
|
||
HTTPS (`[64, 128, 256, 512, 1024, 1280, 1460]`).
|
||
- **Fallback TCP/443**: настоящий **outer TLS-443** (rustls) поверх TCP — на проводе неотличимо
|
||
от валидного HTTPS, ALPN `[h2, http/1.1]`. Внутри TLS — тот же Aura-handshake. Клиент
|
||
использует `AcceptAnyServerCert` (security гарантирует только внутренний Aura-handshake).
|
||
- **Fallback QUIC**: внешний TLS-камуфляж под HTTP/3 + внутреннее Aura-рукопожатие.
|
||
- Клиент пробует транспорты по `order`, переключается при отказе или таймауте подключения
|
||
(по умолчанию 8 с). Сервер слушает все включённые транспорты одновременно (`MultiServer`).
|
||
|
||
Подробный wire-протокол — в [`protocol.md`](protocol.md).
|
||
|
||
---
|
||
|
||
## 6. v2 — что устранено и что остаётся
|
||
|
||
### Устранено в v2 (по сравнению с v1)
|
||
|
||
- ✓ **Мульти-клиент UDP-сервер.** `UdpServer` теперь демультиплексирует датаграммы по адресу
|
||
пира: один сокет обслуживает много клиентов параллельно, каждый со своим `ReliableHsAdapter` и
|
||
своим `UdpConnection`. `MultiServer::accept` выдаёт по соединению на каждого нового клиента
|
||
(в любом из включённых транспортов).
|
||
- ✓ **IP-пул + per-client маршрутизация на сервере.** Новая секция `[server.pool]`
|
||
(`cidr`, `strategy`, `static`) выдаёт каждому клиенту IP при accept; `ServerRouter` держит
|
||
карту `client_ip → Arc<dyn PacketConnection>`, читает с TUN, диспатчит пакеты по `dst_ip` в
|
||
нужное подключение, а параллельные per-conn-задачи пишут входящий трафик обратно в TUN.
|
||
- ✓ **`send_direct` устранён.** Новое `[tunnel.os_routes]` (по умолчанию `enabled = true`)
|
||
программирует **системную таблицу маршрутов**: DIRECT-цели идут мимо TUN через изначальный
|
||
default-gateway, через TUN попадает только VPN-трафик. RAII-guard откатывает все добавленные
|
||
маршруты при остановке клиента.
|
||
- ✓ **Настоящий TLS-443 в TCP-транспорте.** Вместо лёгкой HTTP/1.1-преамбулы — полный outer
|
||
rustls handshake (ALPN `[h2, http/1.1]`); клиент с `AcceptAnyServerCert`, поэтому SNI на
|
||
внешнем слое не верифицируется (это камуфляж), а вся реальная аутентификация — внутри
|
||
Aura-рукопожатия. На проводе неотличимо от валидного HTTPS.
|
||
- ✓ **Авто-NAT на сервере.** `[server.nat] {auto, egress_iface, dry_run}` поднимает
|
||
IP-форвардинг + MASQUERADE на старте (Linux: `sysctl ip_forward` + `iptables -t nat
|
||
MASQUERADE`; macOS: `sysctl ip.forwarding` + `pfctl`). RAII-guard откатывает изменения при
|
||
остановке. Опциональный `dry_run = true` логирует команды без выполнения — для отладки.
|
||
- ✓ **Privilege drop.** `[server]/[client] run_as = "nobody"` — после поднятия TUN и
|
||
привилегированных портов euid/gid сбрасываются в нерутового пользователя (Linux:
|
||
`setresuid/setresgid`; macOS: `setgid` + `setuid` permanent drop). Минимизирует время
|
||
процесса под root.
|
||
- ✓ **Admin-сокет на Windows.** Cfg-gated транспорт: на Unix — Unix socket
|
||
(`/tmp/aura-admin.sock`), на Windows — Tokio named pipe (`\\.\pipe\aura-admin`).
|
||
JSON-протокол и команды (`route add/list/remove`, `status`) идентичны.
|
||
- ✓ **In-band CRL.** Сервер сразу после handshake пушит подписанный CA CRL клиенту
|
||
через мультиплексированный control-envelope с magic-префиксом
|
||
`[0xAA,0xAA,0xC0,0x01]` (не конфликтует с IPv4/v6, которые начинаются с
|
||
`0x4X`/`0x6X`). Клиент проверяет подпись ECDSA-P256 против CA, применяет к
|
||
`AuraCertVerifier`, кэширует на диск. Конфиг `[pki] crl_push = true` /
|
||
`accept_pushed_crl = true` (по умолчанию).
|
||
- ✓ **Анти-надзор v2 (NEW в ответ на дрегнет операторов):**
|
||
- **Port-knocking** на UDP-транспорте: сервер молчит на скан-зондах, отвечает
|
||
только на валидный 16-байтный HMAC-SHA256 «стук» с ±1-минутным окном (ключ
|
||
из CA fingerprint). Сканер видит закрытый порт. `[transport.knock]
|
||
enabled = true`.
|
||
- **Cover traffic / chaff**: при простое UDP-соединение шлёт `Ping` каждые
|
||
~500мс±50% (jitter). Defeats volume/timing-fingerprinting. Под нагрузкой
|
||
подавляется автоматически. `[transport.cover] enabled = true`.
|
||
- ✓ **Автоматизация развёртывания:**
|
||
- `aura server-init --domain ... --pki-dir ...` — одна команда: CA +
|
||
серверный cert + готовый `server.toml` (с авто-определением egress-iface).
|
||
- `aura provision-client --id <UUID> --out <dir>` — выпускает client cert и
|
||
собирает готовый бандл (`ca.crt` + `client.crt` + `client.key` +
|
||
`client.toml`). `--id` опционален — дефолт UUID v4 (имя пользователя не
|
||
привязано к сертификату).
|
||
- ✓ **Минимизация идентификаторов:**
|
||
- `[server] no_logs = true` / `[client] no_logs = true` — поля `peer_id`,
|
||
`client_ip`, `source_addr`, `client_id`, `local_ip`, `user`, `id`,
|
||
`assigned_ip` редактируются из tracing-вывода через field-level фильтр
|
||
(события фиксируются, идентификаторы вычищаются).
|
||
- `[client] bridges = [...]` — список запасных серверов, клиент пробует
|
||
случайный порядок. Блокировка одного IP не убивает доступ.
|
||
- ✓ **НОВОЕ: ежедневная ротация масок в 05:00 МСК.** Внешний фингерпринт (SNI/UA/Server-
|
||
header/UDP padding-профиль) детерминированно меняется раз в сутки. И сервер, и клиент
|
||
выводят одинаковый `MaskSet` из общего seed (SHA-256 от CA-сертификата) + UTC-даты через
|
||
HKDF-SHA256, без сетевой координации. Конфиг: `[transport.masks] enabled = true` (по
|
||
умолчанию). Новые подключения берут текущую маску; уже установленные остаются на своих.
|
||
Палитры: 16 SNI default + 15 SNI russian, 10 User-Agent, 5 Server-headers, 4 padding-профиля;
|
||
профиль 0 байт-в-байт совместим с v1-паддингом (бэк-совместимость). v3.2 добавляет
|
||
`palette = "default" | "russian" | "mixed"` для случая, когда нужно, чтобы outer SNI выглядел
|
||
как обращение к российскому сайту (см. сценарий в §7).
|
||
- ✓ **Multi-hop / onion routing v3.1 + v3.2.** Цепочка из 2-3 хопов: client →
|
||
entry-relay → (опционально middle) → exit. Entry-relay не знает destination, exit-узел не
|
||
знает клиентский IP. v3.2: per-hop client cert (CN entry и exit различаются — нельзя
|
||
слинковать handshakes по identity), cell padding (constant-size cells устраняют per-packet
|
||
size-fingerprinting), CIDR whitelist на relay'е. Конфиг — `[client.circuit]` /
|
||
`[server.relay]`. См. сценарий §7 для деплоймента «российский entry, иностранный exit».
|
||
- ✓ **Let's Encrypt outer-TLS cert.** `[server.outer_cert] cert_path / key_path` — outer-TLS
|
||
слой 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-уровень). На
|
||
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 пункт.
|
||
- **Bridge-discovery без хардкода IP в конфиге** — план v3.3. Сейчас `[client] bridges`
|
||
хардкодит список запасных IP; если их все заблокируют (включая российские entry-узлы из
|
||
сценария §7), восстановление требует обновления конфига клиента вручную.
|
||
|
||
---
|
||
|
||
## 7. Сценарий: российский entry-узел против тарификации иностранного трафика
|
||
|
||
### 7.1. Контекст и угроза
|
||
|
||
Российские операторы связи могут начать тарифицировать «иностранный трафик» отдельно: классификация
|
||
выполняется по destination IP исходящего пакета пользователя. Если первый IP, к которому
|
||
обращается устройство, — российский, биллинг считает соединение «российским», даже если внутри
|
||
этого соединения трафик уходит дальше за рубеж. Цель в этом сценарии — добиться того, чтобы
|
||
оператор биллил трафик пользователя как «российский», при этом сохраняя VPN-выход за рубежом.
|
||
|
||
Решение опирается на три компонента, уже реализованные в AuraVPN:
|
||
|
||
1. **Multi-hop / onion routing v3.1+** (`[client.circuit]` / `[server.relay]`) — entry-узел в РФ
|
||
не знает destination, exit-узел за рубежом не знает клиентский IP.
|
||
2. **Палитра SNI «russian»** (v3.2) — `[transport.masks] palette = "russian"` ротирует outer-TLS
|
||
SNI среди крупных российских доменов (`vk.com`, `www.ozon.ru`, `mail.yandex.ru`, ...).
|
||
3. **OS-уровень kill-switch** (`[tunnel.os_routes] enabled = true`) — гарантия, что системный
|
||
трафик (push-уведомления, OS-сервисы) не обходит туннель и не попадает напрямую к иностранным
|
||
серверам в обход entry-узла.
|
||
|
||
### 7.2. Топология
|
||
|
||
```
|
||
[устройство]
|
||
|
|
||
| весь трафик через TUN (kill-switch)
|
||
v
|
||
[оператор] <-- видит только UDP/443 на RU_VPS_IP, SNI = "vk.com"
|
||
|
|
||
v
|
||
[Russian VPS / entry-relay] <-- v3.1 relay: forward to next hop, never decodes IP packets
|
||
|
|
||
| inner Aura handshake (PQ-encrypted, opaque)
|
||
v
|
||
[Foreign VPS / exit] <-- настоящий VPN-выход в интернет
|
||
|
|
||
v
|
||
[internet]
|
||
```
|
||
|
||
Оператор видит только трафик до **entry-узла**: один UDP-поток с SNI крупного российского сайта.
|
||
Внутри этого потока — зашифрованный многохоп; entry-relay не имеет ключей внутреннего рукопожатия
|
||
и видит только AEAD-ciphertext, который он форвардит на exit. Exit видит только IP entry-узла, а
|
||
не IP клиентского устройства.
|
||
|
||
### 7.3. Что покупать
|
||
|
||
**Подходящие провайдеры для entry-узла в РФ** (юрисдикция РФ, IP в российских AS):
|
||
|
||
- **Selectel** (Москва, СПб).
|
||
- **Beget** (СПб).
|
||
- **Yandex.Cloud** (Москва).
|
||
- **VK Cloud** (бывш. Mail.ru Cloud Solutions).
|
||
- **Timeweb Cloud**.
|
||
|
||
**Неподходящие для роли entry-узла в РФ**:
|
||
|
||
- **Hetzner** (Германия/Финляндия) — IP классифицируется как «иностранный».
|
||
- **DigitalOcean / Vultr / Linode** (США/EU) — то же самое.
|
||
- **AWS / GCP / Azure** даже с российскими DC-локациями — IP-блоки за пределами российских AS у
|
||
большинства операторов.
|
||
|
||
Для **exit-узла** наоборот — берите любой удобный иностранный VPS (Hetzner, DigitalOcean, Vultr,
|
||
любой подходящий по юрисдикции и пропускной способности).
|
||
|
||
### 7.4. Конфиг сервера в РФ (entry-relay)
|
||
|
||
`server.toml` на российском VPS (например, Selectel с IP `RUSSIAN_VPS_IP`):
|
||
|
||
```toml
|
||
[server]
|
||
name = "aura-ru-entry-1"
|
||
listen = "0.0.0.0:443"
|
||
|
||
[pki]
|
||
ca_cert = "/etc/aura/pki/ca.crt"
|
||
cert = "/etc/aura/pki/server/server.crt"
|
||
key = "/etc/aura/pki/server/server.key"
|
||
|
||
[tunnel]
|
||
# Pool нужен формально (для v1-fallback-пути), но в роли чистого relay он не используется —
|
||
# bridged-клиенты не получают IP из пула и не регистрируются в ServerRouter.
|
||
pool_cidr = "10.7.0.0/24"
|
||
mtu = 1420
|
||
|
||
# v3.1: relay-режим. Принимаем ExtendBridge от клиента и сплайсим на foreign exit.
|
||
[server.relay]
|
||
enabled = true
|
||
allow_extend_to = ["EXIT_FOREIGN_IP:443"] # IP вашего иностранного exit-узла
|
||
# v3.2 cell padding: relay сам не декодирует — это сквозной байт-форвардинг. Знаки опции тут
|
||
# для симметрии конфига; реальный декод цельных ячеек — на exit'е.
|
||
cell_padding = true
|
||
cell_size = 1280
|
||
|
||
[transport.masks]
|
||
enabled = true
|
||
# v3.2: outer-TLS SNI крутится среди крупных российских доменов. Каждый день — другой домен.
|
||
palette = "russian"
|
||
|
||
# Опционально: настоящий outer-TLS сертификат (Let's Encrypt) поверх UDP/QUIC и TCP. Без него
|
||
# работает self-signed Aura, но с настоящим LE-сертификатом outer-handshake становится
|
||
# неотличим от обычного HTTPS на CA-trusted сайт.
|
||
[server.outer_cert]
|
||
cert_path = "/etc/letsencrypt/live/relay.example.ru/fullchain.pem"
|
||
key_path = "/etc/letsencrypt/live/relay.example.ru/privkey.pem"
|
||
```
|
||
|
||
И аналогичный `server.toml` на **иностранном exit-узле** — обычный VPN-сервер БЕЗ `[server.relay]`,
|
||
но с `cell_padding_for_circuit_clients = true` в секции `[server]`, чтобы он понимал
|
||
constant-size cells от клиента:
|
||
|
||
```toml
|
||
[server]
|
||
name = "aura-exit-1"
|
||
listen = "0.0.0.0:443"
|
||
# v3.2: exit для cell-padded клиентов — декодирует ячейки внутреннего рукопожатия.
|
||
cell_padding_for_circuit_clients = true
|
||
|
||
[pki]
|
||
ca_cert = "/etc/aura/pki/ca.crt"
|
||
cert = "/etc/aura/pki/server/exit.crt"
|
||
key = "/etc/aura/pki/server/exit.key"
|
||
|
||
[tunnel]
|
||
pool_cidr = "10.7.0.0/24"
|
||
|
||
[server.nat]
|
||
auto = true # включить IP-форвардинг и MASQUERADE на egress-интерфейсе
|
||
egress_iface = "eth0"
|
||
|
||
[transport.masks]
|
||
# На exit'е SNI палитра не критична (клиент видит exit только через relay) — оставим default.
|
||
palette = "default"
|
||
```
|
||
|
||
### 7.5. Конфиг клиента
|
||
|
||
```toml
|
||
[client]
|
||
name = "laptop"
|
||
server_addr = "RUSSIAN_VPS_IP:443" # entry-узел в РФ; именно этот IP видит оператор
|
||
sni = "relay.example.ru" # SAN серверного outer-TLS сертификата (если есть LE)
|
||
|
||
[pki]
|
||
ca_cert = "~/.aura/ca.crt"
|
||
cert = "~/.aura/client.crt"
|
||
key = "~/.aura/client.key"
|
||
|
||
[tunnel]
|
||
tun_name = "aura0"
|
||
local_ip = "10.7.0.2"
|
||
prefix = 24
|
||
mtu = 1420
|
||
|
||
[tunnel.split]
|
||
default = "VPN"
|
||
|
||
# КРИТИЧНО: kill-switch — весь трафик через TUN, OS-уровень. Без этого push-уведомления и
|
||
# OS-сервисы могут уйти напрямую в иностранные сервера в обход entry-узла, и оператор
|
||
# зачтёт это как «иностранный» трафик.
|
||
[tunnel.os_routes]
|
||
enabled = true
|
||
|
||
# v3.1 / v3.2: цепочка хопов client -> RU_entry -> foreign_exit.
|
||
[client.circuit]
|
||
enabled = true
|
||
cell_padding = true
|
||
cell_size = 1280
|
||
|
||
[[client.circuit.hops]]
|
||
addr = "RUSSIAN_VPS_IP:443" # entry в РФ — то, что видит оператор
|
||
cert_path = "~/.aura/circuit/entry.crt"
|
||
key_path = "~/.aura/circuit/entry.key"
|
||
|
||
[[client.circuit.hops]]
|
||
addr = "EXIT_FOREIGN_IP:443" # exit за рубежом, к которому привязаны DNS/маршруты внутри VPN
|
||
cert_path = "~/.aura/circuit/exit.crt"
|
||
key_path = "~/.aura/circuit/exit.key"
|
||
|
||
[transport.masks]
|
||
enabled = true
|
||
# Должно совпадать с palette = "russian" на entry-узле — иначе SNI в логах двух сторон
|
||
# не будут симметричны (на проводе это не ошибка, но удобнее для отладки).
|
||
palette = "russian"
|
||
```
|
||
|
||
Сертификаты двух хопов — разные (`entry.crt` != `exit.crt`). Это v3.2 identity-unlinkability:
|
||
entry-relay видит только клиентский cert для роли entry, exit-узел видит только cert для роли
|
||
exit, и они не пересекаются (см. `aura provision-client --circuit-hops 2 ...`).
|
||
|
||
### 7.6. Что это даёт
|
||
|
||
- **Оператор биллит как «российский».** На проводе оператор видит один UDP-поток на
|
||
`RUSSIAN_VPS_IP:443` — это российский IP в российской AS, классификатор биллинга его не
|
||
обозначает как иностранный.
|
||
- **SNI выглядит как обращение к российскому сайту.** В пакетах outer-TLS / outer-QUIC
|
||
hostname-камуфляж берётся из `SNI_PALETTE_RUSSIAN`: каждый день — другой домен (`vk.com`,
|
||
`www.ozon.ru`, `mail.yandex.ru`, ...). DPI видит «нормальный HTTPS на крупный российский
|
||
сайт».
|
||
- **Реальный VPN-выход — за рубежом.** Внутри multi-hop клиент дозванивается до иностранного
|
||
exit-узла; именно его IP видят внешние ресурсы. Entry-узел в РФ форвардит зашифрованный
|
||
трафик, не зная destination и не имея ключей внутреннего рукопожатия.
|
||
- **Kill-switch предотвращает обход.** `[tunnel.os_routes] enabled = true` программирует
|
||
системную таблицу маршрутов так, что весь трафик идёт через TUN — push-уведомления, OS-сервисы
|
||
и любые «прямые» обращения в обход VPN заблокированы, поэтому ничто из устройства не уйдёт
|
||
напрямую к иностранному IP в обход entry-узла.
|
||
|
||
### 7.7. Что это НЕ даёт (честное ограничение)
|
||
|
||
- **Не скрывает сам факт VPN-использования** от российских органов. DPI с deep-inspection может
|
||
по статистическим паттернам трафика (timing, размеры, поведение в течение сессии) узнать
|
||
Aura-протокол; ротация масок и `palette = "russian"` маскирует пассивного наблюдателя, но не
|
||
активного аналитика. Для дополнительной защиты включайте `[transport.knock]` и
|
||
`[transport.cover]` (port-knocking + cover traffic).
|
||
- **Не освобождает от ответственности за заходы на запрещённые ресурсы.** Кто и за что отвечает
|
||
при заходе на запрещённый ресурс через VPN — вопрос юрисдикции exit-узла и применимого
|
||
законодательства, не технический.
|
||
- **Не защищает от блокировки самого entry-IP.** Если СОРМ-система или Роскомнадзор начнут
|
||
активно блокировать конкретные VPS-IP, придётся ротировать IP / bridges. Сейчас это решается
|
||
через `[client] bridges = [...]` — список запасных российских entry-узлов; клиент пробует их
|
||
в случайном порядке при отказе primary. Полноценный bridge-discovery (без хардкода IP в
|
||
конфиге) — план v3.3.
|
||
- **Cell padding не скрывает наличие туннеля.** Constant-size cells устраняют per-packet
|
||
size-fingerprinting внутри multi-hop, но не делают сам поток неотличимым от HTTPS — общий
|
||
объём и временные паттерны остаются. Это компромисс между обфускацией и накладными расходами.
|
||
|
||
### 7.8. Что менять при ротации
|
||
|
||
При смене IP entry-узла (например, при блокировке текущего) обновите три места:
|
||
|
||
1. `[[client.circuit.hops]] addr` первого хопа → новый `RUSSIAN_VPS_IP:443`.
|
||
2. `[client] server_addr` → тот же новый IP.
|
||
3. На новом VPS — поднять PKI, выпустить cert для entry-роли, перенести `server.toml` с
|
||
`[server.relay]` и `palette = "russian"`.
|
||
|
||
Перевыпускать сертификаты двух хопов не нужно — они остаются те же, меняется только 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-клиента.
|