7d711d8938
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>
39 lines
1.5 KiB
TOML
39 lines
1.5 KiB
TOML
[package]
|
|
name = "aura-transport"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
description = "Aura transport: QUIC (quinn) endpoint, HTTPS/H3 mimicry, padding"
|
|
|
|
[dependencies]
|
|
aura-proto.workspace = true
|
|
aura-crypto.workspace = true
|
|
quinn.workspace = true
|
|
tokio.workspace = true
|
|
bytes.workspace = true
|
|
rustls.workspace = true
|
|
rustls-pki-types.workspace = true
|
|
rand.workspace = true
|
|
tracing.workspace = true
|
|
thiserror.workspace = true
|
|
anyhow.workspace = true
|
|
async-trait.workspace = true
|
|
# PEM (certificates + PKCS#8 keys) -> DER for the outer QUIC/TLS rustls config. Already resolved
|
|
# in the workspace lockfile (pulled transitively), so this adds no new version resolution.
|
|
rustls-pemfile = "2"
|
|
# Outer TLS-443 wrapper for the TCP transport (real HTTPS-on-the-wire camouflage; the security
|
|
# boundary is still the inner Aura handshake, just like for the QUIC backend). Local-only to this
|
|
# crate — not a new workspace dependency.
|
|
tokio-rustls = { version = "0.26", default-features = false, features = ["ring"] }
|
|
# HMAC-SHA256 for UDP port-knocking (probe resistance): the knock token is
|
|
# `HMAC(knock_key, u64_be(unix_minute))[..16]`, prefixed on every HS datagram when
|
|
# `UdpOpts::knock_required` is enabled. Both already resolved in the workspace lockfile (transitively
|
|
# via aura-crypto's deps tree), so no new version is introduced.
|
|
hmac = "0.12"
|
|
sha2 = "0.10"
|
|
|
|
[dev-dependencies]
|
|
# The loopback integration test mints a CA + server/client certs to drive a real QUIC handshake.
|
|
aura-pki.workspace = true
|
|
tokio.workspace = true
|