Closes the v3.3 "bridges by hand" honest limitation. Admins now publish a
CA-signed manifest with the current bridge list; clients re-read it from
disk on a timer and merge it with the static [client] bridges. Cuts the
"rotate the bridge list" cycle from "edit every client config" to
"distribute one signed file".
- New aura sign-bridges CLI:
aura sign-bridges --ca /etc/aura/pki \
--bridges "ip1:443,ip2:443" \
--ttl-days 7 \
--out /var/aura/bridges.signed
- Manifest format (single file, text + signature block, same shape as the
in-band CRL):
AURA-BRIDGES-v1
{"version":1,"generated_at":...,"expires_at":...,"bridges":[...]}
--SIGNATURE--
<hex ECDSA-P256/SHA-256 over body>
- aura-pki now exports `sign_ecdsa_p256` / `verify_ecdsa_p256` so CRL and
bridges share ONE signing primitive (no copy-paste). CRL keeps working.
- aura-cli::bridges::BridgeManifest + BridgesDiscoveryWatcher: new
module. encode_signed/load_signed_verified verifies signature + rejects
expired manifests. Watcher spawns a tokio interval that re-reads the
file; on load failure (truncated, expired, bad sig) the previous
snapshot is kept — bridges never collapse to empty.
- New [client.bridges_discovery] {enabled, manifest_path,
refresh_interval_secs}; serde(default) so v3.2 configs keep working.
- Merge strategy: manifest EXTENDS static [client] bridges, dedup by
SocketAddr, static-first ordering. Static remains as fallback.
- 13 new tests (8 lib unit + 4 integration + 1 config). Workspace: 310
tests passed (+13), clippy -D warnings clean, fmt clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
Adds a way to make the outer-TLS SNI rotate among popular Russian-language
domains so that Russian carriers — who may start metering "foreign traffic"
separately — see the user's first hop as a domestic CDN/site request, not
as an exotic foreign destination.
- aura-crypto::masks:
- SNI_PALETTE_RUSSIAN (15 real domains: mail.yandex.ru, vk.com, www.ozon.ru,
dzen.ru, ya.ru, www.gosuslugi.ru, www.wildberries.ru, rutube.ru,
news.rambler.ru, hh.ru, www.tinkoff.ru, lenta.ru, www.kinopoisk.ru,
afisha.yandex.ru, music.yandex.ru).
- enum SniPalette { Default, Russian, Mixed } (Default = v2 behavior).
- derive_mask_for_msk_date_with_palette(...): pick from chosen palette,
Mixed flips ~50/50 by HKDF okm[8]&1. Old derive_mask_for_msk_date kept
as a thin wrapper -> byte-for-byte unchanged Default.
- aura-cli::masks::MaskRotator gains new_with_palette(...); the spawn loop
uses the stored palette. Old new() preserves Default.
- aura-cli config: [transport.masks] palette = "default"|"russian"|"mixed"
(serde rename_all = "lowercase", default Default).
- server.rs/client.rs read cfg.transport.masks.palette and pass it to the
rotator at startup; logged at INFO so the operator sees the choice.
- docs/deployment.md: new §7 "Сервер в РФ против тарификации иностранного
трафика" — context, ASCII topology, recommended RF providers, full
server.toml + client.toml examples wiring [server.relay] + russian
palette + LE outer cert + multi-hop, plus an honest list of what this
does and does not give.
- config/{server,client}.toml.example updated with palette = "default".
Workspace: 284 tests passed (+8 new = 4 crypto + 2 cli masks + 2 config),
clippy -D warnings clean, fmt clean. 276 baseline tests untouched.
Backward-compatible: configs without palette default to Default, identical
to v2 wire behavior.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
deployment.md §6 updated:
- Moved CRL from "remaining" to "resolved" (now in-band via signed
control-envelope with magic prefix).
- Added bullets for the new v2 features: port-knocking + cover traffic
(anti-surveillance), `aura server-init` / `aura provision-client`
(automation), `no_logs` field redaction, `bridges` list.
- Remaining honest limits trimmed to genuine v3 work: native Go phone
client (sing-box, explicitly excluded by user) and multi-hop routing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
§5: TCP/443 fallback now described as real outer TLS-443 (was the lighter
HTTP/1.1 masquerade in v1).
§6 rewritten "Честные ограничения v1" -> "v2 — что устранено и что остаётся":
- Resolved: UDP multi-client demux, server IP pool + per-client routing,
OS-level split-tunnel (no more send_direct stub), real TLS-443, auto-NAT,
privilege drop, Windows admin named pipe, daily protocol-mask rotation
at 05:00 MSK.
- Remaining honest limits: TUN creation still needs root (privilege drop
shrinks the window), IPv6 in OS routes / iptables not yet, Windows OS
routes stubbed, CRL still out-of-band (in-band push deferred), native
phone client via sing-box still a plan, no auto-detect of egress iface.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
docs/protocol.md, docs/pki.md, docs/split-tunnel.md — written from the actual
implementation (pinned handshake order, ML-KEM-768/FIPS 203, seq||AEAD records
with replay window, QUIC/H3 mimicry) including honest v1 limitations.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>