
numa v0.23.0
Resolvedor DNS portátil en Rust — dominios locales .numa, bloqueo de anuncios, anulaciones para desarrolladores
Numa
Tu propio DNS. Estés donde estés. — numa.rs
Un resolutor DNS portátil en un único binario. Bloquea anuncios en cualquier red, nombra tus servicios locales (frontend.numa), anula cualquier hostname con reversión automática y sella cada consulta saliente con ODoH (RFC 9230) para que ninguna parte vea a la vez quién eres y qué preguntaste — todo desde tu portátil, sin cuenta en la nube ni Raspberry Pi.
Construido desde cero en Rust. Cero librerías DNS. Caché, bloqueo de anuncios y dominios de servicios locales incluidos de serie. Resolución recursiva opcional desde servidores raíz con validación completa de la cadena de confianza DNSSEC, además de un listener DNS-over-TLS para conexiones de clientes cifradas (iOS Private DNS, systemd-resolved, etc.). Ejecuta numa relay y el mismo binario se convierte también en un endpoint ODoH público — la lista curada DNSCrypt tiene actualmente un relay superviviente, así que cada despliegue de Numa expande materialmente el ecosistema. Un binario de ~8MB, todo embebido.

Inicio rápido
# 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 — download from GitHub Releases
# All platforms
cargo install numa
# Docker
docker run -d --name numa --network host ghcr.io/razvandimescu/numa
# Nix
nix run github:razvandimescu/numa
sudo numa # run in foreground (port 53 requires root/admin)
Abre el panel: http://numa.numa (o http://localhost:5380)
Configura como DNS del sistema:
| Plataforma | Instalar | Desinstalar |
|---|---|---|
| macOS | sudo numa install | sudo numa uninstall |
| Linux | sudo numa install | sudo numa uninstall |
| Windows | numa install (admin) + reinicio | numa uninstall (admin) + reinicio |
En macOS y Linux, numa se ejecuta como un servicio del sistema (launchd/systemd). En Windows, numa se inicia automáticamente al iniciar sesión mediante el registro. Windows también vincula 127.0.0.2:53 (el Dnscache integrado posee 127.0.0.1:53) e instala una regla NRPT para enrutar las consultas hacia él — así que edita bind_addr/api_bind_addr apuntando a 127.0.0.2, no a 127.0.0.1.
Servicios locales
Nombra tus servicios de desarrollo en lugar de recordar números de puerto:
curl -X POST localhost:5380/services \
-d '{"name":"frontend","target_port":5173}'
Ahora https://frontend.numa funciona en tu navegador: candado verde, certificado válido, paso de WebSocket para HMR. Sin mkcert, sin nginx, sin /etc/hosts.
Añade enrutamiento basado en rutas (app.numa/api → :5001), comparte servicios entre máquinas mediante descubrimiento en LAN, o configura todo en numa.toml.
Bloqueo de anuncios y privacidad
Más de 385K dominios bloqueados mediante Hagezi Pro. Funciona en cualquier red: cafeterías, hoteles, aeropuertos. Viaja contigo en tu portátil.
Tres modos de resolución:
forward(predeterminado) — proxy transparente a tu DNS del sistema existente. Todo funciona como antes, solo que con caché y bloqueo de anuncios añadidos. Portales cautivos, VPNs, DNS corporativo: todo se respeta.recursive— resuelve directamente desde los servidores raíz. Sin dependencia de upstream, ninguna entidad ve tu patrón completo de consultas. Añade[dnssec] enabled = truepara la validación completa de la cadena de confianza.auto— sondea los servidores raíz al inicio; recursivo si son alcanzables, con respaldo DoH cifrado si están bloqueados.
DNSSEC valida la cadena de confianza completa: firmas RRSIG, verificación DNSKEY, delegación DS, pruebas de denegación NSEC/NSEC3. Lee cómo funciona →
Listener DNS-over-TLS (RFC 7858) — acepta consultas cifradas en el puerto 853 de clientes estrictos como iOS Private DNS, systemd-resolved o stubby. Dos modos:
- Autofirmado (predeterminado) — numa genera una CA local automáticamente.
numa installla añade al almacén de confianza del sistema en macOS, Linux (Debian/Ubuntu, Fedora/RHEL/SUSE, Arch) y Windows. En iOS, instala el.mobileconfigdesdenuma setup-phone. Firefox mantiene su propio almacén NSS e ignora el del sistema — confía en la CA manualmente allí si necesitas HTTPS para los servicios.numaen Firefox. - Certificado propio — apunta
[dot] cert_path/key_patha un certificado de confianza pública (p. ej., Let's Encrypt mediante el desafío DNS-01 en un dominio que apunte a tu instancia de numa). Los clientes se conectan sin necesidad de configurar el almacén de confianza: la misma UX que AdGuard Home o Cloudflare1.1.1.1.
La ALPN "dot" se anuncia y se aplica en ambos modos; un handshake con ALPN no coincidente se rechaza como defensa contra la confusión entre protocolos.
Configuración del teléfono — apunta tu iPhone o Android a Numa en un solo paso:
numa setup-phone
Imprime un código QR. Escanéalo, instala el perfil, activa la confianza del certificado: el DNS de tu teléfono ahora se enruta a través de Numa sobre TLS. Requiere [mobile] enabled = true en numa.toml.
Descubrimiento en LAN
Ejecuta Numa en varias máquinas. Se encuentran automáticamente mediante mDNS:
Machine A (192.168.1.5) Machine B (192.168.1.20)
┌──────────────────────┐ ┌──────────────────────┐
│ Numa │ mDNS │ Numa │
│ - api (port 8000) │◄───────────►│ - grafana (3000) │
│ - frontend (5173) │ discovery │ │
└──────────────────────┘ └──────────────────────┘
Desde la Máquina B: curl http://api.numa → se proxya al puerto 8000 de la Máquina A. Habilítalo con numa lan on.
Modo hub: ejecuta una instancia con bind_addr = "0.0.0.0:53" y apunta el DNS de otros dispositivos hacia ella: obtienen bloqueo de anuncios + resolución .numa sin instalar nada. bind_addr también acepta una lista para vincular un subconjunto específico de interfaces.
Docker
# Recommended — host networking (Linux)
docker run -d --name numa --network host ghcr.io/razvandimescu/numa
# Port mapping (macOS/Windows Docker Desktop)
docker run -d --name numa -p 53:53/udp -p 53:53/tcp -p 5380:5380 ghcr.io/razvandimescu/numa
Panel en http://localhost:5380. La imagen vincula la API y el proxy a 0.0.0.0 por defecto. Anula esto con una configuración personalizada:
docker run -d --name numa --network host \
-v /path/to/numa.toml:/root/.config/numa/numa.toml \
ghcr.io/razvandimescu/numa
Multi-arquitectura: linux/amd64 y linux/arm64.
Recetas compose listas para usar:
packaging/client/— modo cliente ODoH (DNS anónimo), Numa +numa.tomlinicial.packaging/relay/— relay ODoH público, Numa + Caddy + ACME.
Comparativa
| Pi-hole | AdGuard Home | Unbound | Numa | |
|---|---|---|---|---|
| Proxy de servicios locales + TLS automático | — | — | — | dominios .numa, HTTPS, WebSocket |
| Descubrimiento de servicios en LAN | — | — | — | mDNS, cero configuración |
| Anulaciones para desarrolladores (REST API) | — | — | — | Reversión automática, programable |
| Resolutor recursivo | — | — | Sí | Sí, con selección SRTT |
| Validación DNSSEC | — | — | Sí | Sí (RSA, ECDSA, Ed25519) |
| Bloqueo de anuncios | Sí | Sí | — | 385K+ dominios |
| Interfaz web de administración | Completo | Completo | — | Panel |
| Upstream cifrado (DoH/DoT) | Necesita cloudflared | Solo DoH | Solo DoT | DoH + DoT (tls://) |
| Clientes cifrados (listener DoT) | Necesita sidecar stunnel | Sí | Sí | Nativo (RFC 7858) |
| Endpoint de servidor DoH | — | Sí | — | Sí (RFC 8484) |
| Hedging de peticiones | — | — | — | Todos los protocolos (UDP, DoH, DoT) |
| Serve-stale + prefetch | — | — | Prefetch al 90% TTL | RFC 8767, prefetch al 90% TTL |
| Reenvío condicional | — | Sí | Sí | Sí (reglas por sufijo) |
| Portátil (laptop) | No (appliance) | No (appliance) | Servidor | Binario único, macOS/Linux/Windows |
| Madurez de la comunidad | 56K estrellas, 10 años | 33K estrellas | 20 años | Nuevo |
Rendimiento
Consultas en caché de 0.1ms — a la par de Unbound y AdGuard Home. La caché a nivel de wire almacena bytes sin procesar con parcheo de TTL in situ. El hedging de peticiones elimina los picos de p99: p99 recursivo en frío de 538ms frente a 748ms de Unbound (−28%), σ 4× más ajustada. Benchmarks →
Aprende más
- Blog: Numa como resolutor de tu tailnet
- Blog: DNS-over-TLS desde cero en Rust
- Blog: Implementando DNSSEC desde cero en Rust
- Blog: Construí un resolutor DNS desde cero
- Referencia de configuración — todas las opciones documentadas inline
- API REST — anulaciones, caché, bloqueo, servicios, diagnósticos
- numa-metrics — historial de consultas duradero y analíticas, fuera del host por diseño (sin escrituras en la tarjeta SD)
Hoja de ruta
- Reenvío DNS, caché, bloqueo de anuncios, anulaciones para desarrolladores
- Dominios locales
.numa— TLS automático, enrutamiento por ruta, proxy WebSocket - Descubrimiento de servicios en LAN — mDNS, DNS y proxy entre máquinas
- DNS-over-HTTPS — upstream cifrado + endpoint de servidor (RFC 8484)
- DNS-over-TLS — listener de cliente cifrado (RFC 7858) + reenvío upstream (
tls://) - Oblivious DoH — modo cliente anonimizado + relay público (
numa relay, RFC 9230) - Resolución recursiva + DNSSEC — cadena de confianza, NSEC/NSEC3
- Selección de nameservers basada en SRTT
- Failover multi-forwarder — múltiples upstreams con clasificación SRTT, pool de respaldo
- Hedging de peticiones — las peticiones paralelas rescatan la pérdida de paquetes y la latencia de cola (todos los protocolos)
- Serve-stale + prefetch — RFC 8767, refresco en segundo plano a <10% TTL y al servir obsoleto
- Reenvío condicional — reglas por sufijo para DNS split-horizon (Tailscale, VPNs)
- Calentamiento de caché — resolución proactiva para dominios configurados
- Onboarding móvil — flujo QR de
setup-phone, API móvil, perfiles mobileconfig - Integración pkarr — DNS autosoberano mediante Mainline DHT
- Nombres
.numaglobales — respaldados por DHT, sin registrador
Licencia
MIT