Editas /etc/resolv.conf, funciona cinco minutos y luego se “restaura” “amablemente”. Tu aplicación pierde resolución de nombres, el DNS dividido de tu VPN deja de funcionar y el canal de guardia empieza a oler a tostadas quemadas.
Ubuntu 24.04 no rompió DNS. Simplemente dejó más explícita la propiedad del DNS: systemd-resolved, NetworkManager, DHCP y, de vez en cuando, los plugins de VPN, todos intentan ser el adulto en la sala. Si no eliges una autoridad —y la conectas correctamente— resolv.conf se convierte en un campo de batalla de escrituras.
El modelo mental: quién es el dueño del DNS en Ubuntu 24.04
/etc/resolv.conf parece un archivo simple. En Ubuntu moderno, a menudo es un enlace simbólico a algo generado. No es una conspiración; es la fontanería. La verdadera pregunta es: ¿qué componente es la fuente de la verdad para el DNS?
Los actores principales
- systemd-resolved: un servicio de resolución local que puede hacer caché, DNS-over-TLS (en algunas configuraciones) y DNS por interfaz (DNS dividido). Comúnmente expone un stub local en
127.0.0.53y escribe un resolv.conf “gestionado”. - NetworkManager: el orquestador de red para escritorios y muchos servidores, especialmente cuando netplan usa el renderer NetworkManager. Recolecta DNS de DHCP/VPN/configuración estática y puede entregarlo a
systemd-resolvedo escribir/etc/resolv.confdirectamente dependiendo de la configuración. - Clientes DHCP (a menudo a través de NetworkManager): suministran servidores DNS y dominios de búsqueda, a veces de forma agresiva. Si el servidor DHCP está mal, tu máquina queda mal, de forma fiable y a escala.
- Plugins de VPN: añaden rutas y DNS. Algunos esperan DNS dividido. Otros aplican una anulación completa del DNS. Algunos intentan hacerlo bien y aun así pierden contra tu configuración local.
- netplan: genera la configuración de más bajo nivel. No “hace DNS” por sí mismo en tiempo de ejecución, pero decide qué renderer (NetworkManager o systemd-networkd) se encarga.
Qué suele significar “resolv.conf sigue cambiando”
Casi nunca es aleatorio. Es el resultado determinista de una de estas situaciones:
/etc/resolv.confes un enlace simbólico a un archivo generado, y sigues editando la salida del objetivo del enlace en vez de las entradas.- NetworkManager está configurado para usar
systemd-resolved, pero resolved está deshabilitado o mal enlazado, así que NetworkManager escribe por su cuenta. - Están habilitados dos gestores de DNS y ambos creen que son los responsables.
- Una VPN se conecta y empuja DNS, luego DHCP renueva y lo reemplaza (o al revés).
- Una herramienta de configuración (cloud-init, provisioning, gestión de configuración) “corrige” el DNS al arrancar.
Verdad seca y graciosa: /etc/resolv.conf es la cinta adhesiva de la red en Linux—alguien siempre asume que es el lugar correcto para pegar una solución, y siempre se despega a las 3 a.m.
Elige una autoridad. Conecta las demás para que le den información. Y deja de editar /etc/resolv.conf a mano a menos que tu objetivo sea crear un misterio para el tú del futuro.
Guía rápida de diagnóstico (revisa esto primero)
Si el DNS está roto o resolv.conf no se mantiene, no empieces por editar nada. Empieza respondiendo: “¿Quién lo escribió por última vez?” y “¿Quién cree el sistema que maneja el DNS?”
Primero: identifica qué es realmente /etc/resolv.conf
¿Es un archivo real o un enlace simbólico? Si es un enlace, ¿a dónde apunta?
Segundo: determina si systemd-resolved está activo y qué piensa
Si resolved está en ejecución, resolvectl status es tu verdad de base sobre qué servidores DNS se usan por interfaz, incluidas las interfaces VPN.
Tercero: verifica el modo DNS de NetworkManager
NetworkManager puede estar configurado para usar resolved, dnsmasq, o escribir resolv.conf. El modo equivocado es la forma más rápida de obtener un archivo que cambia cada vez que una interfaz cae o vuelve.
Cuarto: reproduce y observa los cambios en vivo
Cuando no puedes explicar un cambio, míralo suceder: tail al archivo, observa marcas de tiempo y correlaciónalo con los logs del journal. La mayoría de “reescrituras misteriosas” son una renovación de DHCP o una reconexión de VPN.
Datos interesantes e historia (porque este desorden tiene leyenda)
- Dato 1:
/etc/resolv.confprecede a la mayoría de las pilas de red modernas en Linux; viene de las tradiciones Unix donde la configuración de DNS era un simple archivo estático. - Dato 2: El enfoque de “stub resolver” (dirección local
127.x) existe porque permite caché y políticas DNS por interfaz sin enseñar nuevos trucos a cada aplicación. - Dato 3: Ubuntu ha usado durante mucho tiempo enlaces simbólicos para gestionar
/etc/resolv.conf(a través de distintas herramientas con el tiempo) porque múltiples componentes quieren suministrar DNS dinámicamente. - Dato 4: El DNS dividido se volvió común no porque sea elegante, sino porque las VPN corporativas y las VPC en la nube lo exigieron. Un único resolvedor para todo dejó de funcionar.
- Dato 5: Los dominios de búsqueda son una característica de productividad que también es una trampa: una lista larga puede ralentizar la resolución, filtrar consultas o producir colisiones de nombres inesperadas.
- Dato 6: Históricamente, muchos resolutores de libc solo leen
/etc/resolv.confe ignoran servicios de tiempo de ejecución sofisticados. Por eso el enlace simbólico sigue siendo pegamento de compatibilidad. - Dato 7: La caché DNS a nivel host puede ser una ganancia de rendimiento, pero también puede amplificar fallos cuando la caché negativa retiene errores.
- Dato 8: El comportamiento de la opción DNS en DHCP varía mucho según el equipo de red; algunos entornos sobrescriben DNS en la renovación incluso cuando en una interfaz UI se puso “DNS manual”.
Una idea para tener en la cabeza, parafraseada desde una voz de confiabilidad: la esperanza no es una estrategia
— atribuida a Gene Kranz, repetida en círculos de operaciones. Las soluciones DNS basadas en esperanza son cómo terminas explicando tus decisiones ante una junta de cambios.
Tareas prácticas: comandos, salida esperada y decisiones
Quieres diagnóstico repetible. Aquí hay tareas concretas que funcionan en Ubuntu 24.04. Cada una incluye qué suele significar su salida y qué decisión tomar después.
Tarea 1: Ver si /etc/resolv.conf es un enlace simbólico
cr0x@server:~$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Jun 2 10:14 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf
Significado: Está gestionado. Editarlo manualmente es, como mucho, temporal.
Decisión: Deja de editar el archivo. Decide si quieres resolved (recomendado) o no, luego configura las entradas adecuadamente.
Tarea 2: Identificar el contenido del objetivo del enlace
cr0x@server:~$ cat /etc/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
nameserver 127.0.0.53
options edns0 trust-ad
search corp.example
Significado: El sistema espera que las aplicaciones consulten el stub local, no los DNS upstream directamente.
Decisión: Si el DNS falla, investiga el estado de resolved y los servidores upstream en lugar de reemplazar esto por resolvers públicos.
Tarea 3: Comprobar si systemd-resolved está en ejecución
cr0x@server:~$ systemctl status systemd-resolved --no-pager
● systemd-resolved.service - Network Name Resolution
Loaded: loaded (/usr/lib/systemd/system/systemd-resolved.service; enabled; preset: enabled)
Active: active (running) since Mon 2025-12-29 08:12:41 UTC; 1h 2min ago
Significado: resolved está activo. Bien. Ahora pregúntale qué DNS está usando realmente.
Decisión: Si está inactivo o enmascarado, no intentes mantener el resolv.conf de stub. Escoge la Receta B en su lugar.
Tarea 4: Inspeccionar la vista de DNS de resolved (global y por enlace)
cr0x@server:~$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 10.10.0.53
DNS Servers: 10.10.0.53 10.10.0.54
DNS Domain: corp.example
Link 2 (ens192)
Current Scopes: DNS
Protocols: +DefaultRoute
Current DNS Server: 10.10.0.53
DNS Servers: 10.10.0.53 10.10.0.54
DNS Domain: corp.example
Significado: resolved es la autoridad y tiene servidores upstream. Si las búsquedas fallan, los upstream pueden ser inaccesibles, estar bloqueados o ser incorrectos.
Decisión: Si “Current DNS Server” está vacío, o apunta a algo inesperado (como una interfaz VPN cuando no estás en VPN), céntrate en la configuración de NetworkManager/VPN.
Tarea 5: Confirmar que NetworkManager gestiona la interfaz
cr0x@server:~$ nmcli device status
DEVICE TYPE STATE CONNECTION
ens192 ethernet connected Wired connection 1
lo loopback unmanaged --
Significado: NetworkManager está al mando de ens192.
Decisión: Configura DNS a través de los perfiles de conexión de NetworkManager (o netplan que los genere), no editando resolv.conf a mano.
Tarea 6: Comprobar el modo DNS de NetworkManager
cr0x@server:~$ nmcli general status
STATE CONNECTIVITY WIFI-HW WIFI WWAN-HW WWAN
connected full enabled enabled enabled enabled
cr0x@server:~$ grep -R "^\[main\]$\|^dns=" -n /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/conf.d/*.conf 2>/dev/null
/etc/NetworkManager/conf.d/10-dns.conf:1:[main]
/etc/NetworkManager/conf.d/10-dns.conf:2:dns=systemd-resolved
Significado: NetworkManager está configurado para alimentar a systemd-resolved. Ese es el valor sensato por defecto en muchas instalaciones de Ubuntu.
Decisión: Si el DNS es inestable, confirma que resolved está habilitado y que resolv.conf apunta al stub. Si prefieres que NM sea el dueño de resolv.conf, cambia a la Receta B de forma limpia.
Tarea 7: Inspeccionar los ajustes DNS de la conexión activa
cr0x@server:~$ nmcli -g ipv4.method,ipv4.dns,ipv4.ignore-auto-dns,ipv4.dns-search connection show "Wired connection 1"
auto
10.10.0.53,10.10.0.54
no
corp.example
Significado: Tienes servidores DNS explícitos y además DHCP no está ignorado (no). Eso puede provocar listas de DNS mezcladas según el comportamiento del DHCP.
Decisión: Si quieres DNS determinista, considera poner ipv4.ignore-auto-dns yes y especificar DNS/búsqueda explícitamente (con la contrapartida de que tendrás que mantenerlo).
Tarea 8: Ver registros recientes que expliquen quién reescribió DNS
cr0x@server:~$ journalctl -u systemd-resolved -n 80 --no-pager
Dec 29 09:01:10 server systemd-resolved[812]: Using DNS server 10.10.0.53 for interface ens192.
Dec 29 09:05:34 server systemd-resolved[812]: Switching to DNS server 10.10.0.54 for interface ens192.
cr0x@server:~$ journalctl -u NetworkManager -n 120 --no-pager
Dec 29 09:05:31 server NetworkManager[701]: <info> [..] dhcp4 (ens192): option domain_name_servers => '10.10.0.54 10.10.0.53'
Significado: Las renovaciones DHCP cambiaron el orden de los DNS ofrecidos; resolved siguió la secuencia.
Decisión: Decide si confiar en DHCP para DNS. Si no, sobreescribe en el perfil de NM y activa ipv4.ignore-auto-dns yes.
Tarea 9: Observar /etc/resolv.conf cambiar en tiempo real
cr0x@server:~$ sudo inotifywait -m /etc/resolv.conf
Setting up watches.
Watches established.
/etc/resolv.conf MODIFY
/etc/resolv.conf ATTRIB
Significado: Algo lo está tocando; ahora correlaciona las marcas de tiempo con los logs.
Decisión: Usa la marca de tiempo del evento para grep en los journal logs alrededor de ese momento; no adivines.
Tarea 10: Probar resolución a través de resolved explícitamente
cr0x@server:~$ resolvectl query repo.corp.example
repo.corp.example: 10.20.30.40 -- link: ens192
-- Information acquired via protocol DNS in 18.7ms.
-- Data is authenticated: no
Significado: resolved puede resolver ese nombre usando su camino DNS actual.
Decisión: Si las aplicaciones siguen fallando, tu problema podría ser nsswitch, DNS en contenedores o una app que hace su propio DNS (sí, algunas lo hacen).
Tarea 11: Probar la resolución “clásica” (y comparar)
cr0x@server:~$ getent hosts repo.corp.example
10.20.30.40 repo.corp.example
Significado: La resolución NSS de glibc está funcionando para aplicaciones normales.
Decisión: Si resolvectl query funciona pero getent falla (o viceversa), inspecciona /etc/nsswitch.conf y si las apps evitan NSS.
Tarea 12: Confirmar la elección de renderer en netplan (quién debe gestionar las interfaces)
cr0x@server:~$ sudo netplan get
network:
version: 2
renderer: NetworkManager
Significado: NetworkManager está destinado a gestionar la red en este host.
Decisión: Evita habilitar configuraciones de systemd-networkd que compitan, a menos que estés migrando intencionalmente.
Tarea 13: Comprobar si cloud-init reescribe red/DNS
cr0x@server:~$ cloud-init status
status: done
cr0x@server:~$ grep -R "manage_resolv_conf" -n /etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.d/*.cfg 2>/dev/null
/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg:2:manage_resolv_conf: false
Significado: Si manage_resolv_conf es true, cloud-init puede reescribir el estado del resolvedor en el arranque.
Decisión: En imágenes cloud, desactiva explícitamente la gestión del resolvedor por cloud-init a menos que realmente quieras que lo gestione.
Tarea 14: Comprobar si hay un dnsmasq local u otro resolvedor ocupando el puerto 53
cr0x@server:~$ sudo ss -lntup | grep -E ":53\s"
udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=812,fd=14))
tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=812,fd=15))
Significado: resolved está escuchando en el stub. Eso es lo esperado en modo stub.
Decisión: Si ves dnsmasq u otro servicio vinculando 127.0.0.53 o 0.0.0.0:53, tienes un conflicto. Decide qué resolvedor debe ejecutarse y deshabilita el otro.
Elige tu arquitectura (no mezcles estas)
Arquitectura 1: systemd-resolved es el resolvedor, NetworkManager le suministra
Esta es la forma “nativa de Ubuntu” para muchas instalaciones. Obtienes DNS por interfaz, buen comportamiento con VPN y una historia clara de dónde provienen los cambios. Tu /etc/resolv.conf típicamente apunta al stub.
Haz esto cuando: tengas VPNs, múltiples enlaces, requisitos de DNS dividido, o quieras comportamiento moderno que no dependa de que todas las aplicaciones se porten bien.
Arquitectura 2: deshabilitar systemd-resolved, NetworkManager escribe /etc/resolv.conf
Esta es la forma “clásica”: las aplicaciones leen /etc/resolv.conf con servidores upstream. Es más simple, y a veces vale la pena. Pero pierdes algunas capacidades de DNS dividido a menos que la herramienta de VPN lo compense.
Haz esto cuando: ejecutes servidores mínimos, no necesites DNS dividido, o tengas una pila de aplicaciones que se comporta mal con resolved stub.
Arquitectura 3: resolv.conf estático (inmutable o gestionado manualmente)
Esta es una opción para controladores. Puede ser correcta en entornos muy controlados (aislados, appliances de laboratorio o servidores con propósito especial). También es una forma común de romper DHCP/VPN silenciosamente.
Haz esto cuando: los servidores DNS nunca cambian y entiendes el coste operativo. De lo contrario, no lo hagas.
Segunda verdad seca y graciosa: si “simplemente pones chattr +i” para salir del problema, no estás arreglando el sistema—estás empezando un hobby.
Receta A (recomendada): systemd-resolved + NetworkManager, correctamente
Estado objetivo
systemd-resolvedhabilitado y en ejecución- NetworkManager configurado con
dns=systemd-resolved /etc/resolv.confenlazado simbólicamente al stub (o al archivo “real” de resolved, según prefieras)- DNS configurado en los perfiles de conexión de NetworkManager (o heredado de DHCP/VPN según corresponda)
Paso 1: asegurar que systemd-resolved esté habilitado
cr0x@server:~$ sudo systemctl enable --now systemd-resolved
Created symlink /etc/systemd/system/multi-user.target.wants/systemd-resolved.service → /usr/lib/systemd/system/systemd-resolved.service.
Significado: resolved arrancará en el arranque y está iniciado ahora.
Decisión: Si habilitar falla porque está enmascarado, desmáscara y vuelve a habilitar.
cr0x@server:~$ sudo systemctl unmask systemd-resolved
Removed "/etc/systemd/system/systemd-resolved.service".
Paso 2: configurar NetworkManager para usar resolved
Crea (o verifica) un drop-in de configuración, no un archivo main editado a mano que olvidarás luego.
cr0x@server:~$ sudo tee /etc/NetworkManager/conf.d/10-dns-systemd-resolved.conf >/dev/null <<'EOF'
[main]
dns=systemd-resolved
EOF
cr0x@server:~$ sudo systemctl restart NetworkManager
Significado: NetworkManager actualizará resolved en lugar de luchar por resolv.conf.
Decisión: Si antes usabas dns=dnsmasq, elimínalo a menos que realmente quieras dnsmasq como front-end (la mayoría no lo desea).
Paso 3: arreglar el enlace simbólico de /etc/resolv.conf
En un sistema gestionado por resolved, generalmente quieres el archivo stub:
cr0x@server:~$ sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
cr0x@server:~$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 37 Dec 29 09:21 /etc/resolv.conf -> /run/systemd/resolve/stub-resolv.conf
Significado: las aplicaciones ven 127.0.0.53 y usan resolved para la política.
Decisión: Si tienes software que falla con un stub resolver (algunos contenedores antiguos, runtimes embebidos o chroots extraños), considera enlazar al listado “real” de upstream en su lugar:
cr0x@server:~$ sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
Ese archivo contiene directamente los servidores upstream. Pierdes algunos beneficios, pero mantienes compatibilidad.
Paso 4: configurar DNS en el lugar correcto (perfiles NM)
Si quieres DNS estático independientemente de DHCP:
cr0x@server:~$ sudo nmcli connection modify "Wired connection 1" ipv4.ignore-auto-dns yes
cr0x@server:~$ sudo nmcli connection modify "Wired connection 1" ipv4.dns "10.10.0.53 10.10.0.54"
cr0x@server:~$ sudo nmcli connection modify "Wired connection 1" ipv4.dns-search "corp.example"
cr0x@server:~$ sudo nmcli connection up "Wired connection 1"
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/7)
Significado: NetworkManager dejará de importar DNS desde DHCP para esta conexión y usará lo que especificaste.
Decisión: Usa esto solo si el DNS de DHCP no es fiable o necesitas comportamiento consistente entre redes.
Paso 5: verificar de extremo a extremo
cr0x@server:~$ resolvectl status | sed -n '1,35p'
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 10.10.0.53
DNS Servers: 10.10.0.53 10.10.0.54
DNS Domain: corp.example
Significado: resolved está en modo stub y tiene tus upstreams previstos.
Decisión: Si resolv.conf mode es “foreign”, algo más está escribiendo resolv.conf. Ve directamente a la sección Errores comunes.
Receta B: deshabilitar systemd-resolved y dejar que NetworkManager escriba resolv.conf
Esto es para entornos donde quieres comportamiento antiguo y aceptas las compensaciones. La clave es hacerlo limpiamente: deshabilita resolved, reemplaza el enlace simbólico por un archivo real (o por un archivo gestionado por NM) y configura el plugin DNS de NetworkManager en consecuencia.
Paso 1: detener y deshabilitar resolved
cr0x@server:~$ sudo systemctl disable --now systemd-resolved
Removed "/etc/systemd/system/multi-user.target.wants/systemd-resolved.service".
Significado: resolved no se ejecutará ni gestionará el comportamiento del stub.
Decisión: Asegúrate de que nada más apunte aún a 127.0.0.53 después de esto.
Paso 2: configurar NetworkManager para gestionar DNS directamente
Dependiendo de tu entorno, establecer dns=default suele ser suficiente.
cr0x@server:~$ sudo tee /etc/NetworkManager/conf.d/10-dns-default.conf >/dev/null <<'EOF'
[main]
dns=default
EOF
cr0x@server:~$ sudo rm -f /etc/NetworkManager/conf.d/10-dns-systemd-resolved.conf
cr0x@server:~$ sudo systemctl restart NetworkManager
Significado: NetworkManager escribirá la información del resolvedor mediante su mecanismo por defecto.
Decisión: Si tenías otros plugins DNS configurados, elimínalos; los plugins mixtos crean resultados impredecibles.
Paso 3: reemplazar /etc/resolv.conf por un archivo regular
cr0x@server:~$ sudo rm -f /etc/resolv.conf
cr0x@server:~$ sudo touch /etc/resolv.conf
cr0x@server:~$ sudo chmod 644 /etc/resolv.conf
cr0x@server:~$ ls -l /etc/resolv.conf
-rw-r--r-- 1 root root 0 Dec 29 09:40 /etc/resolv.conf
Significado: ya no es un enlace simbólico.
Decisión: Baja y sube la conexión para que NM lo pueble, luego verifica el contenido.
cr0x@server:~$ sudo nmcli networking off
cr0x@server:~$ sudo nmcli networking on
cr0x@server:~$ cat /etc/resolv.conf
nameserver 10.10.0.53
nameserver 10.10.0.54
search corp.example
Significado: las aplicaciones consultarán los DNS upstream directamente.
Decisión: Confirma que ningún servicio espere 127.0.0.53; si tenías contenedores o resolvedores locales configurados, ajústalos.
Receta C: resolv.conf estático (solo si realmente lo necesitas)
Un /etc/resolv.conf estático puede ser apropiado para ciertos appliances o servidores aislados. No es una solución general para “sigue cambiando” porque no trata a quién está intentando cambiarlo.
Hazlo estático sin jugar con el sistema de archivos
Prefiere la política a la inmovilidad. Indica a NetworkManager que deje de tocar el DNS para esa conexión:
cr0x@server:~$ sudo nmcli connection modify "Wired connection 1" ipv4.ignore-auto-dns yes
cr0x@server:~$ sudo nmcli connection modify "Wired connection 1" ipv6.ignore-auto-dns yes
cr0x@server:~$ sudo nmcli connection up "Wired connection 1"
Luego gestiona el archivo explícitamente:
cr0x@server:~$ sudo tee /etc/resolv.conf >/dev/null <<'EOF'
nameserver 10.10.0.53
nameserver 10.10.0.54
search corp.example
options timeout:2 attempts:2
EOF
Significado: te haces responsable de las actualizaciones de DNS. Ya no hay red de seguridad automática.
Decisión: Haz esto solo cuando los servidores DNS sean estables y tengas control de cambios sobre ellos.
VPN y DNS dividido: la parte que suele doler
La mayoría de las quejas “mi resolv.conf sigue cambiando” son en realidad quejas de DNS dividido con abrigo. Una VPN se conecta, empuja dominios y servidores internos, luego tu interfaz principal renueva DHCP y reordena los DNS. O el cliente VPN insiste en ser la ruta por defecto y arrastra el DNS con ello.
Cómo debería verse el DNS dividido con systemd-resolved
Con resolved quieres dominios y servidores DNS por enlace. Los dominios internos van al DNS de la VPN; el resto va a tu DNS normal (o a resolvers públicos si esa es tu política).
Diagnostica comprobando dominios por enlace:
cr0x@server:~$ resolvectl status | sed -n '1,200p'
Global
resolv.conf mode: stub
Link 2 (ens192)
DNS Servers: 10.10.0.53 10.10.0.54
DNS Domain: ~.
Link 8 (tun0)
DNS Servers: 172.16.1.10
DNS Domain: corp.example
Significado:
~.indica un dominio de enrutamiento por defecto (todos los nombres) para ese enlace. Si tu enlace VPN obtiene~., puede apropiarse de todas las consultas DNS.- Dominios como
corp.examplesin~.se enrutan solo para ese sufijo.
Decisión: Si la VPN se está apoderando de todo cuando no debería, arregla los ajustes del plugin VPN o las propiedades de la conexión NM para evitar que la VPN establezca el DNS por defecto.
Controles de NetworkManager que importan para el comportamiento DNS de la VPN
Varían según el tipo de VPN, pero el enfoque de depuración es consistente: inspecciona las propiedades IP y rutas del perfil de conexión, luego asegúrate de que la VPN no esté configurada como “usar esta conexión solo para recursos de su red” a menos que realmente quieras eso.
Comprueba los detalles de la conexión VPN:
cr0x@server:~$ nmcli connection show "Corp VPN" | grep -E "ipv4\.|ipv6\.|vpn\."
ipv4.never-default: no
ipv4.ignore-auto-dns: no
ipv4.dns: --
ipv4.dns-search: --
Significado: Si never-default es no, la VPN puede convertirse en ruta por defecto dependiendo del comportamiento del plugin. Si ignore-auto-dns es no, puede importar DNS y potencialmente sobrescribirlos.
Decisión: Para comportamiento de túnel dividido, pon ipv4.never-default yes en la conexión VPN y asegúrate de que los dominios estén configurados específicamente.
cr0x@server:~$ sudo nmcli connection modify "Corp VPN" ipv4.never-default yes
cr0x@server:~$ sudo nmcli connection up "Corp VPN"
Cuando las aplicaciones ignoran el resolvedor del sistema
Algunos runtimes traen su propio resolvedor o caché. Algunos contenedores montan su propio /etc/resolv.conf. Algunas pilas Java hacen caché de DNS haciendo que las interrupciones duren más de lo esperado.
Si el host resuelve pero la aplicación no, compara esto:
cr0x@server:~$ getent hosts internal.service.corp.example
10.50.0.15 internal.service.corp.example
cr0x@server:~$ sudo resolvectl query internal.service.corp.example
internal.service.corp.example: 10.50.0.15 -- link: tun0
Decisión: Si ambos funcionan en el host pero la app falla, inspecciona la caché DNS del runtime de la app y la configuración del resolvedor en los contenedores. No “lo arregles” reemplazando el DNS del host por 8.8.8.8 y esperando que las zonas corporativas aparezcan allí.
Errores comunes: síntoma → causa raíz → arreglo
1) Síntoma: /etc/resolv.conf se restablece a 127.0.0.53 después de cada reinicio
Causa raíz: Estás en la Receta A (resolved), pero sigues reemplazando el enlace simbólico por un archivo regular. Los servicios de arranque restauran el enlace.
Arreglo: Decide usar resolved y configura DNS vía NetworkManager; mantiene /etc/resolv.conf enlazado a /run/systemd/resolve/stub-resolv.conf (o a /run/systemd/resolve/resolv.conf para compatibilidad).
2) Síntoma: resolv.conf contiene servidores upstream, pero resolvectl muestra servidores diferentes
Causa raíz: Modo “foreign”: algo aparte de resolved está gestionando /etc/resolv.conf, pero resolved sigue en ejecución y tomando sus propias decisiones para las apps que consultan el stub.
Arreglo: O bien deshabilita resolved (Receta B) u restaura el enlace simbólico de resolv.conf (Receta A). No ejecutes ambos patrones a la vez.
3) Síntoma: DNS funciona hasta que se conecta la VPN; entonces fallan las búsquedas públicas (o al revés)
Causa raíz: La VPN está configurada como ruta por defecto y/o dominio DNS por defecto (~.), apropiándose de todas las consultas.
Arreglo: Configura DNS dividido: la VPN debe poseer solo los sufijos corporativos; pon ipv4.never-default yes y asegúrate de que los dominios estén acotados. Verifica con resolvectl status.
4) Síntoma: el DNS cambia cada pocas horas
Causa raíz: Las renovaciones DHCP reordenan o reemplazan los servidores DNS; NetworkManager los importa fielmente.
Arreglo: Si el DNS de DHCP está mal, sobrescribe en el perfil de NM y pon ipv4.ignore-auto-dns yes. De lo contrario, arregla la configuración del servidor DHCP (la solución correcta, aunque no siempre la más fácil).
5) Síntoma: “Temporary failure in name resolution” esporádicamente, especialmente bajo carga
Causa raíz: El upstream DNS es lento/inaccesible, o la expansión por dominios de búsqueda causa múltiples consultas fallidas por búsqueda. A veces MTU/fragmentación VPN causa problemas UDP en DNS.
Arreglo: Mide con resolvectl query los tiempos, revisa los dominios de búsqueda y prueba el fallback por TCP. Si hay VPN implicada, verifica MTU y considera forzar paquetes DNS más pequeños vía política upstream (no mutilando resolv.conf).
6) Síntoma: los contenedores resuelven distinto que el host
Causa raíz: El runtime de contenedores inyecta su propio /etc/resolv.conf. También común: apunta a 127.0.0.53 que no es alcanzable desde el namespace de red del contenedor.
Arreglo: Configura el runtime para usar el resolv.conf upstream (para setups con resolved, usa /run/systemd/resolve/resolv.conf como fuente), o configura un servidor DNS alcanzable desde los contenedores.
7) Síntoma: deshabilitas resolved, pero las apps aún consultan 127.0.0.53
Causa raíz: /etc/resolv.conf aún apunta al stub-resolv.conf, o tienes configuraciones obsoletas en chroots/contenedores.
Arreglo: Reemplaza resolv.conf por un archivo real con servidores upstream y reinicia los servicios afectados que cachean estado del resolvedor.
Listas de verificación / plan paso a paso
Lista 1: Estabilizar DNS en un workstation típico Ubuntu 24.04 (recomendado)
- Confirma que netplan usa NetworkManager:
sudo netplan get→ buscarenderer: NetworkManager. - Habilita resolved:
sudo systemctl enable --now systemd-resolved. - Configura NM para usar resolved mediante un drop-in en
/etc/NetworkManager/conf.d/. - Enlaza
/etc/resolv.confa/run/systemd/resolve/stub-resolv.conf. - Configura DNS por conexión en NM si debes sobreescribir DHCP:
nmcli connection modify ... ipv4.ignore-auto-dns yes. - Verifica con
resolvectl statusygetent hosts. - Conecta la VPN y vuelve a comprobar los dominios por enlace; corrige el robo de ruta por defecto si ocurre.
Lista 2: Estabilizar DNS en un servidor donde quieres el resolv.conf clásico
- Deshabilita resolved:
sudo systemctl disable --now systemd-resolved. - Configura NetworkManager
dns=default(o el plugin elegido, pero elige uno). - Reemplaza el enlace simbólico
/etc/resolv.confpor un archivo regular. - Cicla la red:
sudo nmcli networking off && sudo nmcli networking on. - Verifica que
/etc/resolv.confcontenga servidores upstream y quegetent hostsfuncione. - Para clientes VPN, asegúrate de que actualicen resolv.conf de forma controlada o usa DNS explícito.
Lista 3: Cuando “algo lo sigue cambiando” y necesitas pruebas
- Mira los cambios:
sudo inotifywait -m /etc/resolv.conf. - Captura timestamps y correlaciónalos con
journalctl -u NetworkManageryjournalctl -u systemd-resolved. - Comprueba cloud-init:
cloud-init statusy grep demanage_resolv_conf. - Busca ediciones por gestión de configuración: revisa tu automatización, unidades systemd y cron jobs (sí, la gente aún cronnea arreglos DNS).
- Una vez identificado, elimina al escritor competidor. No negocies con él.
Tres micro-historias corporativas desde el frente
Micro-historia 1: El incidente causado por una suposición errónea
El equipo tenía una flota de servidores Ubuntu, mayormente estables y aburridos. Un nuevo servicio interno empezó a fallar de forma que parecía un bug de aplicación: 502 intermitentes, reintentos y luego todo “se arreglaba mágicamente”. La primera suposición fue la peor: “DNS no puede ser el problema, lo configuramos en resolv.conf”.
De hecho, habían “configurado” eso. Meses antes, alguien editó /etc/resolv.conf directamente para forzar servidores DNS internos porque DHCP en un entorno entregaba resolvers públicos. Funcionó hasta el siguiente reinicio, y entonces lo volvieron a editar. Eventualmente una regla de gestión de configuración lo reaplicó diariamente. Eso no es gestión de DNS; es un juego de golpea-la-mole con privilegios root.
Después de actualizar algunos hosts, systemd-resolved se activó y /etc/resolv.conf volvió a ser un enlace simbólico. El job diario reemplazaba con un archivo que contenía DNS upstream, pero algunas aplicaciones seguían usando resolved en ciertos contextos, y algunos servicios cacheaban resolución de forma distinta. Existían dos rutas de resolvedor en el mismo host. Los fallos dependían del timing y de qué ruta de librería usaba el proceso.
La solución no fue “poner mejores servidores DNS”. La solución fue elegir un dueño: estandarizaron en resolved + NetworkManager, quitaron el job diario y movieron la política DNS a perfiles NM. Una vez que el sistema tuvo una única fuente de la verdad, el “bug de aplicación” desapareció. El postmortem fue incómodo por una razón: todos sabían que estaban editando resolv.conf como si fuera 2003.
Micro-historia 2: La optimización que salió mal
Otra organización tenía una iniciativa de rendimiento: reducir la latencia de lookup DNS para microservicios. Alguien notó búsquedas repetidas a los mismos nombres y decidió que la caché local ayudaría. Habilitaron caché a nivel host y empujaron una configuración para apuntar todas las cargas al stub local.
La latencia mejoró. Todos felices. Luego una falla parcial en el tier DNS interno golpeó. Los servidores autorizados eran inestables, no caídos—timeouts, SERVFAIL ocasionales. El resolvedor con caché empezó a cachear negativamente los fallos. Un único fallo transitorio se convirtió en un “no” persistente por la vida de la caché, y la tasa de fallos se volvió de “picos recuperables” a “plana y brutal”.
Lo peor: la incidencia parecía una regresión de la aplicación porque los reinicios no ayudaban. Algunos hosts se recuperaron rápido; otros no. La diferencia fue el estado de la caché. Empezaron a drenar nodos, revertir despliegues y discutir qué cambio lo provocó. El verdadero culpable fue la optimización que eliminó la variabilidad natural y convirtió problemas transitorios en pegajosos.
Al final mantuvieron la caché porque no es inherentemente mala. Pero ajustaron el comportamiento de caché negativa donde fue posible, mejoraron la fiabilidad del DNS upstream y—esto es importante—añadieron diagnósticos: snapshots de resolvectl status en los runbooks de incidentes. Las optimizaciones están bien. Las optimizaciones silenciosas son cómo te ganas un nuevo tono de pager.
Micro-historia 3: La práctica aburrida pero correcta que salvó el día
Una empresa tenía un estándar aburrido y casi molesto: cada host Linux debía pasar una comprobación de “propiedad DNS” durante el aprovisionamiento. Verificaba si el host usaba resolved o no, aseguraba que el estado del enlace simbólico coincidiera y confirmaba el modo DNS de NetworkManager. Los ingenieros se quejaban de que era burocrático.
Entonces llegó una fusión. Dos redes, dos soluciones VPN, dos políticas DHCP y una flota combinada de laptops y agentes de compilación. El comportamiento de DNS se volvió impredecible de la noche a la mañana. La respuesta humana natural fue aplicar “arreglos rápidos” a resolv.conf en los hosts afectados.
Los equipos que siguieron el estándar aburrido no hicieron eso. Ejecutaron la comprobación de propiedad, vieron qué parte del stack debía gestionar DNS y ajustaron solo las entradas: ajustes DNS en perfiles NM y alcance del DNS dividido de la VPN. Eso hizo sus arreglos duraderos. Los reinicios no volvieron a romper las cosas. Las reconexiones VPN no voltearon aleatoriamente el orden de resolvedores.
Mientras tanto, los equipos con soluciones ad-hoc acabaron con un zoológico: algunos hosts tenían resolv.conf inmutable, otros enlaces simbólicos, otros had disabled resolved pero aún referenciaban 127.0.0.53. El equipo aburrido entregó features mientras los demás depuraban “por qué solo este portátil no puede alcanzar el repo de artefactos”. La corrección suele ser tediosa. También escala.
Preguntas frecuentes
1) ¿Por qué /etc/resolv.conf es un enlace simbólico en Ubuntu 24.04?
Porque el DNS ahora es dinámico: DHCP, VPN y múltiples interfaces pueden cambiar la política DNS. El enlace simbólico apunta a un archivo generado para que el sistema pueda actualizar el estado del resolvedor sin editar a mano.
2) ¿127.0.0.53 es “incorrecto”?
No. Es la dirección del stub resolver local usada por systemd-resolved. Las aplicaciones envían consultas DNS allí; resolved las reenvía a servidores upstream reales según la política por enlace.
3) ¿Cómo detengo que resolv.conf cambie?
Deja de tratar a /etc/resolv.conf como la fuente de configuración. Elige una arquitectura: usa resolved y configura NetworkManager para alimentarlo (Receta A), o deshabilita resolved y deja que NetworkManager escriba servidores upstream (Receta B).
4) ¿Qué significa “resolv.conf mode: foreign” en resolvectl?
Normalmente significa que resolved detectó que /etc/resolv.conf no es su archivo gestionado/enlace, por lo que algo más lo está gestionando. Es una señal de que tienes propietarios en competencia y deberías elegir uno claramente.
5) Puse DNS en la interfaz gráfica, pero sigue revirtiendo. ¿Por qué?
A menudo porque DHCP sigue estando permitido para proporcionar DNS y sobrescribir/mezclar ajustes. Revisa nmcli -g ipv4.ignore-auto-dns .... Ponlo en yes si quieres DNS manual determinista en esa conexión.
6) La VPN rompe mi DNS público o mi DNS corporativo. ¿Cuál es la mejor aproximación?
Usa DNS dividido con resolved: zonas corporativas dirigidas al DNS de la VPN, todo lo demás a tu DNS normal. Verifica dominios por enlace con resolvectl status. Evita que la VPN reclame el dominio de enrutamiento por defecto a menos que quieras que todo el DNS vaya a través de ella.
7) ¿Debo hacer /etc/resolv.conf inmutable con chattr?
Sólo si disfrutas de autocausarte interrupciones. Bloquea actualizaciones legítimas de DNS (renovaciones DHCP, conexiones VPN) y crea modos de fallo confusos. Prefiere la propiedad y la configuración adecuada.
8) ¿Cómo depuro “DNS funciona en el host pero no en contenedores”?
Comprueba qué /etc/resolv.conf ve el contenedor. Si apunta a 127.0.0.53 pero el contenedor no puede alcanzar esa dirección (namespace de red distinto), configura el runtime para usar los servidores upstream (a menudo desde /run/systemd/resolve/resolv.conf) o proporciona un servidor DNS alcanzable.
9) ¿Es mala idea deshabilitar systemd-resolved?
No inherentemente. Es una compensación. Simplifica las cosas para algunos servidores, pero puede complicar DNS dividido y comportamiento de VPN. Si lo deshabilitas, hazlo limpiamente y verifica que nadie siga apuntando a 127.0.0.53.
Conclusión: DNS estable, vida estable
La solución duradera para “resolv.conf sigue cambiando” no es pelear con el archivo. Es elegir un dueño del DNS y hacer que todos los demás componentes le provean información en vez de competir.
Próximos pasos que realmente resisten reinicios, reconexiones VPN y renovaciones DHCP:
- Ejecuta el diagnóstico rápido: comprobación de enlace simbólico → estado de resolved → modo DNS de NetworkManager → observa cambios en vivo.
- Si quieres DNS dividido moderno y comportamiento sensato multi-enlace, implementa la Receta A y mantén el enlace al stub.
- Si quieres comportamiento clásico para un servidor simple, implementa la Receta B y elimina el stub por completo.
- Documenta qué modelo elegiste para tu flota. Los incidentes DNS más caros empiezan con “pensé que este host estaba usando…”