
numa v0.22.0
Portabler DNS-Resolver in Rust — lokale .numa-Domains, Adblocking, Entwickler-Overrides
Numa
Dein DNS, wohin du auch gehst. — numa.rs
Ein portabler DNS-Resolver in einer einzigen Binärdatei. Blockiere Werbung in jedem Netzwerk, benenne deine lokalen Dienste (frontend.numa), überschreibe beliebige Hostnamen mit automatischem Zurücksetzen und versiegele jede ausgehende Anfrage mit ODoH (RFC 9230), sodass kein einzelner Teilnehmer sowohl deine Identität als auch deine Abfrage sieht – alles von deinem Laptop aus, ohne Cloud-Konto oder Raspberry Pi.
Komplett neu in Rust entwickelt. Keine DNS-Bibliotheken. Caching, Werbeblockierung und lokale Dienstdomänen sofort einsatzbereit. Optionale rekursive Auflösung von Root-Nameservern mit vollständiger DNSSEC-Trust-Chain-Validierung sowie ein DNS-over-TLS-Listener für verschlüsselte Client-Verbindungen (iOS Private DNS, systemd-resolved, usw.). Führe numa relay aus und dieselbe Binärdatei wird zu einem öffentlichen ODoH-Endpunkt – die kuratierte DNSCrypt-Liste hat derzeit nur ein funktionierendes Relay, daher erweitert jede Numa-Installation das Ökosystem spürbar. Eine ~8 MB große Binärdatei, alles inklusive.

Schnellstart
# macOS
brew install razvandimescu/tap/numa
# Linux
curl -fsSL https://raw.githubusercontent.com/razvandimescu/numa/main/install.sh | sh
# Arch Linux
pacman -S numa
# Windows — von GitHub Releases herunterladen
# Alle Plattformen
cargo install numa
# Docker
docker run -d --name numa --network host ghcr.io/razvandimescu/numa
# Nix
nix run github:razvandimescu/numa
sudo numa # im Vordergrund ausführen (Port 53 erfordert root/admin)
Öffne das Dashboard: http://numa.numa (oder http://localhost:5380)
Als System-DNS einrichten:
| Plattform | Installieren | Deinstallieren |
|---|---|---|
| macOS | sudo numa install | sudo numa uninstall |
| Linux | sudo numa install | sudo numa uninstall |
| Windows | numa install (admin) + Neustart | numa uninstall (admin) + Neustart |
Unter macOS und Linux läuft Numa als Systemdienst (launchd/systemd). Unter Windows startet Numa automatisch beim Login über die Registrierung. Windows bindet außerdem 127.0.0.2:53 (der integrierte Dnscache belegt 127.0.0.1:53) und installiert eine NRPT-Regel, um Abfragen dorthin zu leiten – konfiguriere daher bind_addr/api_bind_addr für 127.0.0.2, nicht für 127.0.0.1.
Lokale Dienste
Benenne deine Entwicklungsdienste, statt Portnummern zu merken:
curl -X POST localhost:5380/services \
-d '{"name":"frontend","target_port":5173}'
Jetzt funktioniert https://frontend.numa in deinem Browser – grünes Schloss, gültiges Zertifikat, WebSocket-Passthrough für HMR. Kein mkcert, kein nginx, kein /etc/hosts.
Füge pfadbasiertes Routing hinzu (app.numa/api → :5001), teile Dienste über LAN-Discovery zwischen Rechnern oder konfiguriere alles in numa.toml.
Werbeblockierung & Privatsphäre
385.000+ Domains blockiert via Hagezi Pro. Funktioniert in jedem Netzwerk – Cafés, Hotels, Flughäfen. Reist mit deinem Laptop mit.
Drei Auflösungsmodi:
forward(Standard) – transparenter Proxy zu deinem vorhandenen System-DNS. Alles funktioniert wie zuvor, nur mit zusätzlichem Caching und Werbeblockierung. Captive Portale, VPNs, Firmen-DNS – alles wird respektiert.recursive– Auflösung direkt von Root-Nameservern. Keine Upstream-Abhängigkeit, kein einzelner Teilnehmer sieht dein vollständiges Abfragemuster. Füge[dnssec] enabled = truefür vollständige Trust-Chain-Validierung hinzu.auto– Teste Root-Server beim Start, rekursiv wenn erreichbar, verschlüsselter DoH-Fallback wenn blockiert.
DNSSEC validiert die gesamte Trust-Chain: RRSIG-Signaturen, DNSKEY-Verifikation, DS-Delegation, NSEC/NSEC3-Nachweisbeweise. Lies, wie es funktioniert →
DNS-over-TLS-Listener (RFC 7858) – akzeptiert verschlüsselte Anfragen auf Port 853 von strengen Clients wie iOS Private DNS, systemd-resolved oder stubby. Zwei Modi:
- Selbstsigniert (Standard) – Numa erstellt automatisch eine lokale CA.
numa installfügt sie dem Systemvertrauensspeicher unter macOS, Linux (Debian/Ubuntu, Fedora/RHEL/SUSE, Arch) und Windows hinzu. Unter iOS installiere das.mobileconfigvonnuma setup-phone. Firefox verwendet seinen eigenen NSS-Speicher und ignoriert den Systemvertrauensspeicher – vertraue der CA dort manuell, wenn du HTTPS für.numa-Dienste in Firefox benötigst. - Eigenes Zertifikat – setze
[dot] cert_path/key_pathauf ein öffentlich vertrauenswürdiges Zertifikat (z. B. Let's Encrypt via DNS-01-Challenge auf einer Domain, die auf deine Numa-Instanz zeigt). Clients verbinden sich ohne Einrichtung des Vertrauensspeichers – gleiche Benutzererfahrung wie AdGuard Home oder Cloudflare1.1.1.1.
ALPN "dot" wird in beiden Modi angekündigt und erzwungen; ein Handshake mit nicht übereinstimmendem ALPN wird als Schutz vor Protokollverwechslung abgelehnt.
Phone-Setup – Richte dein iPhone oder Android in einem Schritt auf Numa ein:
numa setup-phone
Druckt einen QR-Code. Scanne ihn, installiere das Profil, aktiviere die Zertifikatvertrauensstellung – das DNS deines Telefons läuft jetzt verschlüsselt über Numa. Erfordert [mobile] enabled = true in numa.toml.
LAN-Discovery
Führe Numa auf mehreren Rechnern aus. Sie finden sich automatisch über mDNS:
Maschine A (192.168.1.5) Maschine B (192.168.1.20)
┌──────────────────────┐ ┌──────────────────────┐
│ Numa │ mDNS │ Numa │
│ - api (Port 8000) │◄───────────►│ - grafana (3000) │
│ - frontend (5173) │ Discovery │ │
└──────────────────────┘ └──────────────────────┘
Von Maschine B: curl http://api.numa → wird an Port 8000 von Maschine A weitergeleitet. Aktiviere mit numa lan on.
Hub-Modus: Betreibe eine Instanz mit bind_addr = "0.0.0.0:53" und richte die DNS anderer Geräte darauf aus – sie erhalten Werbeblockierung + .numa-Auflösung ohne Installation. bind_addr akzeptiert auch eine Liste, um nur eine bestimmte Teilmenge von Schnittstellen zu binden.
Docker
# Empfohlen – Host-Netzwerk (Linux)
docker run -d --name numa --network host ghcr.io/razvandimescu/numa
# Portweiterleitung (macOS/Windows Docker Desktop)
docker run -d --name numa -p 53:53/udp -p 53:53/tcp -p 5380:5380 ghcr.io/razvandimescu/numa
Dashboard unter http://localhost:5380. Das Image bindet API und Proxy standardmäßig an 0.0.0.0. Überschreibe mit einer benutzerdefinierten Konfiguration:
docker run -d --name numa --network host \
-v /path/to/numa.toml:/root/.config/numa/numa.toml \
ghcr.io/razvandimescu/numa
Multi-Arch: linux/amd64 und linux/arm64.
Komplette Compose-Rezepte:
packaging/client/– ODoH-Client-Modus (anonymes DNS), Numa + Starter-numa.toml.packaging/relay/– öffentlicher ODoH-Relay, Numa + Caddy + ACME.
Vergleich
| Pi-hole | AdGuard Home | Unbound | Numa | |
|---|---|---|---|---|
| Lokaler Dienstproxy + automatisches TLS | — | — | — | .numa-Domänen, HTTPS, WebSocket |
| LAN-Dienst-Erkennung | — | — | — | mDNS, keine Konfiguration |
| Entwickler-Überschreibungen (REST-API) | — | — | — | Automatischer Rückfall, skriptbar |
| Rekursiver Resolver | — | — | Ja | Ja, mit SRTT-Auswahl |
| DNSSEC-Validierung | — | — | Ja | Ja (RSA, ECDSA, Ed25519) |
| Werbeblockierung | Ja | Ja | — | 385.000+ Domänen |
| Web-Admin-Oberfläche | Vollständig | Vollständig | — | Dashboard |
| Verschlüsselter Upstream (DoH/DoT) | Benötigt cloudflared | Nur DoH | Nur DoT | DoH + DoT (tls://) |
| Verschlüsselte Clients (DoT-Listener) | Benötigt stunnel sidecar | Ja | Ja | Nativ (RFC 7858) |
| DoH-Server-Endpunkt | — | Ja | — | Ja (RFC 8484) |
| Request-Hedging | — | — | — | Alle Protokolle (UDP, DoH, DoT) |
| Serve-Stale + Prefetch | — | — | Prefetch bei 90 % TTL | RFC 8767, Prefetch bei 90 % TTL |
| Bedingte Weiterleitung | — | Ja | Ja | Ja (pro-Suffix-Regeln) |
| Portabel (Laptop) | Nein (Appliance) | Nein (Appliance) | Server | Einzelne Binärdatei, macOS/Linux/Windows |
| Community-Reife | 56K Stars, 10 Jahre | 33K Stars | 20 Jahre | Neu |
Leistung
0,1 ms bei gecachten Abfragen – gleichauf mit Unbound und AdGuard Home. Der Cache auf Drahtebene speichert Rohbytes mit direktem TTL-Patching. Request-Hedging eliminiert p99-Spitzen: kalte rekursive p99 538 ms vs. Unbound 748 ms (−28 %), σ 4× enger. Benchmarks →
Mehr erfahren
- Blog: Numa als dein Tailnet-Resolver
- Blog: DNS-over-TLS von Grund auf in Rust
- Blog: DNSSEC von Grund auf in Rust implementieren
- Blog: Ich habe einen DNS-Resolver von Grund auf gebaut
- Konfigurationsreferenz – alle Optionen inline dokumentiert
- REST-API – Überschreibungen, Cache, Blockierung, Dienste, Diagnose
- numa-metrics – dauerhafter Abfrageverlauf und Analysen, standardmäßig außerhalb des Hosts (keine SD-Karten-Schreibvorgänge)
Roadmap
- DNS-Weiterleitung, Caching, Werbeblockierung, Entwickler-Überschreibungen
-
.numa-Lokaldomänen – automatisches TLS, Pfadrouting, WebSocket-Proxy - LAN-Dienst-Erkennung – mDNS, geräteübergreifendes DNS + Proxy
- DNS-over-HTTPS – verschlüsselter Upstream + Server-Endpunkt (RFC 8484)
- DNS-over-TLS – verschlüsselter Client-Listener (RFC 7858) + Upstream-Weiterleitung (
tls://) - Oblivious DoH – anonymisierter Client-Modus + öffentlicher Relay (
numa relay, RFC 9230) - Rekursive Auflösung + DNSSEC – Trust-Chain, NSEC/NSEC3
- SRTT-basierte Nameserver-Auswahl
- Multi-Forwarder-Failover – mehrere Upstreams mit SRTT-Ranking, Fallback-Pool
- Request-Hedging – parallele Anfragen retten Paketverluste und Latenzspitzen (alle Protokolle)
- Serve-Stale + Prefetch – RFC 8767, Hintergrundaktualisierung bei <10 % TTL und bei Serve-Stale
- Bedingte Weiterleitung – pro-Suffix-Regeln für Split-Horizon-DNS (Tailscale, VPNs)
- Cache-Warming – proaktive Auflösung für konfigurierte Domänen
- Mobile Onboarding –
setup-phoneQR-Flow, mobile API, mobileconfig-Profile - pkarr-Integration – selbstbestimmtes DNS über Mainline DHT
- Globale
.numa-Namen – DHT-gestützt, kein Registrar
Lizenz
MIT