Servidores

Configuración de Servidor DNS con BIND9 en Ubuntu: Guía Completa para Sysadmins

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 30 minutos para instalación, 1-2 horas para upgrade in-place.
  • Requisitos: Backup de /home, conexión a internet, 20+ GB libres.
  • Resultado: Sistema actualizado con soporte extendido, drivers funcionando.
  • Troubleshooting: dnf distro-sync, akmods para NVIDIA, journalctl -p err.

Por qué BIND9 sigue siendo relevante en 2026

Cuando el resto del stack se fue a la nube (Route 53, Cloudflare DNS, Google Cloud DNS) montar un servidor de nombres autoritativo en tu propio hardware parece un anacronismo. No lo es. Hay tres casos donde BIND9 sigue siendo la mejor opción, y este tutorial te los explica: dominios internos que no quieres exponer a un tercero, redes grandes que necesitan vistas (split-horizon DNS), y servidores secundarios para tu dominio público donde quieres control total del archivo de zona.

En Ubuntu 24.04 LTS la versión actual del paquete bind9 es la 1:9.18.39-0ubuntu0.24.04.7 (rama estable 9.18 — EOL upstream en junio 2026; Ubuntu 24.04 LTS recibe parches de seguridad hasta abril 2029 pero ISC recomienda migrar a 9.20 ESV para servidores de producción nuevos). En Ubuntu 24.10 el paquete trae la rama 9.20 con mejores defaults para DNSSEC y soporte HTTP/3 sobre DoH. Para servidores de producción quédate con 24.04 LTS.

Instalar bind9 en Ubuntu

El paquete bind9 en Ubuntu es un meta-paquete que trae el servidor (named), las utilidades (dig, nslookup, rndc), y los archivos de configuración en /etc/bind/. Instala también bind9-utils y bind9-doc si vas a usar el servidor desde otra máquina para hacer pruebas con dig.

sudo apt update
sudo apt install -y bind9 bind9-utils bind9-doc
sudo systemctl enable --now named
sudo systemctl status named --no-pager

El primer comando levanta el servicio; systemctl status confirma que está corriendo y que rndc puede hablar con el daemon. Si todo está bien verás active (running) y la línea running as: named -u bind que confirma que el proceso bajó privilegios al usuario bind después de abrir el puerto 53. Esa doble etapa (root → bind) es por seguridad: si alguien explota una vulnerabilidad en named, el código ya no corre como root.

Entender los archivos de configuración que Ubuntu crea

Ubuntu no usa un solo named.conf monolítico: lo divide en cuatro archivos en /etc/bind/. Es la convención que verás en RHEL, Debian y derivados, y vale la pena entenderla antes de modificarlos.

Archivo Propósito
named.conf Incluye los otros tres con directivas include. No tocar salvo para añadir includes nuevos.
named.conf.options Opciones globales: puerto, allow-query, forwarders, recursion, DNSSEC. Aquí va casi toda la configuración que toca seguridad.
named.conf.local Definiciones de zonas (forward y reverse) servidas por este servidor. Cada zona apunta a su archivo de zona.
named.conf.default-zones Zonas por defecto que Ubuntu incluye (localhost, broadcast, 127.in-addr.arpa). Déjalas en paz — son necesarios para que el servidor no recurse hacia sí mismo.
/var/cache/bind/ Directorio de trabajo donde van los archivos de zona personalizados y el journal.

La separación existe porque named recarga archivos individuales sin reiniciar el daemon. Si tocas named.conf.options el servicio no se reinicia — recarga la configuración con rndc reload o el systemd helper systemctl reload bind9.

Configurar named.conf.options para un servidor autoritativo

El default de Ubuntu en named.conf.options deja opciones pensadas para un resolver recursivo. Para un servidor autoritativo puro hay que cerrar la recursion salvo en tus redes internas, restringir allow-query, y desactivar la transferencia de zona a desconocidos. Esta configuración asume que ns1.ejemplo.local es el servidor y 192.168.5.0/24 tu LAN.

sudo cp /etc/bind/named.conf.options /etc/bind/named.conf.options.bak.$(date +%F)
sudo tee /etc/bind/named.conf.options > /dev/null <<'EOF'
options {
    directory "/var/cache/bind";
    recursion no;                  # servidor autoritativo puro, NO recursivo
    allow-query { localnets; };    # solo responde a tu red interna
    allow-transfer { none; };      # nadie puede pedir AXFR, lo definimos por zona
    listen-on { any; };
    listen-on-v6 { any; };
    version "none";                # oculta la versión a quien haga dig @servidor version
    minimal-responses yes;
    auth-nxdomain no;              # cumple RFC1035 mejor
    managed-keys-directory "/var/cache/bind/keys";
    dnssec-validation auto;
    # forwarders para zonas que NO servimos autoritativamente
    # (si este servidor también hace recursive para tu LAN, cambia recursion a yes
    # y allow-query a { any; } — pero por defecto va cerrado)
    forwarders {
        1.1.1.1;
        9.9.9.9;
    };
    forward only;
};
EOF
sudo named-checkconf /etc/bind/named.conf.options

El bloque forwarders queda como red de seguridad: si alguien por error le pide al servidor una zona que no hosteas, named no intenta recursión real (porque recursion no), delega a Cloudflare y Quad9, y devuelve la respuesta. forward only le prohíbe intentar resolver por cuenta propia si los forwarders no responden. named-checkconf es tu validación: cualquier error de sintaxis lo imprime antes de recargar.

Crear archivo de zona para un dominio interno

El dominio ejemplo.local es para uso puramente interno; no delega a raíz pública. El SOA define los timers de refresco y el contacto del admin. Los registros NS apuntan al propio servidor. Por cada host añades línea A (IPv4) y AAAA (IPv6) si tienes.

sudo tee /var/cache/bind/db.ejemplo.local > /dev/null <<'ZEOF'
$TTL 86400
@   IN  SOA ns1.ejemplo.local. admin.ejemplo.local. (
        2026101201 ; serial (YYYYMMDDNN, incrementar en cada cambio)
        3600       ; refresh
        1800       ; retry
        1209600    ; expire
        86400      ; minimum (negative cache TTL)
    )
    IN  NS  ns1.ejemplo.local.
; servidores
ns1     IN  A   192.168.5.10
ns2     IN  A   192.168.5.11
; infraestructura
gateway     IN  A   192.168.5.1
nas         IN  A   192.168.5.20
proxmox     IN  A   192.168.5.2
; workstations
rog-laptop  IN  A   192.168.5.50
rog-escritorio IN A   192.168.5.51
; servicios
wiki        IN  CNAME   nas
vault       IN  CNAME   nas
jellyfin    IN  CNAME   proxmox
ZEOF
sudo chown bind:bind /var/cache/bind/db.ejemplo.local
sudo chmod 644 /var/cache/bind/db.ejemplo.local
sudo named-checkzone ejemplo.local /var/cache/bind/db.ejemplo.local

El serial sigue el patrón YYYYMMDDNN porque muchos secundarios lo comparan como entero de 32 bits y un valor más alto siempre gana. Si haces dos cambios el mismo día, el segundo va 02, el tercero 03. named-checkzone revisa sintaxis y verifica que cada nombre en NS, MX y CNAME apunte a algo real dentro de la zona. Si dice OK puedes seguir.

Crear archivo de zona inversa (PTR records)

Sin zona inversa los logs de muchos servicios (SSH, mail servers, fail2ban) no resuelven IP → nombre y quedan ilegibles. La zona inversa para 192.168.5.0/24 es 5.168.192.in-addr.arpa. Cada registro PTR apunta la IP al hostname canónico.

sudo tee /var/cache/bind/db.192.168.5 > /dev/null <<'REOF'
$TTL 86400
@   IN  SOA ns1.ejemplo.local. admin.ejemplo.local. (
        2026101201 ; serial
        3600       ; refresh
        1800       ; retry
        1209600    ; expire
        86400      ; minimum
    )
    IN  NS  ns1.ejemplo.local.
; PTR records — orden INVERSO: el último octeto primero
10  IN  PTR ns1.ejemplo.local.
11  IN  PTR ns2.ejemplo.local.
1   IN  PTR gateway.ejemplo.local.
2   IN  PTR proxmox.ejemplo.local.
20  IN  PTR nas.ejemplo.local.
50  IN  PTR rog-laptop.ejemplo.local.
51  IN  PTR rog-escritorio.ejemplo.local.
REOF
sudo chown bind:bind /var/cache/bind/db.192.168.5
sudo chmod 644 /var/cache/bind/db.192.168.5
sudo named-checkzone 5.168.192.in-addr.arpa /var/cache/bind/db.192.168.5

La convención es “orden inverso“: para PTR de 192.168.5.10 escribes 10 IN PTR ns1.ejemplo.local., con la última parte de la IP primero. Confuso la primera vez; lo internalizas cuando ves el primer dig -x 192.168.5.10 devolver el hostname correcto en lugar del NXDOMAIN de antes.

Registrar las zonas en named.conf.local

Hasta ahora los archivos existen pero named no sabe que tiene que servirlos. named.conf.local es donde declaras la zona y apuntas al archivo.

sudo tee /etc/bind/named.conf.local > /dev/null <<'LEOF'
zone "ejemplo.local" {
    type master;
    file "/var/cache/bind/db.ejemplo.local";
    allow-transfer { 192.168.5.11; };  # ns2 puede pedir AXFR
    also-notify { 192.168.5.11; };
};
zone "5.168.192.in-addr.arpa" {
    type master;
    file "/var/cache/bind/db.192.168.5";
    allow-transfer { 192.168.5.11; };
    also-notify { 192.168.5.11; };
};
LEOF
sudo named-checkconf
sudo systemctl reload bind9

El allow-transfer solo permite AXFR al secundario en 192.168.5.11. Si no tienes secundario y el servidor es single-node, pon allow-transfer { none; }. also-notify le dice que avise al secundario cuando hay cambios — sin esto los segundos tardan hasta el refresh (1 hora en este ejemplo) en enterarse. rndc reload o systemctl reload bind9 aplica cambios sin cortar consultas en vuelo.

Verificar que todo responde

Antes de declararlo productivo, prueba desde la propia máquina y desde otra en la LAN. Los tres comandos cubren los casos típicos.

# 1. Forward lookup A record
dig @127.0.0.1 nas.ejemplo.local A +short
# 2. Forward lookup CNAME (debe devolver la IP del target)
dig @127.0.0.1 wiki.ejemplo.local +short
# 3. Reverse lookup PTR (clave para logs legibles)
dig @127.0.0.1 -x 192.168.5.20 +short
# 4. Verifica el SOA y los NS records
dig @127.0.0.1 ejemplo.local SOA +short
dig @127.0.0.1 ejemplo.local NS +short
# 5. Comprueba que NO hay recursion abierta
dig @127.0.0.1 google.com +short
# deberia devolver SERVFAIL o reenviar al forwarder, no recursion real

El último dig es la prueba de seguridad: si la respuesta viene recursiva (siguiendo la cadena hasta los root servers) tienes recursion yes abierto al mundo y cualquier atacante puede usar tu servidor como amplificador de DDoS. Con recursion no el servidor responde SERVFAIL o delega a los forwarders externos.

Hardening extra para producción

La configuración base ya está bien para una LAN. Para servidores expuestos a Internet (nunca recomendado para un solo admin) o redes grandes añade estas capas.

Capa Qué hace Cómo
Rate limiting Cap por cliente para mitigación de amplificación rate-limit { responses-per-second 20; }; en options
RPZ (Response Policy Zones) Bloquea dominios maliciosos o de ad-tracking a nivel DNS response-policy { zone "rpz.local"; }; con archivo de zonas RPZ
DNSSEC signing Firma criptográfica que valida el origen dnssec-keygen + dnssec-signzone sobre el archivo de zona
chroot jail Aísla named en /var/named/chroot por si hay exploit apt install bind9-chroot y reconfigurar paths
Logging dedicado Separar queries normales de las sospechosas channel queries { file "/var/log/named/queries.log"; }; con category queries { queries; };
actualizar unattended-upgrades CVE parchadas sin intervención manual sudo dpkg-reconfigure -plow unattended-upgrades

Para un homelab basta rate-limit + DNSSEC. RPZ es overkill salvo que estés hosteando DNS para una familia o una microempresa. El chroot añade fricción operativa sin mucho beneficio real en Ubuntu 24.04 — el bind9 de Ubuntu ya corre como usuario no-root por diseño.

Troubleshooting común

Estos son los tres errores que más vas a ver, y cómo diagnosticarlos.

“zone ejemplo.local/IN: refused” al hacer dig: la causa típica es allow-query demasiado restrictivo. Si el cliente está fuera de la red listada en allow-query { localnets; }, named devuelve REFUSED. Verifica con named-checkconf -p /etc/bind/named.conf | grep allow-query.

“zone ejemplo.local/IN: not loaded due to errors” en journalctl -u named: error de sintaxis en el archivo de zona. named-checkzone ejemplo.local /var/cache/bind/db.ejemplo.local da la línea exacta. El 80% de las veces es un punto final faltante en un registro, o un nombre relativo sin punto final cuando debería ser FQDN.

AXFR denied desde el secundario: el allow-transfer del maestro no lista al secundario, o el firewall entre ambos bloquea puerto 53/TCP. Verifica con rndc zonestatus ejemplo.local en el maestro, y desde el secundario dig @192.168.5.10 ejemplo.local AXFR para ver exactamente qué pasa.

¿Vale la pena montar BIND9 hoy?

Depende del caso. Para dominios públicos pequeños Route 53 o Cloudflare DNS son más baratos en tiempo de administración y te dan anycast global incluido — no tiene sentido montar BIND9 autoritativo para un dominio .com con 10 registros A. Para dominios internos en LAN, dnsmasq cubre el 90% de los casos en 20 líneas de config, y Unbound es mejor si quieres validación DNSSEC estricta sin las complicaciones de BIND9.

Donde BIND9 sigue ganando: redes empresariales con split-horizon DNS (vistas distintas para empleados vs invitados vs VPN), organizaciones que firman sus zonas con DNSSEC manualmente, y entornos donde necesitas controles granulares por ACL sobre qué redes pueden resolver qué vistas. La curva de aprendizaje es más empinada, pero una vez que tu archivo de zona está bien hecho, named se queda corriendo meses sin tocar.

Preguntas frecuentes

¿Por qué Configuración de Servidor DNS con BIND9 en Ubuntu: Guía Completa para Sysadmins es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Configuración de Servidor DNS con?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Configuración de Servidor DNS con?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Configuración de Servidor DNS con y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Configuración de Servidor DNS con?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *