Blog
-
+
-
+
+ DNS-over-TLS from Scratch in Rust+Building RFC 7858 on top of rustls — length-prefix framing, ALPN cross-protocol defense, iPhone dogfooding, and two bugs that only the strict clients caught.+April 2026+ +
-
Implementing DNSSEC from Scratch in Rustdiff --git a/site/index.html b/site/index.html index 89b68d5..27ea8fb 100644 --- a/site/index.html +++ b/site/index.html @@ -188,11 +188,50 @@ p.lead { line-height: 1.8; } +/* =========================== + TOP NAV + =========================== */ +.site-nav { + padding: 1.5rem 2rem; + display: flex; + align-items: center; + gap: 1.5rem; + position: relative; + z-index: 10; +} + +.site-nav a { + font-family: var(--font-mono); + font-size: 0.75rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: var(--text-dim); + text-decoration: none; + transition: color 0.2s ease; +} +.site-nav a:hover { color: var(--amber); } + +.site-nav .wordmark { + font-family: var(--font-display); + font-size: 1.4rem; + font-weight: 400; + color: var(--text-primary); + text-transform: none; + letter-spacing: -0.02em; +} +.site-nav .wordmark:hover { color: var(--amber); } + +.site-nav .sep { + color: var(--text-dim); + font-family: var(--font-mono); + font-size: 0.75rem; +} + /* =========================== HERO =========================== */ .hero { - min-height: 100vh; + min-height: calc(100vh - 5rem); display: flex; align-items: center; position: relative; @@ -1158,6 +1197,9 @@ footer .closing { @media (max-width: 600px) { section { padding: 4rem 0; } .container { padding: 0 1.25rem; } + .site-nav { padding: 1rem 1.25rem; gap: 1rem; } + .site-nav .wordmark { font-size: 1.2rem; } + .hero { min-height: calc(100vh - 4rem); } .network-grid { grid-template-columns: 1fr; } .pipeline { flex-direction: column; align-items: stretch; gap: 0; } .pipeline-arrow { transform: rotate(90deg); padding: 0.15rem 0; align-self: center; } @@ -1171,6 +1213,14 @@ footer .closing { + +
@@ -1243,6 +1293,8 @@ footer .closing { - Ad & tracker blocking — 385K+ domains, zero config
- Recursive resolution — opt-in, resolve from root nameservers, no upstream needed
- DNSSEC validation — chain-of-trust + NSEC/NSEC3 denial proofs (RSA, ECDSA, Ed25519)
+- DNS-over-TLS listener — encrypted DNS for phones and strict clients (RFC 7858 with ALPN defense)
+- Hostile-network resilience — TCP fallback with UDP auto-disable when ISPs block port 53
- TTL-aware caching (sub-ms lookups)
- Single binary, portable — macOS, Linux, and Windows
Self-Sovereign DNS
- pkarr integration — DNS via Mainline DHT, no registrar needed @@ -1342,6 +1394,14 @@ footer .closing {
- Resolution Modes
- Recursive (iterative from root hints, CNAME chasing, glue extraction) or Forward (DoH / plain UDP) +
- Listeners +
- UDP:53 + TCP:53 (plain DNS), DoT:853 (RFC 7858 + ALPN), HTTP proxy :80 / HTTPS proxy :443, dashboard :5380 +
- DNSSEC
- Chain-of-trust via ring — RSA/SHA-256, ECDSA P-256, Ed25519. NSEC/NSEC3 denial proofs. EDNS0 DO bit, 1232-byte payload (DNS Flag Day 2020).
- Dependencies -
- 19 runtime crates — tokio, axum, hyper, ring (DNSSEC), reqwest (DoH), rcgen + rustls (TLS), socket2 (multicast), serde, and more +
- A focused set — tokio, axum, hyper, ring (DNSSEC), reqwest (DoH), rcgen + rustls + tokio-rustls (TLS/DoT), socket2 (multicast), serde. No transitive DNS library.
- Packet Format
- RFC 1035 compliant. EDNS0 OPT pseudo-record. Parses A, AAAA, NS, CNAME, MX, SOA, SRV, HTTPS, DNSKEY, DS, RRSIG, NSEC, NSEC3. @@ -1586,7 +1657,7 @@ footer .closing { $ curl -fsSL https://raw.githubusercontent.com/razvandimescu/numa/main/install.sh | sh # Run -$ sudo numa # bind to :53, :80, :5380 +$ sudo numa # bind :53, :80, :443, :853, :5380 $ dig @127.0.0.1 google.com # test resolution $ open http://localhost:5380 # dashboard $ curl -X POST localhost:5380/services \ @@ -1639,16 +1710,28 @@ footer .closing { Phase 7 DNSSEC validation — chain-of-trust, NSEC/NSEC3 denial proofs, RSA + ECDSA + Ed25519 -
netsh DNS config, service integration
+