d5b9a8611d
- 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>
71 lines
4.0 KiB
Markdown
71 lines
4.0 KiB
Markdown
# 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.
|