El split DNS es uno de esos problemas que “debería ser aburrido” pero se convierte en un fin de semana entero porque alguien reinició un portátil, la VPN se reconectó,
y de repente git.company.internal se resuelve en Internet público (o peor, no se resuelve). Si alguna vez has visto un despliegue de producción detenerse porque un agente de compilación perdió el DNS interno a mitad de ejecución, conoces la sensación: no es dramático,
es caro.
Debian 13 puede manejar split DNS de forma limpia. El truco es elegir un único plano de control DNS y hacer que todo lo demás le alimente.
Este artículo te da una configuración que sobrevive reinicios, cambios de Wi‑Fi, reconexiones de VPN y servidores DHCP “ayudantes”.
Lo que vas a construir (y lo que no)
Split DNS significa: ciertos dominios se resuelven usando servidores DNS específicos, mientras que todo lo demás utiliza tu DNS “normal”.
Ejemplo típico:
*.corp.internaly*.svc.cluster.localse resuelven a través de los servidores DNS de la VPN- todo lo demás se resuelve a través del DNS de la LAN (o resolvers públicos)
No estás construyendo una granja de servidores DNS. Estás creando una configuración determinista del resolutor cliente que:
(1) envía los nombres correctos a los resolutores correctos, (2) no filtra consultas internas a DNS públicos, y (3) se mantiene estable tras reinicios.
Tu enemigo no es la complejidad del DNS. Son los gestores de DNS en conflicto. Los sistemas Debian a menudo tienen múltiples actores tirando de /etc/resolv.conf:
NetworkManager, systemd-resolved, clientes VPN, clientes DHCP y, en ocasiones, el dotfile de alguien de 2014.
Hechos interesantes y breve historia (porque el contexto evita el dolor)
- El split DNS es anterior al hype de las VPN: las empresas lo usaron temprano para zonas de split‑horizon donde los nombres internos no deben resolverse externamente.
-
El formato de
/etc/resolv.confes intencionalmente simple—tan simple que no puede expresar enrutamiento por dominio. El split DNS requiere algo más inteligente. -
Los “dominios de enrutamiento” de systemd-resolved (el concepto
~domain) están diseñados específicamente para expresar “este sufijo va al DNS de este enlace”. -
El clásico “límite de 3 nameservers” en
resolv.confno es solo folklore: muchos resolutores todavía se comportan así, y el orden puede jugar en tu contra. - El cache negativo (recordar NXDOMAIN) puede hacer que el DNS parezca encantado: arregla el servidor y los clientes siguen fallando hasta que expira la caché.
- Los dominios de búsqueda son más antiguos que la mayoría de las herramientas VPN modernas, y se abusan con frecuencia. Una lista larga de búsquedas aumenta la carga de consultas y las sorpresas.
- Las “fugas DNS” a menudo no son sobre privacidad—son sobre fiabilidad. Las zonas internas consultadas vía DNS público devuelven NXDOMAIN y rompen las aplicaciones.
- Muchas VPN corporativas históricamente imponían un control total del DNS porque los clientes antiguos no podían hacer enrutamiento por dominio; ese hábito aún perdura.
Una idea parafraseada de Werner Vogels (CTO de Amazon): todo falla, todo el tiempo; diseña sistemas asumiendo que la falla es normal
.
El split DNS es una pequeña versión de esa filosofía—diseña para flaps de interfaz y reconexiones.
Decisiones de diseño que realmente aguantan
Elige un único propietario para las decisiones de DNS
En Debian 13, el enfoque más limpio es: dejar que systemd-resolved sea el motor de políticas del resolutor.
Deja que NetworkManager (o tu cliente VPN) le proporcione servidores DNS y dominios por enlace.
Luego apunta /etc/resolv.conf al stub de resolved.
Lo que debes evitar: una pila de resolutores “elige tu propia aventura” donde NetworkManager escribe /etc/resolv.conf,
la VPN lo sobrescribe y un script post‑up intenta parchearlo. Funciona hasta que deja de funcionar—y normalmente falla tras un reinicio.
Entiende los dos modos de resolved
-
Escucha stub: tu sistema apunta a
127.0.0.53(stub local), y resolved hace el enrutamiento upstream y el caching. - Foreign / resolv.conf directo: las apps consultan los servidores upstream directamente. Aquí es donde el split DNS muere silenciosamente.
La VPN debe publicar dominios, no solo servidores
Una VPN que solo empuja servidores DNS pero no “qué dominios me pertenecen” está pidiendo problemas.
Quieres o bien:
- la interfaz VPN reciba dominios de enrutamiento como
~corp.internal,~company.local - o al menos dominios de búsqueda (menos preciso, más riesgo)
La prioridad DNS no es un sentimiento
La selección de DNS tiene reglas. Los resolutores eligen servidores según enlace, ruta y coincidencia de dominio. Si no estableces prioridades,
el “ganador” puede cambiar cuando cambian las métricas de las interfaces (el roaming Wi‑Fi es excelente para eso).
Broma #1: El DNS es el único sistema donde “está en caché” se acepta tanto como explicación como coartada.
Guion rápido de diagnóstico
Cuando el split DNS falla, no empieces editando archivos. Empieza respondiendo tres preguntas rápidamente:
qué resolutor está activo, qué enlace posee el dominio y qué ruta de consulta está usando la aplicación.
Primero: ¿systemd-resolved está realmente a cargo?
- Comprueba si
/etc/resolv.confapunta al stub - Comprueba
resolvectl statuspara ver DNS por enlace
Segundo: ¿el dominio está enrutado al enlace VPN?
resolvectl query git.corp.internaly verifica que usa el servidor DNS de la VPN- Confirma que el enlace de la VPN tiene
~corp.internal(dominio de enrutamiento), no solo un dominio de búsqueda genérico
Tercero: ¿tu app está evitando el resolutor del sistema?
- Los navegadores, runtimes de contenedores y algunos SDK pueden hacer su propio DNS o caching
- Comprueba con
getent hostsfrente adigy compara resultados
Prueba rápida para olfatear cuellos de botella
- Si
resolvectl queryes rápido pero la app es lenta: sospecha caching a nivel de app, ajustes de proxy o DoH/DoT dentro de la app. - Si
resolvectl queryes lento: sospecha servidor DNS inalcanzable, problemas de MTU en la VPN o UDP/TCP 53 bloqueado. - Si solo algunos dominios fallan: sospecha dominios de enrutamiento, conflictos de split‑horizon o caché negativa obsoleta.
Prerequisitos y comprobaciones básicas
Debian 13 normalmente incluye systemd y puede ejecutar systemd-resolved. NetworkManager es común en escritorios y portátiles; en servidores podrías
usar systemd-networkd o ifupdown. Esta guía asume que usas NetworkManager o tienes una interfaz VPN que puedes configurar.
Decide el comportamiento deseado antes de tocar nada:
- ¿Quieres que solo los dominios internos usen el DNS de la VPN (preferido)?
- ¿O quieres que todo el DNS pase por la VPN mientras esté conectada (a veces requerido por política)?
- ¿Necesitas soportar servidores DNS tanto IPv4 como IPv6?
Configuración preferida: systemd-resolved como el plano de control DNS
1) Asegúrate de que resolved esté en ejecución
Si resolved no está activo, todo lo demás se vuelve cinta adhesiva. Habilítalo y haz que sea aburrido.
2) Apunta /etc/resolv.conf al stub
Quieres que /etc/resolv.conf sea un enlace simbólico al stub resolv.conf de systemd. Este es el ancla que sobrevive el reinicio.
Si dejas que otras herramientas lo escriban, tendrás una personalidad de DNS diferente cada lunes.
3) Deja que NetworkManager hable con resolved
NetworkManager puede integrarse con systemd-resolved. Cuando lo hace, los servidores DNS y dominios se convierten en propiedades por enlace, que es exactamente lo que necesita el split DNS.
4) Adjunta dominios de enrutamiento al enlace VPN
La magia es la sintaxis de dominio de enrutamiento: ~corp.internal. La tilde significa “enruta las consultas para este dominio al DNS de este enlace”.
Sin ella, vuelves a la ruleta global del DNS.
Split DNS en NetworkManager y VPN: patrones para WireGuard y OpenVPN
WireGuard vía NetworkManager
WireGuard es limpio, pero el ecosistema a su alrededor varía. Si lo gestionas mediante NetworkManager, establece DNS y dominios en el perfil de conexión de WireGuard.
Algunas implementaciones también empujan DNS mediante scripts; evita eso si es posible—mantén una autoridad.
OpenVPN vía NetworkManager
OpenVPN suele empujar “dhcp-option DNS” y “dhcp-option DOMAIN”. NetworkManager puede traducir eso a configuraciones de enlace para resolved.
La clave es asegurar que los dominios se conviertan en dominios de enrutamiento (o al menos dominios de búsqueda), y que la prioridad DNS no permita que la LAN se lleve nombres internos.
Broma #2: El DNS de la VPN es como un organigrama corporativo—técnicamente documentado, emocionalmente impredecible.
Opcional: dnsmasq local para casos difíciles
Prefiero systemd-resolved solo para clientes Debian. Pero hay casos límite:
- Necesitas reglas de reenvío condicional que una aplicación heredada específica espera.
- Quieres reproducir un patrón corporativo de larga data: “envía corp.internal a 10.x, todo lo demás al ISP”.
- Tratas con un entorno donde la herramienta VPN no puede comunicar dominios de forma fiable a resolved.
En esos casos, dnsmasq puede actuar como un reenviador local con políticas, y resolved puede reenviar hacia él—o puedes saltarte resolved y dejar que NetworkManager alimente dnsmasq.
El riesgo es aumentar la complejidad. La complejidad está bien cuando está documentada y estable. No está bien cuando es accidental.
Tareas prácticas: comandos, salidas y decisiones
Estas tareas están escritas como si estuvieras de guardia: ejecutas un comando, interpretas la salida y luego decides qué hacer a continuación.
No “pruebes cosas”. Cambia una variable a la vez.
Task 1: Confirmar que Debian usa systemd-resolved
cr0x@server:~$ systemctl status systemd-resolved --no-pager
● systemd-resolved.service - Network Name Resolution
Loaded: loaded (/lib/systemd/system/systemd-resolved.service; enabled; preset: enabled)
Active: active (running) since Mon 2025-12-29 08:41:12 UTC; 2h 13min ago
Docs: man:systemd-resolved.service(8)
Significado: “active (running)” es innegociable para este diseño.
Decisión: Si está inactive/disabled, actívalo antes de tocar el DNS de la VPN.
Task 2: Verificar quién posee /etc/resolv.conf
cr0x@server:~$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Dec 29 08:41 /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf
Significado: Este enlace simbólico es la parte “a prueba de reinicios”.
Decisión: Si apunta a otro sitio (o es un archivo regular), arréglalo; de lo contrario estás depurando un objetivo que se mueve.
Task 3: Inspeccionar la vista global y por‑enlace de resolved
cr0x@server:~$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 192.168.1.1
DNS Servers: 192.168.1.1
DNS Domain: lan
Link 2 (enp3s0)
Current Scopes: DNS
Protocols: +DefaultRoute
Current DNS Server: 192.168.1.1
DNS Servers: 192.168.1.1
DNS Domain: lan
Link 5 (wg0)
Current Scopes: DNS
Protocols: -DefaultRoute
DNS Servers: 10.20.30.53 10.20.30.54
DNS Domain: ~corp.internal ~svc.cluster.local
Significado: El enlace VPN tiene dominios de enrutamiento (~corp.internal) y no es la ruta por defecto para DNS.
Decisión: Si el enlace VPN carece de dominios de enrutamiento, el split DNS no ocurrirá. Añádelos en el nivel de conexión.
Task 4: Confirmar que un nombre interno específico se enruta al DNS de la VPN
cr0x@server:~$ resolvectl query git.corp.internal
git.corp.internal: 10.20.40.12 -- link: wg0
(git.corp.internal)
Significado: La consulta pasó por el enlace wg0.
Decisión: Si dice link: enp3s0 o “No appropriate name servers”, arregla los dominios de enrutamiento o la alcanzabilidad DNS.
Task 5: Comparar la ruta de resolución de libc (lo que usan la mayoría de las apps)
cr0x@server:~$ getent hosts git.corp.internal
10.20.40.12 git.corp.internal
Significado: NSS + libc están resolviendo correctamente.
Decisión: Si resolvectl query funciona pero getent falla, sospecha una mala configuración de NSS o una app que evita el resolutor del sistema.
Task 6: Comprobar que NetworkManager usa resolved (no escribe resolv.conf directamente)
cr0x@server:~$ nmcli general status
STATE CONNECTIVITY WIFI-HW WIFI WWAN-HW WWAN
connected full enabled enabled enabled enabled
cr0x@server:~$ nmcli -t -f RUNNING,VERSION,STATE general
running:yes
version:1.48.0
state:connected
Significado: NM está vivo; el siguiente paso es verificar que esté configurado para usar systemd-resolved.
Decisión: Si NM no está en ejecución, tus cambios de DNS deben hacerse vía systemd-networkd o directamente con la herramienta VPN.
Task 7: Inspeccionar DNS y dominios de una conexión VPN en NetworkManager
cr0x@server:~$ nmcli -f NAME,TYPE,DEVICE connection show --active
NAME TYPE DEVICE
Office-WG wireguard wg0
Home-LAN ethernet enp3s0
cr0x@server:~$ nmcli connection show "Office-WG" | sed -n '1,120p'
connection.id: Office-WG
connection.type: wireguard
connection.interface-name: wg0
ipv4.method: auto
ipv4.dns: 10.20.30.53,10.20.30.54
ipv4.dns-search: corp.internal,svc.cluster.local
ipv4.ignore-auto-dns: yes
ipv6.method: disabled
Significado: NM tiene DNS y dominios de búsqueda. Con la integración con resolved, estos pueden convertirse en dominios de enrutamiento.
Decisión: Si ipv4.ignore-auto-dns es no en la LAN, DHCP puede anular tus intenciones; ajusta prioridades y usa ignore-auto-dns donde corresponda.
Task 8: Establecer servidores DNS específicos de la VPN y dominios de búsqueda (y persistirlos)
cr0x@server:~$ sudo nmcli connection modify "Office-WG" ipv4.dns "10.20.30.53 10.20.30.54"
cr0x@server:~$ sudo nmcli connection modify "Office-WG" ipv4.dns-search "corp.internal svc.cluster.local"
cr0x@server:~$ sudo nmcli connection modify "Office-WG" ipv4.ignore-auto-dns yes
cr0x@server:~$ sudo nmcli connection down "Office-WG" && sudo nmcli connection up "Office-WG"
Connection 'Office-WG' successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/17)
Connection 'Office-WG' successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/19)
Significado: Has hecho explícito y persistente el DNS de la VPN en NM.
Decisión: Si tras reconectar resolvectl status aún no muestra dominios de enrutamiento, revisa la integración NM–resolved o usa un drop‑in para resolved.
Task 9: Confirmar que resolved ve los servidores DNS de la VPN después de reconectar
cr0x@server:~$ resolvectl status wg0
Link 5 (wg0)
Current Scopes: DNS
Protocols: -DefaultRoute
DNS Servers: 10.20.30.53 10.20.30.54
DNS Domain: ~corp.internal ~svc.cluster.local
Significado: Perfecto: servidores DNS con alcance por enlace y dominios de enrutamiento.
Decisión: Si los dominios carecen de la tilde, aún puedes funcionar vía dominios de búsqueda, pero espera fugas y comportamiento extraño. Arréglalo correctamente.
Task 10: Forzar dominios de enrutamiento en el enlace VPN vía resolved (cuando el cliente VPN no puede)
cr0x@server:~$ sudo mkdir -p /etc/systemd/resolved.conf.d
cr0x@server:~$ sudo tee /etc/systemd/resolved.conf.d/wg0-domains.conf >/dev/null <<'EOF'
[Resolve]
EOF
cr0x@server:~$ sudo resolvectl domain wg0 '~corp.internal' '~svc.cluster.local'
cr0x@server:~$ sudo resolvectl dns wg0 10.20.30.53 10.20.30.54
Significado: Aplicaste ajustes en vivo. Nota: los cambios de resolvectl domain no son automáticamente persistentes a través de reinicios a menos que tu gestor de red los reaplique.
Decisión: Usa esto para triage; luego mueve la configuración a NetworkManager o systemd-networkd para que sobreviva al reinicio.
Task 11: Validar que no estás filtrando consultas internas a DNS públicos
cr0x@server:~$ resolvectl query doesnotexist.corp.internal
doesnotexist.corp.internal: resolve call failed: 'does not exist' (NXDOMAIN) -- link: wg0
Significado: NXDOMAIN vino del enlace VPN. Bien. Eso significa que la consulta fue a donde la querías.
Decisión: Si NXDOMAIN proviene del DNS de la LAN, tu enrutamiento dividido no está funcionando y las consultas internas se están filtrando.
Task 12: Comprobar un stub local “útil” o listener en conflicto en el puerto 53
cr0x@server:~$ sudo ss -ltnup | grep ':53 '
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=620,fd=13))
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=620,fd=14))
Significado: resolved posee el listener stub. Sin bind local inesperado.
Decisión: Si ves dnsmasq/unbound también enlazando 127.0.0.1:53, decide quién gana y desactiva el otro. “Ambos” no es un plan.
Task 13: Confirmar que nsswitch es sensato para la resolución de hosts
cr0x@server:~$ grep -E '^(hosts|networks):' /etc/nsswitch.conf
hosts: files mdns4_minimal [NOTFOUND=return] dns
networks: files
Significado: DNS está en la cadena; los archivos locales tienen precedencia.
Decisión: Si dns falta, o tienes módulos exóticos, arregla NSS antes de culpar a resolved.
Task 14: Observar el comportamiento DNS durante una reconexión VPN
cr0x@server:~$ journalctl -u systemd-resolved -n 80 --no-pager
Dec 29 10:42:11 server systemd-resolved[620]: Switching to fallback DNS server 192.168.1.1#53.
Dec 29 10:42:25 server systemd-resolved[620]: Using degraded feature set UDP instead of UDP+EDNS0 for DNS server 10.20.30.53.
Dec 29 10:42:29 server systemd-resolved[620]: DNS server 10.20.30.53#53 connected via wg0.
Significado: resolved se está adaptando a la alcanzabilidad del servidor y a la capacidad EDNS0. Esto es a menudo una razón oculta de “ayer iba rápido”.
Decisión: Si ves cambios constantes, investiga MTU, pérdida de paquetes o reglas de firewall en la ruta VPN.
Tres mini-historias corporativas (porque las cicatrices enseñan)
Mini-historia 1: El incidente causado por una suposición errónea
Una empresa mediana desplegó un nuevo concentrador VPN. El equipo de red lo probó con un cliente Windows, confirmó que los sitios internos funcionaban,
y entonces anunció victoria. A los usuarios Linux se les dijo “simplemente usad OpenVPN” y se les dio una configuración que empujaba servidores DNS pero no dominios.
La suposición errónea: “Si empujamos servidores DNS internos, los nombres internos se resolverán”. En clientes Linux, eso a menudo significa que esos servidores DNS se vuelven
preferidos globalmente. Luego, cuando los usuarios se desconectaban, la configuración obsoleta permanecía—o peor, el resolutor seguía intentando consultar a los servidores 10.x inalcanzables.
La gente lo experimentó como “el DNS muere aleatoriamente tras la VPN”.
El outage no fue un gran estallido. Fue un sangrado lento: los runners de CI fallaban al obtener dependencias porque la resolución pública funcionaba, pero los nombres internos de artefactos no. Los desarrolladores reejecutaban trabajos hasta que pasaban. Puedes imaginar cómo afectó a la planificación de capacidad.
La solución no fue heroica. Dejaron de permitir que la VPN sobrescribiera el DNS global y en su lugar publicaron dominios de enrutamiento para corp.internal y
svc.cluster.local. Los clientes Linux enviaron entonces solo esos sufijos al DNS de la VPN. Todo lo demás permaneció en el DNS de la LAN.
La lección: el split DNS no es “un pulido opcional”. Es corrección. El DNS de la VPN sin dominios es como repartir números de teléfono sin prefijos de área.
Mini-historia 2: La optimización que salió mal
Otra organización quería builds más rápidos. Alguien notó que la latencia DNS hacia los resolutores corporativos por la VPN era ~60–120ms en horas punta.
La optimización propuesta: “Cachéalo todo agresivamente en los portátiles usando un resolutor caché local y subamos los TTLs en el DNS interno”.
Parecía razonable—hasta que no lo fue.
Desplegaron una capa de caché local y mejoró la mediana de resolución. Pero los límites del split DNS se volvieron borrosos.
Algunos registros internos tenían TTL cortos por diseño porque los servicios se movían tras balanceadores. La capa de caché guardó respuestas antiguas con diligencia.
Cuando un servicio hizo failover, los clientes siguieron llamando al endpoint muerto durante minutos.
El momento del fallo fue sutil: el monitoreo mostraba que el servicio estaba sano y el failover funcionó. Solo un subconjunto de clientes fallaba.
Las cachés del resolutor eran las culpables. Un proyecto de “DNS más rápido” se convirtió en un incidente de “por qué solo los ingenieros remotos están rotos”.
El rollback fue doloroso porque todos se habían vuelto dependientes de la mejora. La solución a largo plazo fue respetar TTLs, cachear responsablemente
y dejar de tratar el DNS como una base de datos de configuración estática. No lo es. Es un plano de control.
Mini-historia 3: La práctica aburrida pero correcta que salvó el día
Una compañía global tenía una regla estricta para endpoints: un propietario de DNS (resolutor del sistema), un camino de configuración (perfiles de NetworkManager),
y nada de scripts post‑conexión que editen /etc/resolv.conf. Los ingenieros se quejaban porque parecía burocrático.
Entonces un parche del gateway VPN introdujo un bug donde la lista de servidores DNS empujada ocasionalmente incluía primero un resolutor inalcanzable.
Algunos clientes hacían timeout en el primer servidor y caían al siguiente; otros se quedaban bloqueados por la lógica de reintento. Podría haber sido un desastre.
Porque tenían un diseño consistente, el diagnóstico fue rápido. En las máquinas afectadas, resolvectl status mostraba claramente el servidor DNS malo en el enlace VPN.
Pudieron desplegar una actualización de perfil de NetworkManager de una línea para reordenar servidores DNS y reducir el dolor de reintentos.
Sin heroísmos, sin editar archivos a mano en portátiles, sin “ejecuta este script tras conectar”. Solo un cambio aburrido de configuración que se aplicó al reconectar.
El incidente se mantuvo contenido y el servicio de asistencia no ardió.
Errores comunes: síntoma → causa raíz → solución
-
Síntoma: El DNS funciona hasta el reinicio, luego los nombres internos fallan.
Causa raíz:/etc/resolv.confes un archivo regular o está gestionado por la herramienta equivocada; resolved no es el stub activo.
Solución: Habilita resolved y crea el enlace simbólico/etc/resolv.conf→/run/systemd/resolve/stub-resolv.conf. -
Síntoma: Mientras estás en la VPN, el DNS público deja de funcionar o se vuelve lento.
Causa raíz: Los servidores DNS de la VPN se están usando como resolutores globales; o bien bloquean recursión o tienen mal egress.
Solución: Usa dominios de enrutamiento (~corp.internal) para que solo los dominios internos lleguen al DNS de la VPN; mantiene los resolutores de LAN/públicos para lo demás. -
Síntoma: Los dominios internos se resuelven a IPs públicas (servicio equivocado, certificado erróneo, errores confusos).
Causa raíz: Coincidencia de split‑horizon: las consultas de zonas internas van primero a resolutores públicos.
Solución: Asegura que el sufijo interno esté enrutado al enlace VPN; verifica conresolvectl querymostrandolink: wg0. -
Síntoma:
resolvectl queryfunciona, pero un navegador o app Java falla.
Causa raíz: App evita el resolutor del sistema (DoH), DNS fijado o caché de la app.
Solución: Confirma congetent hosts; desactiva DoH de la app o alinéalo con la política corporativa; reinicia la app tras cambios DNS. -
Síntoma: Solo algunos nombres internos fallan, especialmente nombres cortos.
Causa raíz: Falta dominio de búsqueda en el enlace VPN, o orden conflictivo de búsquedas entre LAN y VPN.
Solución: Añade dominios explícitos; prefiere FQDNs; reduce y ordena cuidadosamente los dominios de búsqueda. -
Síntoma: Timeouts aleatorios al resolver nombres internos por la VPN.
Causa raíz: Problemas de MTU/fragmentación en la ruta VPN, o el servidor DNS requiere fallback a TCP y está bloqueado.
Solución: Revisa logs de resolved por modo degradado; prueba alcance TCP/53; arregla MTU o reglas de firewall. -
Síntoma: Las consultas DNS van al servicio local equivocado en el puerto 53.
Causa raíz: Otro resolutor (dnsmasq/unbound) está escuchando, o una red de contenedores está secuestrando DNS.
Solución: Decide un listener local; detén el otro; confirma conss -ltnup.
Listas de verificación / plan paso a paso
Checklist A: Base limpia y a prueba de reinicios
- Habilita e inicia systemd-resolved.
- Crea el enlace simbólico
/etc/resolv.confhacia el stub resolv.conf de resolved. - Confirma que
resolvectl statusmuestraresolv.conf mode: stub. - Elige un gestor de red: NetworkManager en escritorios, systemd-networkd en servidores. No mezcles sin cuidado.
Checklist B: Split DNS en la VPN que no filtra
- Establece servidores DNS de la VPN explícitamente (evita “automático si funciona”).
- Adjunta dominios de enrutamiento al enlace VPN:
~corp.internal,~svc.cluster.local. - Asegura que el enlace VPN no sea la ruta DNS por defecto a menos que la política lo requiera.
- Valida con
resolvectl querymostrandolink: wg0para dominios internos. - Valida que los dominios públicos aún se resuelvan vía DNS de la LAN.
Checklist C: Endurecimiento para el mundo real
- Mantén los dominios de búsqueda cortos; evita apilar cinco sufijos corporativos “por si acaso”.
- Prefiere FQDNs en automatización y gestión de configuración.
- Haz el comportamiento DNS observable: enseña a la gente
resolvectl statusyresolvectl query. - Prueba bucles de reconexión: desconecta/reconecta la VPN, cambia Wi‑Fi, suspende/reanuda.
- Documenta la única fuente de verdad: “El DNS lo gestiona resolved; NM lo alimenta.”
Preguntas frecuentes
1) ¿Realmente necesito systemd-resolved para split DNS en Debian 13?
No, pero necesitas algo que pueda expresar enrutamiento por dominio. resolved es lo más directo en Debian 13
y se integra bien con NetworkManager.
2) ¿Cuál es la diferencia entre dominios de búsqueda y dominios de enrutamiento?
Los dominios de búsqueda añaden sufijos a nombres cortos (por ejemplo, git se convierte en git.corp.internal).
Los dominios de enrutamiento (~corp.internal) le indican a resolved qué servidores DNS deben recibir consultas para ese sufijo.
Usa dominios de enrutamiento para split DNS. Usa dominios de búsqueda con moderación.
3) ¿Por qué no simplemente poner los servidores DNS de la VPN primero en resolv.conf?
Porque se rompe en cuanto la VPN se desconecta, y porque envía consultas no corporativas a resolutores corporativos.
El split DNS es cuestión de corrección, no solo de “hacer que lo interno resuelva mientras estás conectado”.
4) Uso WireGuard con wg-quick, no con NetworkManager. ¿Puedo hacerlo igualmente?
Sí, pero debes asegurar que el DNS y el enrutamiento de dominios se apliquen persistentemente cuando la interfaz se levante.
Un enfoque común es integrarlo con resolved mediante hooks de interface‑up—y luego verificar tras un reinicio que los hooks se ejecutan.
Si puedes, gestionar WireGuard vía NetworkManager suele ser más consistente en portátiles.
5) Mis servidores DNS internos solo responden zonas internas y rechazan recursión. ¿Está bien?
Está bien y a menudo es intencional. Es otra razón para usar split DNS: solo los sufijos internos deben ir a esos servidores,
mientras que los nombres públicos se resuelven en otro lado.
6) ¿Por qué a veces “NXDOMAIN” persiste después de arreglar el DNS?
Caché negativa. Los resolutores y aplicaciones pueden cachear NXDOMAIN por un TTL. Reiniciar resolved puede limpiar su caché,
pero las apps pueden seguir en caché. Al depurar, prueba con nombres nuevos o reinicia la aplicación.
7) ¿Cómo sé si mi app está evitando el resolutor del sistema?
Compara resultados entre getent hosts name y la app. Si libc resuelve pero la app no,
revisa la app por ajustes DoH, resolutores embebidos o configuración de proxy.
8) ¿Debería deshabilitar IPv6 para “arreglar problemas DNS”?
Normalmente no. El dual‑stack añade complejidad, pero deshabilitar IPv6 suele ocultar el problema real (como DNS VPN roto sobre IPv6 o anuncios de router malos).
Arregla la configuración; no amputes la red.
9) ¿Cuándo elegirías dnsmasq sobre systemd-resolved?
Cuando necesites reglas de reenvío condicional que no encajen bien con dominios DNS por enlace, o cuando herramientas heredadas no puedan comunicar dominios divididos.
Trátalo como excepción, no como predeterminado.
Conclusión: próximos pasos que no arruinarán tu lunes
El camino estable en Debian 13 es simple: systemd-resolved controla la política DNS; NetworkManager (o tu stack de red) lo alimenta con servidores DNS por enlace y dominios de enrutamiento.
Haz que /etc/resolv.conf apunte al stub y deja de permitir que scripts aleatorios lo modifiquen.
Pasos prácticos:
- Verifica que
/etc/resolv.confsea el enlace simbólico al stub de resolved. - Asegura que tu enlace VPN tenga dominios de enrutamiento (
~corp.internal) y servidores DNS de VPN enresolvectl status. - Ejecuta tres pruebas:
resolvectl querypara un nombre interno,getent hostspara el mismo nombre y una consulta para un nombre público. - Reinicia una vez a propósito. Si se rompe tras un reinicio planificado, nunca fue estable—solo tuvo suerte temporal.