feat(cli): select transport in config; server MultiServer + client dial handover
- aura-cli config gains [transport] (order + per-transport ports + obfuscate/ masquerade); server binds all enabled transports via MultiServer, client uses dial() with UDP->TCP->QUIC handover. Config examples updated; backward-compatible (defaults to udp,tcp,quic). 21 cli tests incl. a real-UDP-transport loopback. - docs/sing-box.md: integration approach note (process-bridge now; native Go outbound for phones, with crypto-library mapping + KAT requirement). - Normalize rustfmt across the v2 transport files (tcp/dial/udp contract). Whole workspace: 97 tests pass, clippy -D warnings clean, fmt clean. Deploy flow (pki init/issue-server/issue-client) validated with the release binary. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# Integrating AuraVPN with sing-box (approach note)
|
||||
|
||||
Goal: let a phone client running **sing-box** connect to an Aura server speaking the **AuraVPN**
|
||||
protocol (Aura's own tunneling — not a third party's). This is a short note on *how*; the wire
|
||||
protocol it must match is fully specified in [`protocol.md`](protocol.md).
|
||||
|
||||
sing-box is written in Go and has no generic "load an arbitrary external wire protocol" plugin, so
|
||||
integration means giving sing-box a Go implementation (or a bridge) of the Aura protocol. Three
|
||||
realistic paths, cheapest first:
|
||||
|
||||
## Option A — Process bridge (fastest, desktop/server)
|
||||
|
||||
Run the existing Rust `aura` client as a local process and expose a local proxy/TUN, then point
|
||||
sing-box at it:
|
||||
|
||||
- `aura client` already creates a TUN and routes through the Aura tunnel; sing-box can route selected
|
||||
traffic into that interface, **or**
|
||||
- add a local **SOCKS5 inbound** to `aura-cli` (small addition) and configure a sing-box `socks`
|
||||
outbound pointing at `127.0.0.1:<port>`.
|
||||
|
||||
Pros: reuses the audited Rust core verbatim; no crypto re-implementation. Cons: two processes; weak
|
||||
fit for mobile (sing-box mobile apps embed the core and don't spawn helpers easily).
|
||||
|
||||
## Option B — Native Go outbound/inbound (the real target for phones)
|
||||
|
||||
Implement the AuraVPN protocol natively in Go and register it as a sing-box **outbound** (client) and
|
||||
**inbound** (server), so the phone's embedded sing-box core speaks AuraVPN directly. This is the
|
||||
clean, performant, mobile-friendly path. Crypto maps cleanly to existing Go libraries:
|
||||
|
||||
| Aura piece | Rust crate | Go equivalent |
|
||||
|---|---|---|
|
||||
| X25519 ECDH | `x25519-dalek` | `crypto/ecdh` (stdlib) |
|
||||
| ML-KEM-768 (FIPS 203) | `ml-kem` | `crypto/mlkem` (Go 1.24+) or `cloudflare/circl` |
|
||||
| ChaCha20-Poly1305 | `chacha20poly1305` | `golang.org/x/crypto/chacha20poly1305` |
|
||||
| HKDF-SHA256 | `hkdf` | `golang.org/x/crypto/hkdf` |
|
||||
| HMAC-SHA256 (Finished) | `hmac` | `crypto/hmac` + `crypto/sha256` |
|
||||
| ECDSA P-256 sigs (cert auth) | `ring` | `crypto/ecdsa` + `crypto/x509` |
|
||||
| X.509 verify + CRL | `rustls-webpki` | `crypto/x509` |
|
||||
|
||||
What the Go code must reproduce **exactly** (see `protocol.md`):
|
||||
- 5-byte frame header `msg_type(1) || len(u24 BE) || version=0x01`.
|
||||
- Handshake order CH → SH → ServerAuth → ClientAuth → Finished(c→s) → Finished(s→c); transcript =
|
||||
`SHA-256(ClientHello_frame || ServerHello_frame)`; ECDSA-P256/SHA-256 signature over the transcript;
|
||||
HMAC-SHA256 Finished.
|
||||
- Hybrid shared secret = `x25519_ss || mlkem_ss`; HKDF salt = `client_nonce || server_nonce`,
|
||||
info = `b"aura-v1-session"`.
|
||||
- Data record (datagram/UDP) = `seq(8 BE) || ChaCha20Poly1305(frame, aad = seq)`, nonce =
|
||||
`LE(seq) || 0x00000000`; replay window 64. (Stream/TCP record adds the 5-byte header to the AAD.)
|
||||
- Transport selection: UDP (type `0x01` HS / `0x02` DATA) primary; TCP/443 and QUIC fallbacks.
|
||||
|
||||
To de-risk the Go port, export **known-answer test vectors** from the Rust side (a captured
|
||||
handshake transcript + derived keys + a sealed data record) and assert the Go implementation
|
||||
reproduces them byte-for-byte. The ML-KEM KAT already lives in `aura-crypto/tests/kat_kyber.rs`.
|
||||
|
||||
## Option C — Rust core via cgo (`cdylib`)
|
||||
|
||||
Compile the Aura Rust core to a C-ABI shared library and call it from a thin sing-box Go shim via
|
||||
cgo. Reuses the audited crypto/handshake with no Go re-implementation, but cgo + per-platform
|
||||
(Android/iOS) packaging is fiddly and complicates sing-box's pure-Go build.
|
||||
|
||||
## Recommendation
|
||||
|
||||
- **Now:** Option A (process bridge) for desktop/server validation — minimal work, real protocol.
|
||||
- **For the phone:** Option B (native Go outbound), built against `protocol.md` + exported Rust test
|
||||
vectors. It is the only option that fits sing-box's embedded mobile core well.
|
||||
- Keep `protocol.md` the single source of truth and version the wire protocol (the header already
|
||||
carries `version = 0x01`) so the Rust and Go implementations stay in lockstep.
|
||||
|
||||
> Status: this is a design note. No Go code or sing-box module is implemented yet — that is a
|
||||
> separate deliverable tracked for after the Rust transport stabilizes.
|
||||
Reference in New Issue
Block a user