--- title: "Cómo instalar Unbound como resolvedor DNS en Ubuntu 24.04" description: "Instala Unbound en Ubuntu 24.04 como resolvedor DNS recursivo con validación DNSSEC, acceso limitado a tu red privada, zonas locales y reenvío por DNS-over-TLS." category: "DNS Avanzado" language: es source: https://cubepath.com/es/docs/dns-avanzado/instalacion-de-unbound-resolvedor-dns updated: 2026-09-25 --- # Cómo instalar Unbound como resolvedor DNS en Ubuntu 24.04 Unbound es un resolvedor DNS recursivo, validador y con caché, desarrollado por NLnet Labs. En lugar de enviar tus consultas a un resolvedor de terceros, Unbound las resuelve él mismo desde los servidores raíz, valida las firmas DNSSEC y guarda las respuestas en caché. En este tutorial lo instalarás en Ubuntu 24.04 como resolvedor para el propio servidor y para las máquinas de tu red privada, con nombres internos propios y, opcionalmente, reenvío cifrado por DNS-over-TLS. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 512 MB de RAM. - Un usuario no root con privilegios `sudo`. - Si otras máquinas van a usar el resolvedor: una red privada entre ellas. En los ejemplos la red es `10.0.0.0/24` y el servidor Unbound tiene la IP privada `10.0.0.5`; sustitúyelas por las tuyas. > Advertencia: nunca expongas un resolvedor recursivo a todo Internet. Un resolvedor abierto se usa para ataques de amplificación DNS. En esta guía Unbound solo escucha en localhost y en la IP privada, y solo acepta consultas de tu red. ## Paso 1: Instalar Unbound Instala Unbound y las utilidades `dig`: ```bash sudo apt update sudo apt install unbound dnsutils ``` Comprueba la versión y el estado del servicio: ```bash unbound -V | head -n 1 systemctl status unbound --no-pager ``` ```output Version 1.19.2 ... Active: active (running) ``` Con la configuración por defecto de Ubuntu, Unbound escucha solo en `127.0.0.1` y `::1`, por lo que no choca con `systemd-resolved`, que usa `127.0.0.53`. El paquete ya incluye dos ficheros en `/etc/unbound/unbound.conf.d/`: - `root-auto-trust-anchor-file.conf`: activa la validación DNSSEC con el ancla de confianza de la raíz, que el servicio actualiza automáticamente en cada arranque. - `remote-control.conf`: habilita `unbound-control` a través de un socket local, sin certificados. Haz una primera consulta para confirmar que resuelve: ```bash dig @127.0.0.1 cubepath.com +short ``` Debe devolver una o varias IP. ## Paso 2: Configurar el resolvedor Crea tu configuración en un fichero aparte dentro de `unbound.conf.d`, así las actualizaciones del paquete no la sobrescriben: ```bash sudo nano /etc/unbound/unbound.conf.d/resolver.conf ``` ```text server: # Direcciones en las que escucha (localhost y la IP privada) interface: 127.0.0.1 interface: ::1 interface: 10.0.0.5 # Permite arrancar aunque la IP privada aún no esté configurada ip-freebind: yes # Quién puede hacer consultas. Todo lo demás se rechaza. access-control: 127.0.0.0/8 allow access-control: ::1/128 allow access-control: 10.0.0.0/24 allow # Un hilo por núcleo de CPU num-threads: 2 # Caché: rrset-cache-size debe ser el doble de msg-cache-size msg-cache-size: 64m rrset-cache-size: 128m # Renueva las entradas populares antes de que caduquen prefetch: yes prefetch-key: yes # No revela versión ni identidad a quien pregunte hide-identity: yes hide-version: yes # Protección contra DNS rebinding: una respuesta de Internet # no puede apuntar a direcciones privadas private-address: 10.0.0.0/8 private-address: 172.16.0.0/12 private-address: 192.168.0.0/16 private-address: 169.254.0.0/16 private-address: fd00::/8 private-address: fe80::/10 ``` Ajusta `num-threads` al número de núcleos (`nproc`) y el tamaño de la caché a la RAM disponible. Valida la sintaxis y reinicia: ```bash sudo unbound-checkconf sudo systemctl restart unbound ``` ```output unbound-checkconf: no errors in /etc/unbound/unbound.conf ``` Comprueba que Unbound escucha en las tres direcciones: ```bash sudo ss -lnup 'sport = :53' ``` Deben aparecer `127.0.0.1:53`, `[::1]:53` y `10.0.0.5:53` asociados al proceso `unbound`, además de `127.0.0.53` de `systemd-resolved`. ## Paso 3: Permitir las consultas de la red privada Si UFW está activo, permite el puerto 53 solo desde la red privada: ```bash sudo ufw allow from 10.0.0.0/24 to any port 53 sudo ufw status ``` Desde otra máquina de la red, consulta al resolvedor: ```bash dig @10.0.0.5 cubepath.com +short ``` Si obtienes `status: REFUSED`, la IP del cliente no está cubierta por ninguna línea `access-control`. ## Paso 4: Comprobar la validación DNSSEC Un dominio firmado correctamente debe devolver el flag `ad` (*authenticated data*): ```bash dig @127.0.0.1 isc.org SOA +dnssec | grep flags ``` ```output ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ``` Y un dominio con la firma rota a propósito debe fallar: ```bash dig @127.0.0.1 dnssec-failed.org | grep status ``` ```output ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 41253 ``` Ese SERVFAIL es el comportamiento correcto: Unbound se niega a entregar una respuesta que no puede validar. ## Paso 5: Usar Unbound como resolvedor del servidor `systemd-resolved` sigue siendo el resolvedor del sistema y reenvía a los DNS que recibe por DHCP. Para que el propio servidor use Unbound, indícaselo con un fichero adicional: ```bash sudo mkdir -p /etc/systemd/resolved.conf.d sudo nano /etc/systemd/resolved.conf.d/unbound.conf ``` ```ini [Resolve] DNS=127.0.0.1 Domains=~. ``` `Domains=~.` hace que todas las consultas vayan a ese servidor y no a los DNS de la interfaz. Aplica y verifica: ```bash sudo systemctl restart systemd-resolved resolvectl status | grep 'DNS Server' ``` ```output Current DNS Server: 127.0.0.1 DNS Servers: 127.0.0.1 ``` Repite este mismo fichero en los demás servidores de la red, cambiando `127.0.0.1` por `10.0.0.5`. ## Paso 6: Añadir nombres internos Unbound puede responder por nombres que solo existen en tu red, sin montar un servidor autoritativo. Usa el dominio `.internal`, reservado para este uso. Crea un fichero para ellos: ```bash sudo nano /etc/unbound/unbound.conf.d/local-zones.conf ``` ```text server: local-zone: "internal." static local-data: "web.internal. 3600 IN A 10.0.0.10" local-data: "db.internal. 3600 IN A 10.0.0.20" local-data-ptr: "10.0.0.10 web.internal" local-data-ptr: "10.0.0.20 db.internal" # Bloquear un dominio concreto local-zone: "ads.example.com." always_nxdomain ``` El tipo `static` responde con los datos definidos y devuelve NXDOMAIN para cualquier otro nombre bajo `internal.`, sin preguntar a Internet. Aplica y comprueba: ```bash sudo unbound-checkconf sudo systemctl restart unbound dig @127.0.0.1 web.internal +short dig @127.0.0.1 -x 10.0.0.10 +short ``` ```output 10.0.0.10 web.internal. ``` ## Paso 7 (opcional): Reenviar por DNS-over-TLS Por defecto Unbound resuelve de forma recursiva y sus consultas salen sin cifrar hacia los servidores autoritativos. Si prefieres que todo el tráfico salga cifrado hacia un resolvedor de confianza, reenvía por DNS-over-TLS. A cambio, ese proveedor verá tus consultas. ```bash sudo nano /etc/unbound/unbound.conf.d/forward-tls.conf ``` ```text server: tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt forward-zone: name: "." forward-tls-upstream: yes forward-addr: 1.1.1.1@853#cloudflare-dns.com forward-addr: 1.0.0.1@853#cloudflare-dns.com forward-addr: 9.9.9.9@853#dns.quad9.net forward-addr: 149.112.112.112@853#dns.quad9.net ``` El nombre tras `#` es el que Unbound comprueba en el certificado del servidor, y `tls-cert-bundle` le indica dónde están las CA del sistema. Sin esa línea no verifica el certificado. Aplica y comprueba: ```bash sudo unbound-checkconf sudo systemctl restart unbound sudo unbound-control list_forwards dig @127.0.0.1 cubepath.com +short ``` `list_forwards` debe mostrar la zona `.` con las cuatro direcciones configuradas, y `dig` debe seguir devolviendo IP. La validación DNSSEC sigue funcionando con reenvío: repite las pruebas del paso 4. ## Paso 8: Consultar estadísticas y vaciar la caché `unbound-control` permite ver el estado del resolvedor sin reiniciarlo. Muestra las estadísticas principales sin ponerlas a cero: ```bash sudo unbound-control stats_noreset | grep -E '^total\.num\.(queries|cachehits|cachemiss)=' ``` ```output total.num.queries=1532 total.num.cachehits=1204 total.num.cachemiss=328 ``` Para forzar que un dominio se vuelva a resolver (por ejemplo, tras cambiar sus registros): ```bash sudo unbound-control flush_zone your_domain ``` Para ver por dónde resolvería Unbound un nombre: ```bash sudo unbound-control lookup cubepath.com ``` ## Solución de problemas - **Unbound no arranca con "can't bind socket: Address already in use"**: has puesto `interface: 0.0.0.0` y choca con `systemd-resolved`. Usa direcciones concretas como en el paso 2. - **`status: REFUSED` desde un cliente**: falta su red en `access-control`. - **`status: SERVFAIL` en todos los dominios**: suele ser la hora del sistema (DNSSEC depende de ella) o que el servidor no llega a Internet por el puerto 53. Comprueba `timedatectl` y `dig @1.1.1.1 cubepath.com`. - **Depurar una consulta concreta**: sube temporalmente el nivel de log con `sudo unbound-control verbosity 3`, reproduce el fallo, revisa `sudo journalctl -u unbound -n 100` y vuelve a `sudo unbound-control verbosity 1`. ## Conclusión Unbound ya resuelve DNS para el servidor y para tu red privada, valida DNSSEC, responde por los nombres internos de `.internal` y, si lo activaste, cifra el tráfico de salida con DNS-over-TLS. Como siguientes pasos puedes ofrecer DNS-over-TLS y DNS-over-HTTPS a tus propios clientes con Unbound, o combinarlo con Pi-hole o AdGuard Home como resolvedor de origen para bloquear publicidad sin depender de un proveedor externo.