Commit Graph

11 Commits

Author SHA1 Message Date
xah30 7d711d8938 feat(transport): anti-surveillance - UDP port-knocking + cover traffic
Two opt-in (default off) features directly targeting the kind of operator
dragnet described in the news context — make the server harder to identify
on a scan, and the traffic harder to fingerprint by volume/timing analysis.

1) Port-knocking (probe resistance, UDP)
   - Wire: every HS datagram (0x01) is prefixed with a 16-byte HMAC token
     when UdpOpts.knock_required is on:
       knock = HMAC-SHA256(knock_key, u64_be(unix_minute))[..16]
   - Server-side: validates against {now-1, now, now+1} minutes (3-minute
     window for clock skew, constant-time compare). Invalid -> silent drop;
     the port looks closed to scanners.
   - knock_key comes from the CLI (derived from CA fingerprint at the
     deployment layer); transport just consumes it.
   - DATA datagrams unchanged (AEAD already proves legitimacy past hs).

2) Cover traffic (chaff, UDP)
   - Optional background task per UdpConnection: every random delay
     (mean_interval_ms +/- jitter, default 500ms +/- 50%) sends a
     Frame::Ping{seq=random} when no Data was sent in the recent window
     (idle-skip => zero overhead under load). RAII-aborted on Drop.
   - Receiver answers Ping with Pong (existing logic); both are consumed
     internally by recv_packet, invisible to the app.

API: UdpOpts gains knock_required/knock_key/cover_traffic_enabled/
cover_mean_interval_ms/cover_jitter (all defaults preserve v2 behavior).
Helpers exported: knock_for_minute, KNOCK_LEN.

Local deps: hmac 0.12 + sha2 0.10 (already in workspace lockfile, no new
resolution). Workspace: 185 tests passed (+11), clippy -D warnings clean,
fmt clean. 174 baseline tests unchanged.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 11:50:16 +03:00
xah30 c6f0d7af9b feat(cli): auto-NAT + privilege drop + Windows named-pipe admin
Three v2-hardening features in aura-cli, one pass:

- nat::NatGuard: RAII auto-config of IP forwarding + MASQUERADE on server
  startup. Linux (sysctl ip_forward + iptables -t nat MASQUERADE) and
  macOS (sysctl ip.forwarding + pfctl with /tmp/aura-nat.conf). dry_run
  works on every platform (logs "would run: ..."). Reverts everything in
  Drop. New [server.nat] {auto, egress_iface, dry_run}; absent section =
  back-compat no-op. Removes v1's "manual NAT/forwarding" step.
- privdrop::drop_to_user: drop euid/gid after binding TUN + privileged
  ports. Linux setresuid/setresgid, macOS setgid+setuid (permanent drop),
  Windows no-op with warning. New [server] / [client] run_as = "..."
  (optional). Skipped with info-log if already non-root.
- admin: split transport into cfg(unix) Unix-socket and cfg(windows) Tokio
  named-pipe modules sharing one JSON-line serve/request flow over
  AsyncRead/AsyncWrite. DEFAULT_SOCKET = "/tmp/aura-admin.sock" on Unix,
  r"\\.\pipe\aura-admin" on Windows. Removes v1's "admin Unix-only".

Deps: nix 0.29 user feature under [target.'cfg(unix)'.dependencies] (cli-
local, not workspace). Workspace: 155 tests passed (+13), clippy -D warnings
clean, fmt clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 02:09:38 +03:00
xah30 821f7711e7 feat(transport): real TLS-443 on the TCP backend (replaces HTTP/1.1 masquerade)
The TCP fallback now does a full outer TLS handshake (tokio-rustls 0.26 over
rustls 0.23, ring provider) before the Aura proto handshake, exactly like the
QUIC backend: on the wire it is indistinguishable from genuine HTTPS until the
inner Aura mutual-auth handshake starts. Removes v1's "light HTTP masquerade"
limitation; the real security boundary remains the inner PQ handshake.

- aura-transport::tcp: dropped the HTTP/1.1 preamble helpers and TcpOpts
  fields (masquerade, host, user_agent, server_header). New flow:
  TlsAcceptor::accept (server) / TlsConnector::connect (client) →
  tokio::io::split(TlsStream) → server_handshake / client_handshake → Session.
  Client reuses crate::quic::AcceptAnyServerCert (outer SNI not authenticated;
  inner handshake is the security boundary). Outer server cert auto-sourced
  from proto_cfg.server_cert_pem (no API change for the CLI's bind).
- ALPN default: ["h2", "http/1.1"] (DEFAULT_TCP_ALPN, exported).
- TcpOpts: now just { alpn: Option<Vec<Vec<u8>>> }.
- TcpClient::connect gains an outer-SNI &str param; DialConfig.sni passes it
  through (separate from the inner proto_cfg.server_name).
- tokio-rustls 0.26 added as a transport-local dependency (not workspace).

CLI updates: removed dead host/user_agent/server_header wiring; mask rotation
no longer touches TCP outer parameters (TLS doesn't have a Host header on
the wire). [transport] masquerade kept as a no-op for back-compat with old
configs (documented).

3 new tcp_loopback tests (default ALPN end-to-end, custom ALPN, outer SNI
mismatch still connects = proves accept-any is in effect). Workspace: 142
tests passed (+1), clippy -D warnings clean, fmt clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 01:53:02 +03:00
xah30 75e350e870 chore: update Cargo.lock for aura-cli async-trait dev-dep 2026-05-27 01:41:56 +03:00
xah30 cb89312a27 feat(cli): implement Wave 4 — aura binary (PKI, server/client, admin, bench)
aura-cli: clap command tree (pki init/issue-server/issue-client/revoke/list,
server, client, route add/list/remove, status, bench-crypto); TOML config with
~ expansion and split-tunnel rules -> RouteTable; JSON-over-Unix-socket admin
IPC; server/client data paths wiring transport + tunnel (TUN run needs root).
config/{server,client}.toml.example. 15 tests (pki roundtrip, config parse,
admin-socket roundtrip, loopback connection). Verified the real binary: --help,
bench-crypto, and a full CA->server->client cert workflow.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:36:13 +03:00
xah30 c19a6c5586 feat(transport,tunnel): implement Wave 3 — QUIC transport + split-tunnel router
aura-transport: quinn 0.11 endpoint with HTTP/3 mimicry (ALPN h3/h3-29,
Chrome-like transport params), outer-TLS accept-any (real auth is the inner
Aura handshake), packet padding to HTTPS sizes; AuraServer/AuraClient drive the
proto handshake over a QUIC bidi stream; AuraConnection impls
aura_proto::PacketConnection (full-duplex via Session::split + per-half mutex).
14 tests incl. a real-QUIC loopback end-to-end (crypto+pki+proto+transport).

aura-tunnel: RouteTable (longest-prefix split-tunnel classify), AuraDns
(hickory) host-route registration, AuraRouter over a PacketIo TUN seam +
Arc<dyn PacketConnection>, AuraTun (tun 0.8 unix; wintun cfg-gated Windows).
10 tests (route classify/priority, dst-IP parse, mock router). send_direct is a
v1 stub. Whole workspace: tests green, clippy clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:26:39 +03:00
xah30 0a045c248d refactor: move PacketConnection trait to aura-proto; decouple tunnel from transport
Worktree isolation is unavailable in this environment, so make Wave 3 safe for
same-tree parallel work instead: the PacketConnection contract now lives in
aura-proto (stable) and aura-tunnel no longer depends on aura-transport. With
transport and tunnel both depending only on proto (and not each other), the two
crates are independent leaves and can be built/edited concurrently without one
breaking the other's build. proto: 13 tests still green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:13:37 +03:00
xah30 cb78de4f37 feat(transport): pin PacketConnection contract for the router seam
Define the async PacketConnection trait (send_packet/recv_packet over &self)
that aura-tunnel's router consumes and the QUIC connection will implement.
Committed before Wave 3 so the transport and tunnel agents build against a
stable cross-crate contract from isolated worktrees.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:10:17 +03:00
xah30 bb835e4ca7 feat(proto): implement Wave 2 — hybrid PKI handshake + session
aura-proto: 5-byte wire header + Frame codec (§6.1/§6.3); transport-agnostic
handshake state machine (§6.2) over split tokio AsyncRead/AsyncWrite —
hybrid X25519+ML-KEM-768 KEM, SHA-256 transcript, mutual X.509 auth with
ECDSA-P256 transcript signatures (ring), constant-time HMAC Finished;
Session with sliding-window replay protection. 13 tests green, clippy clean.

Handshake message order pinned (resolves spec diagram ambiguity); reader/writer
taken by value since Session owns both halves.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 18:05:11 +03:00
xah30 b8ce58ddf0 feat(crypto,pki): implement Wave 1 — hybrid KEM + PKI
aura-crypto: X25519 + ML-KEM-768 (FIPS 203) hybrid KEM, HKDF-SHA256 session
key derivation, ChaCha20-Poly1305 AeadSession with counter nonces; genuine
NIST ACVP ML-KEM-768 KAT (decapsulation vector). 16 tests green, clippy clean.

aura-pki: self-signed CA, server/client cert issuance (rcgen 0.14), mutual
X.509 chain verification via rustls-webpki, CRL revocation. 8 tests green.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 17:55:06 +03:00
xah30 f78633e04f chore: scaffold Aura workspace skeleton (Stage 0)
- 6-crate Cargo workspace, dependency tree frozen (cargo check green in ~1m)
- ml-kem 0.3 (FIPS 203) replaces spec's pqcrypto-kyber for ML-KEM-768
- fix invalid target-gated workspace.dependencies: Windows deps (wintun/windows)
  declared untargeted, cfg-gated per-crate in aura-tunnel
- version bumps vs spec: tun 0.8, rcgen 0.14, wintun 0.5
- stub lib/main per crate; real implementations land wave by wave

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 17:42:40 +03:00