
Resolvedor DNS portátil en Rust — dominios locales .numa, bloqueo de anuncios, anulaciones para desarrolladores
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.

# 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:
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.
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.
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 = true para 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:
numa install la añade al almacén de confianza del sistema en macOS, Linux (Debian/Ubuntu, Fedora/RHEL/SUSE, Arch) y Windows. En iOS, instala el .mobileconfig desde numa 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 .numa en Firefox.[dot] cert_path / key_path a 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 Cloudflare 1.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.
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.
# 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.toml inicial.packaging/relay/ — relay ODoH público, Numa + Caddy + ACME.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 →
.numa — TLS automático, enrutamiento por ruta, proxy WebSockettls://)numa relay, RFC 9230)MIT
| 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 |
| 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 |
setup-phone, API móvil, perfiles mobileconfig.numa globales — respaldados por DHT, sin registrador