El problema#
Hace unos meses mi servidor DNS se cayó sin aviso. No fue catastrófico, pero sí incómodo: durante varias horas ningún dispositivo en la red doméstica podía resolver dominios. Aprendí la lección: un DNS centralizado es un punto único de fallo que no puedo permitirme.
La solución obvia es redundancia. Necesitaba dos servidores DNS independientes con failover automático. Esto es lo que implementé.
La arquitectura#
Configuré dos máquinas con BIND9:
- ns1: servidor primario (maestro)
- ns2: servidor secundario (esclavo)
Ambos resuelven consultas. Si ns1 cae, los clientes se redirigen automáticamente a ns2. En la red doméstica, los equipos apuntan a ambos servidores en su configuración de DHCP.
Instalación base#
En ambas máquinas instalé BIND9:
sudo apt-get update
sudo apt-get install bind9 bind9-utils bind9-doc
sudo systemctl enable namedConfiguración del servidor primario (ns1)#
Edité /etc/bind/named.conf.local:
zone "ejemplo.local" {
type master;
file "/etc/bind/zones/db.ejemplo.local";
allow-transfer { 192.168.1.20; };
notify yes;
also-notify { 192.168.1.20; };
};Las líneas clave:
allow-transfer: permite que ns2 descargue la zonanotify: notifica automáticamente al secundario de cambiosalso-notify: especifica la IP del secundario
Luego creé el archivo de zona /etc/bind/zones/db.ejemplo.local:
$TTL 3600
@ IN SOA ns1.ejemplo.local. admin.ejemplo.local. (
2026090401 ; serial
3600 ; refresh
1800 ; retry
604800 ; expire
86400 ) ; minimum
IN NS ns1.ejemplo.local.
IN NS ns2.ejemplo.local.
ns1 IN A 192.168.1.10
ns2 IN A 192.168.1.20
@ IN A 192.168.1.10El serial es crítico: cada cambio requiere incrementarlo. Uso YYYYMMDDNN como formato.
Configuración del servidor secundario (ns2)#
En /etc/bind/named.conf.local del secundario:
zone "ejemplo.local" {
type slave;
masters { 192.168.1.10; };
file "/etc/bind/zones/db.ejemplo.local";
};Mucho más simple. El secundario descarga la zona completa del primario y la mantiene sincronizada.
Validación de configuración#
Antes de reiniciar, validé la sintaxis:
sudo named-checkconf
sudo named-checkzone ejemplo.local /etc/bind/zones/db.ejemplo.localSi hay errores, estos comandos lo dirán. Reinicié el servicio:
sudo systemctl restart namedPruebas de failover#
Desde otra máquina en la red probé la resolución:
nslookup ns1.ejemplo.local 192.168.1.10
nslookup ns1.ejemplo.local 192.168.1.20Ambas responden correctamente. Luego simulé la caída del primario deteniendo BIND9:
sudo systemctl stop namedLas consultas al primario fallan, pero las al secundario funcionan sin problemas.
Configuración del cliente DHCP#
En el servidor DHCP (o en los equipos estáticos), configuré ambos servidores DNS:
option domain-name-servers 192.168.1.10, 192.168.1.20;Los clientes automáticamente intentan el primero y usan el segundo si falla.
Monitoreo en producción#
Agregué un script simple que verifica el estado cada 5 minutos:
#!/bin/bash
for ns in 192.168.1.10 192.168.1.20; do
dig @$ns ejemplo.local +short | grep -q "192.168.1" || \
echo "ALERTA: NS $ns no responde" | mail -s "DNS FALLO" admin@ejemplo.local
doneLo metí en crontab.
Lecciones aprendidas#
La redundancia DNS no es complicada, pero los detalles importan. El serial en la zona debe estar correcto o no se sincroniza. Los permisos de archivos deben permitir que BIND lea las zonas. Y siempre validar configuración antes de reiniciar.
Desde que implementé esto, he podido reiniciar servidores sin perder resolución DNS. Eso es tranquilidad en infraestructura doméstica.