Unbound puede actuar como resolvedor recursivo con caché para un servidor Ubuntu: consulta la jerarquía DNS, conserva las respuestas durante su TTL y valida firmas DNSSEC antes de entregar los datos.
En esta guía, systemd-resolved mantiene el stub local de Ubuntu en 127.0.0.53:53, mientras que Unbound escucha en 127.0.0.1:5335. Esta separación evita que ambos servicios compitan por el puerto 53 y permite que las aplicaciones continúen utilizando la resolución normal del sistema.
Resultado esperado: las aplicaciones consultarán asystemd-resolved; este enviará las consultas DNS unicast a Unbound; las respuestas firmadas válidas serán aceptadas y un dominio deliberadamente roto por DNSSEC devolveráSERVFAIL.
Qué resuelve y qué no
Unbound realizará:
- Recursión desde los servidores raíz hasta los servidores autoritativos.
- Caché de respuestas respetando sus TTL.
- Validación DNSSEC mediante el trust anchor de la raíz.
- Minimización de QNAME para reducir la información enviada durante la recursión.
DNSSEC autentica la procedencia y la integridad de los datos DNS. No cifra las consultas ni oculta las direcciones de los servidores consultados.
Esta guía tampoco configura DNS-over-TLS, DNS-over-HTTPS, bloqueo publicitario ni zonas DNS autoritativas.
Requisitos previos
- Ubuntu Server 24.04 LTS o compatible.
- Acceso mediante
sudo. - Una consola alternativa abierta durante el cambio.
- Conectividad saliente UDP y TCP hacia el puerto 53.
- Reloj sincronizado.
- Backup de la configuración DNS actual.
- Herramientas
dig,resolvectl,ssyjournalctl. - Para atender una LAN: IP privada fija, CIDR autorizado y firewall configurable.
Seguridad: el procedimiento principal escucha exclusivamente en loopback. No uses interface: 0.0.0.0 ni abras UDP/TCP 53 hacia Internet. Un resolvedor recursivo abierto puede utilizarse en ataques de amplificación.Paso 1: inventariar la configuración actual
Registra el reloj, la resolución activa y los puertos ocupados:
date -u
timedatectl status
timedatectl show -p NTPSynchronized
resolvectl status
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
sudo ss -lntup | grep -E ':(53|5335)\b' || true
dig @127.0.0.53 example.com A +statsEn Ubuntu 24.04 es habitual que /etc/resolv.conf apunte a /run/systemd/resolve/stub-resolv.conf y que systemd-resolved escuche en 127.0.0.53:53.
No reemplaces ese enlace ni desactives systemd-resolved como primera opción.
Revisa también los DNS asignados a cada interfaz:
resolvectl dns
resolvectl domainLos servidores recibidos por DHCP, Netplan o una VPN podrían competir posteriormente con la ruta global.
Paso 2: instalar Unbound y crear un backup
Instala el servicio, la utilidad de trust anchors y las herramientas DNS:
sudo apt update
sudo apt install unbound unbound-anchor dnsutils
unbound -V
unbound-checkconf -h | headEn Ubuntu 24.04, unbound-anchor se distribuye como paquete independiente. Instalarlo explícitamente evita que la recuperación del trust anchor falle con command not found. Paquete oficial de Ubuntu.
El paquete puede iniciar Unbound automáticamente. Comprueba de nuevo los listeners antes de continuar.
Crea un backup privado:
STAMP=$(date -u +%Y%m%dT%H%M%SZ)
BACKUP_DIR="$HOME/unbound-backup-$STAMP"
install -d -m 0700 "$BACKUP_DIR"
sudo cp -a /etc/unbound "$BACKUP_DIR/"
sudo cp -a /etc/systemd/resolved.conf "$BACKUP_DIR/"
if [ -d /etc/systemd/resolved.conf.d ]; then
sudo cp -a /etc/systemd/resolved.conf.d "$BACKUP_DIR/"
fi
readlink -f /etc/resolv.conf \
> "$BACKUP_DIR/resolv-conf-target.txt"
sudo chown -R "$USER":"$USER" "$BACKUP_DIR"
printf '%s\n' "$BACKUP_DIR" \
> "$HOME/.unbound-backup-last"
chmod 0600 "$HOME/.unbound-backup-last"El archivo ~/.unbound-backup-last conserva la ruta seleccionada y permite recuperarla después de una desconexión o en otra sesión.
El backup contiene configuración, pero no garantiza el acceso a la red del proveedor. Mantén abierta una consola alternativa durante el cambio.
Paso 3: comprobar el trust anchor
Los paquetes Debian y Ubuntu suelen incluir un archivo dentro de /etc/unbound/unbound.conf.d/ que declara:
auto-trust-anchor-file: "/var/lib/unbound/root.key"Comprueba primero la configuración instalada:
sudo grep -RnsE \
'^[[:space:]]*(auto-)?trust-anchor-file:' \
/etc/unbound/unbound.conf \
/etc/unbound/unbound.conf.d \
2>/dev/null || true
sudo -u unbound test -r /var/lib/unbound/root.key
sudo -u unbound test -w /var/lib/unbound/root.key
sudo -u unbound test -w /var/lib/unboundUnbound debe poder leer y actualizar el archivo y su directorio para realizar el seguimiento definido por RFC 5011.
No declares dos veces auto-trust-anchor-file. La duplicación de trust anchors para la misma zona puede impedir el inicio del servicio.
Si la configuración declara /var/lib/unbound/root.key, pero el archivo no existe, inicialízalo mediante el usuario del servicio:
sudo -u unbound unbound-anchor \
-a /var/lib/unbound/root.key
ANCHOR_RC=$?
printf 'unbound-anchor exit=%s\n' "$ANCHOR_RC"En unbound-anchor, el código de salida 1 también puede indicar que el anchor fue instalado o actualizado. No debe interpretarse automáticamente como un fallo: revisa el archivo, sus permisos y ejecuta después unbound-checkconf.
Unbound dispone de root hints internos. No es obligatorio descargar un archivo root.hints. Si decides administrarlo manualmente, deberás verificar su origen y mantenerlo actualizado.
Paso 4: crear la configuración local
Comprueba si IPv6 loopback está disponible:
ip -6 address show dev loCrea /etc/unbound/unbound.conf.d/20-local-recursive.conf mediante sudoedit:
server:
interface: 127.0.0.1@5335
interface: ::1@5335
access-control: 127.0.0.0/8 allow
access-control: ::1/128 allow
do-udp: yes
do-tcp: yes
hide-identity: yes
hide-version: yes
qname-minimisation: yes
aggressive-nsec: yes
harden-dnssec-stripped: yes
prefetch: yesSi IPv6 está deshabilitado y no aparece ::1, omite estas dos líneas:
interface: ::1@5335
access-control: ::1/128 allowNo añadas auto-trust-anchor-file si el paquete ya lo declaró.
Tampoco expongas remote-control mediante una interfaz TCP. El paquete puede proporcionar control local seguro; no hace falta reemplazarlo ni regenerar claves si no utilizarás unbound-control.
La configuración realiza recursión directa. Unbound consultará servidores raíz, TLD y autoritativos mediante UDP o TCP 53.
Paso 5: validar antes de reiniciar
Valida toda la configuración:
sudo unbound-checkconfResultado esperado:
unbound-checkconf: no errors in /etc/unbound/unbound.confSi aparece un trust anchor duplicado, una ruta inaccesible, una interfaz inexistente o un error de sintaxis, corrígelo antes de modificar systemd-resolved.
Reinicia Unbound:
sudo systemctl restart unbound
sudo systemctl --no-pager --full status unbound
sudo ss -lntup | grep ':5335'
sudo journalctl \
-u unbound \
--since '-5 minutes' \
--no-pagerDurante el recorrido local debe escuchar exclusivamente en:
127.0.0.1:5335
[::1]:5335Paso 6: probar Unbound directamente
No cambies todavía la resolución del sistema. Prueba primero el nuevo servicio:
dig @127.0.0.1 -p 5335 \
cloudflare.com A +dnssec +multi
dig @127.0.0.1 -p 5335 \
cloudflare.com A +dnssec +tcp
dig @127.0.0.1 -p 5335 \
. DNSKEY +dnssec +multiPara una respuesta firmada y validada, busca:
status: NOERROR
flags: ... ad ...La prueba con +tcp confirma que el resolvedor no depende exclusivamente de UDP.
Prueba ahora el dominio deliberadamente roto recomendado por ICANN:
dig @127.0.0.1 -p 5335 \
dnssec-failed.org A +dnssecResultado esperado:
status: SERVFAILPara observar la respuesta subyacente desactivando la comprobación únicamente en esa consulta:
dig @127.0.0.1 -p 5335 \
dnssec-failed.org A +dnssec +cdflag+cdflag es una herramienta de diagnóstico. No debe convertirse en la configuración habitual de los clientes
Paso 7: integrar systemd-resolved
Ubuntu 24.04 permite especificar un puerto en la opción DNS=. Crea /etc/systemd/resolved.conf.d/60-unbound.conf:
[Resolve]
DNS=127.0.0.1:5335
FallbackDNS=
Domains=~.
DNSSEC=noDNSSEC=no evita una segunda capa de validación dentro de systemd-resolved. La política de aceptar o rechazar datos ya la aplicará Unbound.
Por este motivo, la bandera ad debe comprobarse directamente contra Unbound. La ruta completa se validará mediante sus resultados y la prueba negativa.
FallbackDNS= vacío elimina los fallbacks compilados, pero no necesariamente los DNS recibidos por DHCP, Netplan o una VPN. Estos servidores pueden continuar asociados a interfaces concretas.
Reinicia el stub y limpia su caché:
sudo systemctl restart systemd-resolved
sudo resolvectl flush-caches
resolvectl status
sudo journalctl \
-u systemd-resolved \
--since '-5 minutes' \
--no-pagerEl DNS global debe mostrar:
127.0.0.1:5335El stub debe continuar disponible para las aplicaciones en 127.0.0.53:53.
Paso 8: probar la ruta completa
Ejecuta:
resolvectl query cloudflare.com
getent ahosts cloudflare.com
dig @127.0.0.53 cloudflare.com A +dnssec
dig @127.0.0.53 dnssec-failed.org A +dnssecLa consulta normal debe resolverse. El dominio deliberadamente inválido debe devolver SERVFAIL.
Si devuelve NOERROR, comprueba en resolvectl status que systemd-resolved no esté enviando la consulta a otro servidor DNS por interfaz o VPN.
Ejecuta dos veces una consulta directa:
dig @127.0.0.1 -p 5335 www.iana.org A +stats
dig @127.0.0.1 -p 5335 www.iana.org A +statsUna segunda respuesta más rápida y con un TTL inferior es una señal de caché, pero no constituye una medición concluyente. Para evaluar rendimiento, utiliza varias consultas y una carga representativa.
Puerta de aceptación
- Unbound escucha únicamente en loopback:5335.
- UDP y TCP responden.
- El dominio firmado valida correctamente.
- La prueba DNSSEC bogus devuelve
SERVFAIL. resolvectlmuestra Unbound como DNS global.getenty las aplicaciones resuelven.- No hay errores persistentes en los journals.
- El reloj permanece sincronizado.
Modo LAN opcional
Para atender clientes de una red privada, añade una dirección que exista realmente en el servidor y el CIDR mínimo necesario:
server:
interface: 10.0.0.53@53
access-control: 10.0.0.0/24 allowAdapta las direcciones a tu red. Antes de reiniciar:
sudo unbound-checkconf
ip address showPermite UDP y TCP 53 exclusivamente desde el CIDR autorizado en:
- El firewall del host.
- El firewall o security group del proveedor.
- Las ACL intermedias.
Desde un cliente autorizado:
dig @10.0.0.53 cloudflare.com A +dnssec
dig @10.0.0.53 cloudflare.com A +dnssec +tcp
dig @10.0.0.53 dnssec-failed.org A +dnssecDesde un origen no autorizado, la consulta debe rechazarse o no alcanzar el servicio.
Verifica con ss que Unbound no esté escuchando en una interfaz pública imprevista.
Rollback
Recupera y valida la ruta persistida del backup:
test -s "$HOME/.unbound-backup-last" || {
printf 'No se encontró la referencia del backup.\n' >&2
exit 1
}
BACKUP_DIR=$(cat "$HOME/.unbound-backup-last")
test -d "$BACKUP_DIR" || {
printf 'No existe el backup: %s\n' "$BACKUP_DIR" >&2
exit 1
}Revierte primero la ruta del sistema mientras Unbound continúa disponible:
test -f \
/etc/systemd/resolved.conf.d/60-unbound.conf
sudo mv \
/etc/systemd/resolved.conf.d/60-unbound.conf \
"$BACKUP_DIR/60-unbound.conf.disabled"
sudo systemctl restart systemd-resolved
sudo resolvectl flush-caches
resolvectl status
getent ahosts example.comConfirma que systemd-resolved recuperó los servidores anteriores.
Después puedes retirar la configuración personalizada de Unbound:
test -f \
/etc/unbound/unbound.conf.d/20-local-recursive.conf
sudo mv \
/etc/unbound/unbound.conf.d/20-local-recursive.conf \
"$BACKUP_DIR/20-local-recursive.conf.disabled"
sudo unbound-checkconf
sudo systemctl restart unboundSi habilitaste el modo LAN, elimina también las reglas UDP/TCP 53 del firewall del host, del firewall perimetral y de las ACL intermedias.
Comprueba desde un origen no autorizado que el servidor ya no responde y revisa los listeners mediante ss.
No modifiques manualmente /etc/resolv.conf mientras continúe gestionado por systemd-resolved.
Problemas frecuentes
Unbound no inicia por el puerto
Ejecuta:
sudo ss -lntup | grep -E ':(53|5335)\b'Revisa cada dirección, no solo el puerto. 127.0.0.53:53 y 127.0.0.1:5335 no entran en conflicto.
Busca configuraciones adicionales que declaren interface: 0.0.0.0, otra dirección ocupada o el puerto 53.
Aparece un error relacionado con root.key
Comprueba:
- Que exista un único
auto-trust-anchor-file. - Que el usuario
unboundpueda leer y escribir el archivo. - Que pueda actualizar su directorio.
- Que el reloj esté sincronizado.
- Que
unbound-anchoresté instalado.
No borres ni descargues claves sin comprender primero el mecanismo del paquete.
Las consultas normales funcionan, pero DNSSEC falla
Revisa:
- Reloj del sistema.
- Trust anchor.
- Salida UDP y TCP 53.
- Fragmentación de red.
- Journal de Unbound.
- Consulta directa contra
127.0.0.1:5335.
La consulta directa permite separar un problema de Unbound de uno relacionado con systemd-resolved.
dnssec-failed.org devuelve NOERROR por la ruta del sistema
Es probable que la consulta utilice otro DNS instalado por DHCP, Netplan o una VPN.
Inspecciona:
resolvectl status
resolvectl dns
resolvectl domainUn dominio sin DNSSEC no presenta la bandera AD
Es un resultado válido. Una zona insegura legítima puede devolver NOERROR sin ad.
DNSSEC distingue entre estados seguro, inseguro y bogus; no exige que todos los dominios estén firmados.
Los clientes LAN no pueden consultar
Comprueba:
- Dirección de escucha.
- ACL de Unbound.
- UDP y TCP 53.
- Firewall del host.
- Firewall perimetral.
- Security groups.
- Rutas entre cliente y servidor.
No amplíes la ACL a 0.0.0.0/0 para ocultar el problema.
Buenas prácticas
- Mantén actualizados Unbound,
unbound-anchorydns-root-data. - Supervisa
SERVFAIL, latencia, consumo, journals y sincronización horaria. - Revisa listeners y ACL después de actualizaciones.
- Prueba UDP, TCP, un dominio firmado y un dominio bogus.
- Mantén QNAME minimisation, pero no la confundas con cifrado.
- Evita
.localpara zonas DNS privadas porque suele reservarse para mDNS. - Documenta DNS por interfaz, VPN y rutas
~.antes de modificar Netplan. - Conserva una consola alternativa y un rollback verificable.
Conclusión
La configuración estará completa cuando Unbound resuelva de forma recursiva, valide DNSSEC, responda mediante UDP y TCP y permanezca limitado al origen previsto.
La integración con systemd-resolved evita romper el comportamiento habitual de Ubuntu y permite revertir la ruta sin modificar manualmente /etc/resolv.conf.
DNSSEC aporta autenticidad e integridad. La confidencialidad requiere un diseño adicional con transporte cifrado.