# Развёртывание 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//client.crt`) — листовой сертификат клиента; - `client.key` (из `/etc/aura/clients//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 ` к каждой команде. Полная спецификация команд и 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`, читает с 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`) идентичны. - ✓ **НОВОЕ: ежедневная ротация масок в 05:00 МСК.** Внешний фингерпринт (SNI/UA/Server- header/UDP padding-профиль) детерминированно меняется раз в сутки. И сервер, и клиент выводят одинаковый `MaskSet` из общего seed (SHA-256 от CA-сертификата) + UTC-даты через HKDF-SHA256, без сетевой координации. Конфиг: `[transport.masks] enabled = true` (по умолчанию). Новые подключения берут текущую маску; уже установленные остаются на своих. Палитры: 16 SNI, 10 User-Agent, 5 Server-headers, 4 padding-профиля; профиль 0 байт-в-байт совместим с v1-паддингом (бэк-совместимость). ### Остающиеся честные ограничения v2 - **TUN всё ещё требует root** для **создания** интерфейса (это OS-уровень). Privilege drop минимизирует окно работы под root, но саму операцию обойти нельзя. - **IPv6 в OS-маршрутах и iptables MASQUERADE** не реализован — только IPv4 (план v3). - **Windows OS-маршруты** — заглушка с лог-warning (план v3). Windows admin pipe **работает**. - **CRL** пока распространяется out-of-band (плоский файл `revoked.crl` на сервере и клиенте); in-band пуш сервером → клиенту запланирован (отдельная v2-задача, не реализована в этом раунде). - **Нативного Go-клиента для телефона нет** — через sing-box (Option B нативный Go-outbound, по `protocol.md` + KAT из Rust, см. [`sing-box.md`](sing-box.md)). Сейчас доступен только десктоп-клиент / process-bridge. - **Автоопределение egress-интерфейса** для NAT не реализовано: `[server.nat] egress_iface` обязательно задавать вручную, если `auto = true` (план v3).