Files
AuraVPN/docs/sing-box.md
T
xah30 d5b9a8611d 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>
2026-05-25 21:41:59 +03:00

4.0 KiB

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.

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.