From f5bd2da608cb9557ccfb9bd5b64f79e832162270 Mon Sep 17 00:00:00 2001 From: Razvan Dimescu Date: Fri, 10 Apr 2026 19:20:12 +0300 Subject: [PATCH] chore: site navbar, updated roadmap, DoT blog listing, spec updates - Add top nav bar to landing page (wordmark + links, responsive) - Add DoT blog post entry to blog index - Update roadmap: phases 8-13 (hostile-network, Windows, DoT shipped) - Update specs: listeners section, dependency description, port list - Blog: hostile-network SVG in DNSSEC post, text-transform fix - Blog template: wordmark text-transform fix Co-Authored-By: Claude Opus 4.6 (1M context) --- blog/dnssec-from-scratch.md | 6 +-- site/blog-template.html | 1 + site/blog/index.html | 8 +++ site/index.html | 97 ++++++++++++++++++++++++++++++++++--- 4 files changed, 102 insertions(+), 10 deletions(-) diff --git a/blog/dnssec-from-scratch.md b/blog/dnssec-from-scratch.md index 208bc53..01bc5c5 100644 --- a/blog/dnssec-from-scratch.md +++ b/blog/dnssec-from-scratch.md @@ -163,12 +163,12 @@ The fix has three parts: **TCP fallback.** Every outbound query tries UDP first (800ms timeout). If UDP fails or the response is truncated, retry immediately over TCP. TCP uses a 2-byte length prefix before the DNS message — trivial to implement, and it handles DNSSEC responses that exceed the UDP payload limit. -**UDP auto-disable.** After 3 consecutive UDP failures, flip a global `AtomicBool` and skip UDP entirely — go TCP-first for all queries. This avoids burning 800ms per hop on a network where UDP will never work. The flag resets when the network changes (detected via LAN IP monitoring). +**UDP auto-disable.** After 3 consecutive UDP failures, flip a global `AtomicBool` and skip UDP entirely — go TCP-first for all queries. The flag resets when the network changes (detected via LAN IP monitoring). + +Latency profile on a hostile network: queries 1-3 each spend 800ms waiting for a UDP timeout before retrying over TCP, taking 1,100ms total per query. After 3 consecutive failures the UDP auto-disable flag flips, and queries 4+ go TCP-first and complete in 300ms each — 3.7× faster. **Query minimization (RFC 7816).** When querying root servers, send only the TLD — `com` instead of `secret-project.example.com`. Root servers handle trillions of queries and are operated by 12 organizations. Minimization reduces what they learn from yours. -The result: on a network that blocks UDP:53, Numa detects the block within the first 3 queries, switches to TCP, and resolves normally at 300-500ms per cold query. Cached queries remain 0ms. No manual config change needed — switch networks and it adapts. - I wouldn't have found this without dogfooding. The code worked perfectly on my home network. It took a real hostile network to expose the assumption that UDP always works. ## What I learned diff --git a/site/blog-template.html b/site/blog-template.html index 4c0defe..85e854b 100644 --- a/site/blog-template.html +++ b/site/blog-template.html @@ -74,6 +74,7 @@ body::before { font-weight: 400; color: var(--text-primary); text-decoration: none; + text-transform: none; letter-spacing: -0.02em; } .blog-nav .wordmark:hover { color: var(--amber); } diff --git a/site/blog/index.html b/site/blog/index.html index 9447e0d..10d62a7 100644 --- a/site/blog/index.html +++ b/site/blog/index.html @@ -67,6 +67,7 @@ body::before { font-weight: 400; color: var(--text-primary); text-decoration: none; + text-transform: none; letter-spacing: -0.02em; } .blog-nav .wordmark:hover { color: var(--amber); } @@ -167,6 +168,13 @@ body::before {

Blog

@@ -1261,7 +1313,7 @@ footer .closing {
-
Coming Next
+
The Vision

Self-Sovereign DNS

  • pkarr integration — DNS via Mainline DHT, no registrar needed
  • @@ -1342,6 +1394,14 @@ footer .closing { No Root hints + full DNSSEC + + DNSSEC validation + Passthrough + Cloud only + Cloud only + Passthrough + Full chain-of-trust + Ad & tracker blocking Yes @@ -1398,6 +1458,14 @@ footer .closing { No Built in (HTTP/2 + rustls) + + DNS-over-TLS listener + No + Cloud only + Cloud only + Yes (cert required) + Self-signed or BYO + Conditional forwarding No @@ -1567,11 +1635,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
-
+
Phase 8 + Hostile-network resilience — TCP fallback with UDP auto-disable when ISPs block :53, RFC 7816 query minimization +
+
+ Phase 9 + Windows support — cross-platform install/uninstall, netsh DNS config, service integration +
+
+ Phase 10 + DNS-over-TLS listener (RFC 7858) — ALPN enforcement, persistent connections, self-signed or BYO cert +
+
+ Phase 11 pkarr integration — self-sovereign DNS via Mainline DHT, no registrar needed
- Phase 9 + Phase 12 Global .numa names — self-publish, DHT-backed, first-come-first-served
- Phase 10 + Phase 13 .onion bridge — human-readable Tor naming via Ed25519 same-key binding