Adds a CLI subcommand that generates a one-time mobileconfig profile containing both the Numa local CA (as a com.apple.security.root payload) and the DoT DNS settings, then serves it via a temporary HTTP server and prints a scannable QR code in the terminal. Flow: 1. User runs `numa setup-phone` (no sudo needed) 2. Detects current LAN IP, reads CA from /usr/local/var/numa/ca.pem 3. Builds combined mobileconfig (CA trust + DoT) 4. Renders QR code with qrcode crate (Unicode block characters) 5. Serves the profile on port 8765, stays open until Ctrl+C 6. Counts successful downloads (multi-device households) Important caveat documented in instructions: even with the CA bundled in the profile, iOS still requires the user to manually enable trust in Settings → General → About → Certificate Trust Settings. Verified on a real iPhone. Stable PayloadIdentifiers/UUIDs ensure re-running replaces the existing profile on iOS rather than accumulating duplicates. - New module: src/setup_phone.rs (~270 lines) - New CLI subcommand: `numa setup-phone` - New dependency: qrcode = "0.14" (default-features = false) - tokio "signal" feature added for Ctrl+C handling - 3 unit tests: PEM stripping, mobileconfig generation, QR rendering Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
51 lines
1.5 KiB
TOML
51 lines
1.5 KiB
TOML
[package]
|
|
name = "numa"
|
|
version = "0.10.3"
|
|
authors = ["razvandimescu <razvan@dimescu.com>"]
|
|
edition = "2021"
|
|
description = "Portable DNS resolver in Rust — .numa local domains, ad blocking, developer overrides, DNS-over-HTTPS"
|
|
license = "MIT"
|
|
repository = "https://github.com/razvandimescu/numa"
|
|
keywords = ["dns", "dns-server", "ad-blocking", "reverse-proxy", "developer-tools"]
|
|
categories = ["network-programming", "development-tools"]
|
|
|
|
[dependencies]
|
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "net", "time", "sync", "signal"] }
|
|
axum = "0.8"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
toml = "1.1"
|
|
log = "0.4"
|
|
env_logger = "0.11"
|
|
reqwest = { version = "0.12", features = ["rustls-tls", "gzip", "http2"], default-features = false }
|
|
hyper = { version = "1", features = ["client", "http1", "server"] }
|
|
hyper-util = { version = "0.1", features = ["client-legacy", "http1", "tokio"] }
|
|
http-body-util = "0.1"
|
|
futures = "0.3"
|
|
socket2 = { version = "0.6", features = ["all"] }
|
|
rcgen = { version = "0.14", features = ["pem", "x509-parser"] }
|
|
time = "0.3"
|
|
rustls = "0.23"
|
|
tokio-rustls = "0.26"
|
|
arc-swap = "1"
|
|
ring = "0.17"
|
|
rustls-pemfile = "2.2.0"
|
|
qrcode = { version = "0.14", default-features = false }
|
|
|
|
[dev-dependencies]
|
|
criterion = { version = "0.8", features = ["html_reports"] }
|
|
tower = { version = "0.5", features = ["util"] }
|
|
http = "1"
|
|
|
|
[[bench]]
|
|
name = "hot_path"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "throughput"
|
|
harness = false
|
|
|
|
[[bench]]
|
|
name = "dnssec"
|
|
harness = false
|