Vous modifiez /etc/resolv.conf, cela tient cinq minutes, puis le fichier « utilement » revient en arrière. Votre application perd la résolution de noms, votre VPN avec DNS split cesse de fonctionner, et le canal d’astreinte commence à sentir le toast brûlé.
Ubuntu 24.04 n’a pas cassé le DNS. Il a simplement rendu la responsabilité du DNS plus explicite : systemd-resolved, NetworkManager, le DHCP et parfois les plugins VPN essaient tous d’être l’adulte dans la pièce. Si vous ne choisissez pas une autorité — et ne la reliez pas proprement — resolv.conf devient un champ de bataille d’écritures.
Le modèle mental : qui gère le DNS sur Ubuntu 24.04
/etc/resolv.conf ressemble à un simple fichier. Sur les Ubuntu modernes, c’est souvent un lien symbolique vers quelque chose de généré. Ce n’est pas une conspiration ; c’est du plomberie. La vraie question est : quel composant est la source de vérité pour le DNS ?
Les principaux acteurs
- systemd-resolved : un service de résolveur local qui peut faire du cache, DNS-over-TLS (dans certains déploiements) et DNS par lien (split DNS). Il expose couramment un stub local à
127.0.0.53et écrit un resolv.conf « géré ». - NetworkManager : l’orchestrateur réseau pour postes de travail et beaucoup de serveurs, surtout quand netplan utilise le renderer NetworkManager. Il collecte le DNS depuis DHCP/VPN/config statique et peut le transmettre à
systemd-resolvedou écrire/etc/resolv.confdirectement selon la configuration. - Clients DHCP (souvent via NetworkManager) : fournissent des serveurs DNS et des domaines de recherche, parfois de manière agressive. Si le serveur DHCP est erroné, votre machine devient erronée, de façon fiable et à grande échelle.
- Plugins VPN : ajoutent des routes et du DNS. Certains attendent du split DNS. D’autres imposent un override complet du DNS. Certains font de leur mieux et perdent quand même face à votre configuration locale.
- netplan : génère la configuration de bas niveau. Il ne « fait » pas le DNS à l’exécution, mais il décide quel renderer (NetworkManager ou systemd-networkd) s’en chargera.
Ce que « resolv.conf se réinitialise » signifie généralement
Ce n’est presque jamais aléatoire. C’est le résultat déterministe d’un de ces cas :
/etc/resolv.confest un lien symbolique vers un fichier généré, et vous continuez à modifier la sortie de la cible du symlink au lieu des entrées.- NetworkManager est configuré pour utiliser
systemd-resolved, mais resolved est désactivé ou mal lié, donc NetworkManager redescend à l’écriture directe. - Deux gestionnaires DNS sont activés et pensent tous deux être responsables.
- Un VPN se connecte et pousse du DNS, puis le DHCP renouvelle et le remplace (ou l’inverse).
- Un outil de configuration (cloud-init, provisioning, gestion de configuration) « corrige » le DNS au démarrage.
Vérité sèchement drôle : /etc/resolv.conf est le ruban adhésif du réseau Linux — quelqu’un suppose toujours que c’est l’endroit pour coller une réparation, et ça se décroche systématiquement à 3 h du matin.
Choisissez une autorité. Branchez les autres pour qu’ils l’alimentent. Et arrêtez d’éditer /etc/resolv.conf à la main à moins que votre objectif soit de créer un mystère pour votre futur vous.
Playbook de diagnostic rapide (vérifiez d’abord ceci)
Si le DNS est en panne ou que resolv.conf ne reste pas en place, ne commencez pas par éditer quoi que ce soit. Commencez par répondre : « Qui l’a écrit en dernier ? » et « Qui le système pense-t-il gérer le DNS ? »
Première étape : identifier ce qu’est réellement /etc/resolv.conf
Est-ce un fichier réel ou un lien symbolique ? Si c’est un symlink, vers où pointe-t-il ?
Deuxième étape : déterminer si systemd-resolved est actif et ce qu’il pense
Si resolved tourne, resolvectl status est votre vérité de base sur les serveurs DNS réellement utilisés par interface, y compris les liens VPN.
Troisième étape : vérifier le mode DNS de NetworkManager
NetworkManager peut être configuré pour utiliser resolved, dnsmasq, ou écrire resolv.conf. Le mauvais mode est la manière la plus rapide d’obtenir un fichier qui change chaque fois qu’un lien bouge.
Quatrième étape : reproduire et observer les changements en direct
Quand vous ne pouvez pas expliquer un changement, regardez-le se produire : tail du fichier, regardez les horodatages et corrélez avec les logs du journal. La plupart des « réécritures mystères » sont un renouvellement DHCP ou une reconnexion VPN.
Faits intéressants & historique (parce que ce bazar a sa légende)
- Fait 1 :
/etc/resolv.confexiste avant la plupart des stacks réseau modernes ; il vient des traditions Unix où la configuration DNS était un simple fichier statique. - Fait 2 : L’approche du « stub resolver » (adresse locale
127.x) existe parce qu’elle permet le cache et des politiques DNS par interface sans enseigner de nouvelles règles à chaque application. - Fait 3 : Ubuntu utilise depuis longtemps des symlinks pour la gestion de
/etc/resolv.conf(via différents outils au fil du temps) parce que plusieurs composants veulent fournir le DNS dynamiquement. - Fait 4 : Le split DNS est devenu courant non pas parce qu’il est élégant, mais parce que les VPN d’entreprise et les VPC cloud l’ont imposé. Un résolveur pour tout a cessé de fonctionner.
- Fait 5 : Les domaines de recherche sont une fonctionnalité productive qui fait aussi office de piège : une longue liste de recherche peut ralentir la résolution, divulguer des requêtes ou produire des collisions de noms surprenantes.
- Fait 6 : Historiquement, de nombreux resolveurs libc ne lisaient que
/etc/resolv.confet ignoraient les services d’exécution avancés. C’est pourquoi le symlink compte encore : c’est le glue de compatibilité. - Fait 7 : Le cache DNS au niveau hôte peut améliorer les performances, mais peut aussi amplifier les pannes quand le cache négatif conserve des échecs.
- Fait 8 : Le comportement de l’option DNS du DHCP varie beaucoup selon l’équipement réseau ; certains environnements réécrivent le DNS au renouvellement même quand « DNS manuel » est défini dans une interface graphique.
Une idée paraphrasée d’une voix fiabilité à garder en tête : « paraphrased idea: “Hope is not a strategy” » — attribuée à Gene Kranz, souvent répétée dans les cercles opérations. Les correctifs DNS basés sur l’espoir sont la façon dont vous vous retrouvez à expliquer vos choix à un comité de revue des changements.
Tâches pratiques : commandes, sorties attendues et décisions
Vous voulez un diagnostic reproductible. Voici des tâches concrètes qui fonctionnent sur Ubuntu 24.04. Chacune inclut ce que la sortie signifie généralement et quelle décision prendre ensuite.
Tâche 1 : Voir si /etc/resolv.conf est un symlink
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
Signification : Il est géré. L’éditer manuellement n’est qu’une mesure temporaire au mieux.
Décision : Arrêtez d’éditer le fichier. Décidez si vous voulez resolved (recommandé) ou pas, puis configurez les entrées en conséquence.
Tâche 2 : Identifier le contenu de la cible du symlink
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
Signification : Le système attend que les applications interrogent le stub local, pas les DNS en amont directement.
Décision : Si le DNS échoue, inspectez le statut de resolved et les serveurs en amont plutôt que de remplacer ceci par des résolveurs publics.
Tâche 3 : Vérifier si systemd-resolved tourne
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
Signification : resolved est actif. Bien. Demandez-lui maintenant quels DNS il utilise réellement.
Décision : S’il est inactif ou masqué, n’essayez pas de garder le resolv.conf stub. Choisissez la Recette B à la place.
Tâche 4 : Inspecter la vue du DNS par resolved (globale et par lien)
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
Signification : resolved est l’autorité, et il a des serveurs en amont. Si les résolutions échouent, l’amont peut être injoignable, bloqué ou erroné.
Décision : Si « Current DNS Server » est vide, ou pointe vers quelque chose d’inattendu (comme un lien VPN alors que vous n’êtes pas en VPN), concentrez-vous sur la configuration de NetworkManager/VPN.
Tâche 5 : Confirmer que NetworkManager gère l’interface
cr0x@server:~$ nmcli device status
DEVICE TYPE STATE CONNECTION
ens192 ethernet connected Wired connection 1
lo loopback unmanaged --
Signification : NetworkManager est au volant pour ens192.
Décision : Configurez le DNS via les profils de connexion NetworkManager (ou netplan qui les génère), pas en éditant resolv.conf à la main.
Tâche 6 : Vérifier le mode 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
Signification : NetworkManager est configuré pour alimenter systemd-resolved. C’est le comportement sensé par défaut dans de nombreuses installations Ubuntu.
Décision : Si le DNS est instable, confirmez que resolved est activé et que resolv.conf pointe vers le stub. Si vous voulez que NM possède resolv.conf, passez proprement à la Recette B.
Tâche 7 : Inspecter les paramètres DNS de la connexion active
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
Signification : Vous avez des serveurs DNS explicites plus le DHCP auto-DNS n’est pas ignoré (no). Cela peut conduire à des listes DNS mixtes selon le comportement du DHCP.
Décision : Si vous voulez un DNS déterministe, envisagez de définir ipv4.ignore-auto-dns yes et de spécifier DNS/search explicitement (au prix de devoir les maintenir).
Tâche 8 : Voir les logs récents qui expliquent qui a réécrit le 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'
Signification : Les renouvellements DHCP ont changé l’ordre des DNS proposés ; resolved a suivi.
Décision : Décidez si le DHCP doit être digne de confiance. Sinon, surchargez le DNS dans le profil NM et ignorez le DNS automatique.
Tâche 9 : Surveiller /etc/resolv.conf en temps réel
cr0x@server:~$ sudo inotifywait -m /etc/resolv.conf
Setting up watches.
Watches established.
/etc/resolv.conf MODIFY
/etc/resolv.conf ATTRIB
Signification : Quelque chose le touche ; corrélez maintenant les horodatages avec les logs.
Décision : Utilisez l’horodatage de l’événement pour greper les logs du journal autour de ce moment ; ne devinez pas.
Tâche 10 : Tester la résolution via resolved explicitement
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
Signification : resolved peut résoudre ce nom en utilisant son chemin DNS actuel.
Décision : Si les applications échouent toujours, votre problème pourrait être nsswitch, le DNS des conteneurs, ou une application faisant son propre DNS (oui, certaines le font).
Tâche 11 : Tester la résolution « classique » (et comparer)
cr0x@server:~$ getent hosts repo.corp.example
10.20.30.40 repo.corp.example
Signification : La résolution NSS de glibc fonctionne pour les applications normales.
Décision : Si resolvectl query fonctionne mais getent échoue (ou vice versa), inspectez /etc/nsswitch.conf et si des applications contournent NSS.
Tâche 12 : Confirmer le choix du renderer de netplan (qui doit gérer les liens)
cr0x@server:~$ sudo netplan get
network:
version: 2
renderer: NetworkManager
Signification : NetworkManager est destiné à gérer le réseau sur cet hôte.
Décision : Évitez d’activer des configurations systemd-networkd qui concurrencent, sauf si vous migrez intentionnellement.
Tâche 13 : Vérifier si cloud-init réécrit le réseau/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
Signification : Si manage_resolv_conf est true, cloud-init peut réécrire l’état du résolveur au démarrage.
Décision : Dans les images cloud, désactivez explicitement la gestion du résolveur par cloud-init à moins que vous vouliez qu’il gère le DNS.
Tâche 14 : Vérifier s’il y a un dnsmasq local ou un autre résolveur qui vole le port 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))
Signification : resolved écoute sur le stub. C’est attendu en mode stub.
Décision : Si vous voyez dnsmasq ou un autre service liant 127.0.0.53 ou 0.0.0.0:53, vous avez un conflit. Décidez quel résolveur doit tourner et désactivez l’autre.
Choisissez votre architecture (ne mélangez pas)
Architecture 1 : systemd-resolved est le résolveur, NetworkManager l’alimente
C’est la manière « native Ubuntu » pour de nombreuses installations. Vous obtenez du DNS par interface, un bon comportement VPN et une histoire claire pour l’origine des changements. Votre /etc/resolv.conf pointe typiquement vers le stub.
Faites ceci quand : vous avez des VPN, plusieurs liens, des besoins de split DNS, ou vous voulez un comportement moderne qui ne dépend pas de chaque application.
Architecture 2 : désactiver systemd-resolved, NetworkManager écrit /etc/resolv.conf
C’est la manière « classique » : les applications lisent /etc/resolv.conf avec des serveurs amont. C’est plus simple, et parfois cela vaut le coup. Mais vous perdez certaines capacités de split DNS à moins que l’outil VPN ne compense.
Faites ceci quand : vous exécutez des serveurs minimaux, vous n’avez pas besoin de split DNS, ou vous avez une pile applicative qui se comporte mal avec les stub resolvers.
Architecture 3 : /etc/resolv.conf statique (immutable ou géré manuellement)
C’est une option de contrôle absolu. Cela peut être correct dans des environnements très contrôlés (air-gapped, appliances de laboratoire ou serveurs à usage spécial). C’est aussi une façon courante de casser silencieusement les configurations DHCP/VPN.
Faites ceci quand : les serveurs DNS ne changent jamais et vous comprenez le coût opérationnel. Sinon, n’y allez pas.
Deuxième vérité sèchement drôle : si vous « chattr +i » pour sortir du churn DNS, vous ne réparez pas un système — vous commencez un hobby.
Recette A (recommandée) : systemd-resolved + NetworkManager, correctement
État cible
systemd-resolvedactivé et en cours d’exécution- NetworkManager configuré avec
dns=systemd-resolved /etc/resolv.conflié symboliquement vers le stub (ou vers le fichier « réel » de resolved, selon votre préférence)- DNS configuré dans les profils de connexion NetworkManager (ou hérité du DHCP/VPN comme prévu)
Étape 1 : s’assurer que systemd-resolved est activé
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.
Signification : resolved démarrera au boot et est démarré maintenant.
Décision : Si l’activation échoue parce qu’il est masqué, démasquez-le et réactivez.
cr0x@server:~$ sudo systemctl unmask systemd-resolved
Removed "/etc/systemd/system/systemd-resolved.service".
Étape 2 : configurer NetworkManager pour utiliser resolved
Créez (ou vérifiez) un drop-in, pas un fichier principal édité à la main que vous oublierez plus tard.
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
Signification : NetworkManager mettra à jour resolved au lieu de se disputer le resolv.conf.
Décision : Si vous utilisiez dns=dnsmasq auparavant, retirez-le à moins que vous n’ayez l’intention d’avoir dnsmasq devant (la plupart des gens ne le veulent pas).
Étape 3 : réparer le symlink /etc/resolv.conf
Sur un système géré par resolved, vous voulez en général le fichier 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
Signification : les applications voient 127.0.0.53 et utilisent resolved pour la politique.
Décision : Si un logiciel casse avec un stub resolver (certains vieux conteneurs, runtimes embarqués ou chroots étranges), envisagez de lier vers la liste d’amont « réelle » à la place :
cr0x@server:~$ sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
Cet fichier contient les serveurs en amont directement. Vous perdez certains avantages, mais vous gardez la compatibilité.
Étape 4 : configurer le DNS au bon endroit (profils NM)
Si vous voulez un DNS statique indépendamment du 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)
Signification : NetworkManager cessera d’importer le DNS depuis DHCP pour cette connexion et utilisera ce que vous avez spécifié.
Décision : N’utilisez ceci que si le DNS DHCP n’est pas digne de confiance ou si vous avez besoin d’un comportement cohérent entre réseaux.
Étape 5 : vérifier de bout en bout
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
Signification : resolved est en mode stub et a vos amonts voulus.
Décision : Si resolv.conf mode est « foreign », quelque chose d’autre écrit resolv.conf. Allez directement à la section Erreurs fréquentes.
Recette B : désactiver systemd-resolved et laisser NetworkManager écrire resolv.conf
Cela convient aux environnements où vous voulez le comportement à l’ancienne et acceptez les compromis. L’important est de le faire proprement : désactivez resolved, remplacez le symlink par un fichier réel (ou un fichier géré par NM), et configurez le plugin DNS de NetworkManager en conséquence.
Étape 1 : arrêter et désactiver resolved
cr0x@server:~$ sudo systemctl disable --now systemd-resolved
Removed "/etc/systemd/system/multi-user.target.wants/systemd-resolved.service".
Signification : resolved ne tournera plus ni ne gérera le comportement stub.
Décision : Assurez-vous que rien d’autre ne pointe encore vers 127.0.0.53 après cela.
Étape 2 : configurer NetworkManager pour gérer le DNS directement
Selon votre environnement, définir dns=default suffit souvent.
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
Signification : NetworkManager écrira l’information de résolveur via son mécanisme par défaut.
Décision : Si vous aviez d’autres plugins DNS configurés, retirez-les ; les plugins mixtes créent des résultats imprévisibles.
Étape 3 : remplacer /etc/resolv.conf par un fichier régulier
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
Signification : ce n’est plus un symlink.
Décision : Ramenez la connexion down/up pour que NM le remplisse, puis vérifiez le contenu.
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
Signification : les applications interrogeront les DNS en amont directement.
Décision : Confirmez qu’aucun service n’attend 127.0.0.53 ; si vous aviez des conteneurs ou des résolveurs locaux configurés, ajustez-les.
Recette C : resolv.conf statique (uniquement si vous le pensez vraiment)
Un /etc/resolv.conf statique peut convenir pour certains appliances ou serveurs isolés. Ce n’est pas une correction générale pour « il se réinitialise sans cesse » parce que cela n’adresse pas qui essaie de le changer.
Rendre statique sans jouer avec le système de fichiers
Privilégiez la politique plutôt que l’immuabilité. Dites à NetworkManager d’arrêter de toucher le DNS pour cette connexion :
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"
Puis gérez le fichier explicitement :
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
Signification : vous prenez la responsabilité des mises à jour DNS. Il n’y a plus de filet de sécurité automatisé.
Décision : Faites-le uniquement quand les serveurs DNS sont stables et que vous avez le contrôle des changements.
VPN et DNS split : la partie qui fait mal
La plupart des plaintes « mon resolv.conf se réinitialise » sont en réalité des plaintes de split-DNS déguisées. Un VPN se connecte, pousse des domaines et serveurs internes, puis votre interface principale renouvelle le DHCP et réordonne le DNS. Ou le client VPN insiste pour être la route par défaut et entraîne le DNS avec lui.
À quoi le split DNS devrait ressembler avec systemd-resolved
Avec resolved, vous voulez des domaines et serveurs DNS par lien. Les domaines internes vont au DNS du VPN ; tout le reste va à votre DNS normal (ou à des résolveurs publics si c’est votre politique).
Diagnostiquez en vérifiant les domaines par lien :
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
Signification :
~.indique un domaine de routage par défaut (tous les noms) pour ce lien. Si votre lien VPN obtient~., il peut voler tout le DNS.- Les domaines comme
corp.examplesans~.sont routés uniquement pour ce suffixe.
Décision : Si le VPN vole tout alors qu’il ne devrait pas, corrigez les paramètres du plugin VPN ou les propriétés de la connexion NM pour éviter que le VPN ne devienne la route DNS par défaut.
Les réglages NetworkManager importants pour le comportement DNS du VPN
Ils varient selon le type de VPN, mais l’approche de debug est consistante : inspectez les paramètres IP du profil de connexion et les routes, puis assurez-vous que le VPN n’est pas configuré comme « utiliser cette connexion seulement pour les ressources de son réseau » sauf si c’est ce que vous voulez.
Vérifiez les détails de la connexion 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: --
Signification : Si never-default est no, le VPN peut devenir la route par défaut selon le comportement du plugin. Si ignore-auto-dns est no, il peut importer le DNS et potentiellement écraser.
Décision : Pour un split-tunnel, définissez ipv4.never-default yes sur la connexion VPN et assurez-vous que les domaines sont configurés spécifiquement.
cr0x@server:~$ sudo nmcli connection modify "Corp VPN" ipv4.never-default yes
cr0x@server:~$ sudo nmcli connection up "Corp VPN"
Quand les applications ignorent le résolveur système
Certains runtimes embarquent leur propre résolveur ou cache. Certains conteneurs montent leur propre /etc/resolv.conf. Certaines piles Java font du caching DNS qui prolonge les pannes plus longtemps que nécessaire.
Si votre hôte résout mais que l’application non, comparez ceci :
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
Décision : Si les deux fonctionnent sur l’hôte, mais que l’application échoue, inspectez le caching DNS du runtime et toute configuration de résolveur du conteneur. Ne « réparez » pas ça en remplaçant le DNS de l’hôte par 8.8.8.8 en espérant que les zones d’entreprise y existent magiquement.
Erreurs fréquentes : symptôme → cause racine → correctif
1) Symptom : /etc/resolv.conf revient à 127.0.0.53 après chaque reboot
Cause racine : Vous êtes sur la Recette A (resolved), mais vous remplacez sans cesse le symlink par un fichier régulier. Les services de démarrage restaurent le symlink.
Correctif : Décidez d’utiliser resolved et configurez le DNS via NetworkManager ; gardez /etc/resolv.conf lié vers /run/systemd/resolve/stub-resolv.conf (ou vers /run/systemd/resolve/resolv.conf pour la compatibilité).
2) Symptom : resolv.conf contient des serveurs amont, mais resolvectl montre d’autres serveurs
Cause racine : mode « foreign » : quelque chose d’autre que resolved gère /etc/resolv.conf, mais resolved tourne encore et prend ses propres décisions pour les applis qui interrogent le stub.
Correctif : Soit désactivez resolved (Recette B), soit restaurez le symlink resolv.conf (Recette A). Ne faites pas les deux en même temps.
3) Symptom : le DNS fonctionne jusqu’à la connexion du VPN ; ensuite les requêtes publiques échouent (ou inversement)
Cause racine : Le VPN est défini comme route par défaut et/ou comme domaine DNS par défaut (~.), volant toutes les requêtes.
Correctif : Configurez le split DNS : le VPN ne doit posséder que les suffixes d’entreprise ; mettez ipv4.never-default yes et assurez-vous que les domaines sont scopiés. Vérifiez avec resolvectl status.
4) Symptom : le DNS change toutes les quelques heures
Cause racine : Les renouvellements DHCP réordonnent ou remplacent les serveurs DNS ; NetworkManager les importe fidèlement.
Correctif : Si le DNS DHCP est erroné, surchargez-le dans le profil NM et mettez ipv4.ignore-auto-dns yes. Sinon, corrigez la configuration du serveur DHCP (la solution correcte, mais pas toujours la plus simple).
5) Symptom : « Temporary failure in name resolution » sporadiquement, surtout sous charge
Cause racine : L’amont DNS est lent/injoignable, ou l’expansion des domaines de recherche provoque plusieurs requêtes échouées par résolution. Parfois la fragmentation MTU/VPN cause des problèmes UDP DNS.
Correctif : Mesurez avec resolvectl query les temps, révisez les domaines de recherche et testez le fallback TCP. Si un VPN est impliqué, vérifiez le MTU et envisagez de forcer des paquets DNS plus petits via la politique en amont (pas en mutilant resolv.conf).
6) Symptom : les conteneurs résolvent différemment de l’hôte
Cause racine : Le runtime du conteneur injecte son propre /etc/resolv.conf. Très souvent : il pointe vers 127.0.0.53 qui n’est pas joignable depuis l’espace de noms réseau du conteneur.
Correctif : Configurez le runtime pour utiliser le resolv.conf en amont (pour les setups resolved, utilisez /run/systemd/resolve/resolv.conf comme source), ou fournissez un serveur DNS atteignable depuis les conteneurs.
7) Symptom : vous désactivez resolved, mais les applis interrogent encore 127.0.0.53
Cause racine : /etc/resolv.conf pointe encore vers stub-resolv.conf, ou vous avez une configuration obsolète dans des chroots/containers.
Correctif : Remplacez resolv.conf par un fichier réel contenant des serveurs amont, et redémarrez les services affectés qui mettent en cache l’état du résolveur.
Listes de contrôle / plan étape par étape
Checklist 1 : Stabiliser le DNS sur un poste Ubuntu 24.04 typique (recommandé)
- Confirmer que netplan utilise NetworkManager :
sudo netplan get→ vérifierrenderer: NetworkManager. - Activer resolved :
sudo systemctl enable --now systemd-resolved. - Configurer NM pour utiliser resolved via un drop-in dans
/etc/NetworkManager/conf.d/. - Lier
/etc/resolv.confvers/run/systemd/resolve/stub-resolv.conf. - Configurer le DNS par connexion NM si vous devez surcharger le DHCP :
nmcli connection modify ... ipv4.ignore-auto-dns yes. - Vérifier avec
resolvectl statusetgetent hosts. - Connecter le VPN et revérifier les domaines par lien ; corriger le vol de route par défaut si nécessaire.
Checklist 2 : Stabiliser le DNS sur un serveur où vous voulez le resolv.conf classique
- Désactiver resolved :
sudo systemctl disable --now systemd-resolved. - Configurer NetworkManager
dns=default(ou votre plugin choisi, mais choisissez-en un). - Remplacer le symlink
/etc/resolv.confpar un fichier régulier. - Recharger le réseau :
sudo nmcli networking off && sudo nmcli networking on. - Vérifier que
/etc/resolv.confcontient les serveurs amont et quegetent hostsfonctionne. - Pour les clients VPN, assurez-vous qu’ils mettent à jour resolv.conf de manière contrôlée ou utilisez des DNS explicites.
Checklist 3 : Quand « quelque chose le change sans cesse » et que vous avez besoin de preuves
- Surveiller les changements :
sudo inotifywait -m /etc/resolv.conf. - Capturer les horodatages et corréler avec
journalctl -u NetworkManageretjournalctl -u systemd-resolved. - Vérifier cloud-init :
cloud-init statuset grep pourmanage_resolv_conf. - Rechercher des modifications via la gestion de configuration : vérifiez votre automatisation, unités systemd et cron jobs (oui, certains utilisent encore cron pour corriger le DNS).
- Une fois identifié, supprimez l’écrivain concurrent. Ne négociez pas avec lui.
Trois mini-histoires d’entreprise du terrain
Mini-histoire 1 : l’incident causé par une mauvaise hypothèse
L’équipe avait une flotte de serveurs Ubuntu, majoritairement stable et sans histoires. Un nouveau service interne a commencé à échouer d’une manière qui ressemblait à un bug applicatif : 502 intermittents, retries, puis tout se « réparait » magiquement. La première hypothèse fut la pire : « Le DNS ne peut pas être en cause, on l’a mis dans resolv.conf. »
En réalité, ils l’avaient « mis ». Des mois plus tôt, quelqu’un avait édité /etc/resolv.conf directement pour forcer des serveurs DNS internes, parce que le DHCP dans un environnement donnait des résolveurs publics. Ça fonctionnait jusqu’au reboot suivant, et alors ils l’éditaient à nouveau. Finalement une règle de gestion de configuration a été ajoutée pour le réappliquer quotidiennement. Ce n’est pas de la gestion DNS ; c’est du whack-a-mole avec des privilèges root.
Après mise à niveau de certains hôtes, systemd-resolved est redevenu actif et /etc/resolv.conf est redevenu un symlink. Le job quotidien de configuration le remplaçait par un fichier contenant les DNS en amont, mais certaines applications utilisaient encore resolved dans certains contextes, et certains services gardaient un cache de résolution différent. Deux chemins de résolveur existaient sur le même hôte. Les pannes dépendaient du timing et de quel chemin de bibliothèque le processus utilisait.
La correction n’a pas été « mettre de meilleurs serveurs DNS ». La correction a été de choisir un propriétaire : ils se sont standardisés sur resolved + NetworkManager, ont supprimé le job quotidien et déplacé la politique DNS dans les profils NM. Une fois qu’il y eut une seule source de vérité, le « bug applicatif » disparut. Le postmortem fut gênant pour exactement une raison : tout le monde savait qu’on éditait resolv.conf comme en 2003.
Mini-histoire 2 : l’optimisation qui s’est retournée contre eux
Une autre organisation avait une initiative de performance : réduire la latence des requêtes DNS pour des microservices. Quelqu’un a remarqué des requêtes répétées vers les mêmes noms et a décidé qu’un cache local aiderait. Ils ont activé le cache résolveur au niveau hôte et poussé une config pour pointer toutes les charges de travail vers le stub local.
La latence s’est améliorée. Tout le monde était content. Puis une panne partielle de la couche DNS interne a eu lieu. Les serveurs autoritatifs étaient instables, pas morts — timeouts, SERVFAIL occasionnels. Le résolveur local a commencé à mettre en cache négativement les échecs. Un seul miss transitoire est devenu un « non » persistant pour la durée du cache, et le taux d’échec des services est passé de « pointilleux et récupérable » à « plat et brutal ».
Le pire : la panne ressemblait à une régression applicative parce que les redémarrages n’aidaient pas. Certains hôtes se sont rétablis vite ; d’autres non. La différence était l’état du cache. Les gens ont commencé à vider des nœuds, rollback des déploiements et à se disputer sur la cause. Le vrai coupable était l’optimisation qui avait supprimé l’aleatoire naturel et transformé des problèmes DNS transitoires en pannes tenaces.
Ils ont finalement conservé le caching, car ce n’est pas intrinsèquement mauvais. Mais ils ont ajusté le comportement de cache négatif quand possible, amélioré la fiabilité des DNS en amont et — aspect important — ajouté des diagnostics : des snapshots resolvectl status dans les runbooks d’incident. Les optimisations sont bien. Les optimisations silencieuses sont la manière d’acheter un nouveau son de pager.
Mini-histoire 3 : la pratique ennuyeuse mais correcte qui a sauvé la mise
Une entreprise avait une norme ennuyeuse, presque agaçante : chaque hôte Linux devait passer un « check de propriété DNS » lors du provisioning. Il vérifiait si l’hôte utilisait resolved ou non, s’assurait que l’état du symlink correspondait et confirmait le mode DNS de NetworkManager. Les ingénieurs se plaignaient que c’était bureaucratique.
Puis vint une fusion. Deux réseaux, deux solutions VPN, deux politiques DHCP et une flotte combinée d’ordinateurs portables et d’agents de build. Le comportement DNS devint imprévisible du jour au lendemain. La réponse humaine naturelle fut d’appliquer des « quick fixes » à resolv.conf sur les hôtes affectés.
Les équipes qui suivaient la norme ennuyeuse n’ont pas fait cela. Elles ont exécuté le contrôle de propriété, vu quelle partie de la pile devait gérer le DNS et n’ont ajusté que les entrées : paramètres DNS des profils NM et le scope du split DNS du VPN. Leurs correctifs ont tenu. Les reboots n’ont pas réeclaté les choses. Les reconnexions VPN n’ont pas basculé aléatoirement l’ordre des résolveurs.
Pendant ce temps, les équipes de dépannage ad hoc se sont retrouvées avec un zoo : certains hôtes avaient un resolv.conf immuable, d’autres des symlinks, d’autres encore avaient disabled resolved mais référaient toujours 127.0.0.53. L’équipe ennuyeuse a livré des fonctionnalités pendant que les autres déboguaient « pourquoi seulement ce laptop ne peut pas atteindre le repo d’artefacts ». La bonne pratique est souvent fastidieuse. Elle scale aussi.
FAQ
1) Pourquoi /etc/resolv.conf est-il un symlink sur Ubuntu 24.04 ?
Parce que le DNS est dynamique maintenant : DHCP, VPN et plusieurs interfaces peuvent tous changer la politique DNS. Le symlink pointe vers un fichier généré afin que le système puisse mettre à jour l’état du résolveur sans éditer à la main.
2) Est-ce que 127.0.0.53 est « mauvais » ?
Non. C’est l’adresse du stub résolveur local utilisée par systemd-resolved. Les applications y envoient les requêtes DNS ; resolved les relaie vers les serveurs DNS en amont selon la politique par lien.
3) Comment empêcher resolv.conf de changer ?
Arrêtez de traiter /etc/resolv.conf comme la source de configuration. Choisissez une architecture : utilisez resolved et configurez NetworkManager pour l’alimenter (Recette A), ou désactivez resolved et laissez NetworkManager écrire les serveurs amont (Recette B).
4) Que signifie « resolv.conf mode: foreign » dans resolvectl ?
Cela signifie généralement que resolved a détecté que /etc/resolv.conf n’est pas son fichier géré/symlink, donc quelque chose d’autre le gère. C’est le signe que vous avez des propriétaires concurrents et devez en choisir un proprement.
5) J’ai défini le DNS dans l’interface graphique, mais il revient. Pourquoi ?
Souvent parce que le DHCP est toujours autorisé à fournir le DNS et écrase/fusionne les paramètres. Vérifiez nmcli -g ipv4.ignore-auto-dns .... Mettez-le à yes si vous voulez un DNS manuel déterministe sur cette connexion.
6) Le VPN casse mon DNS public ou mon DNS d’entreprise. Quelle est la meilleure approche ?
Utilisez le split DNS avec resolved : les zones d’entreprise routées vers le DNS du VPN, tout le reste vers votre DNS normal. Vérifiez les domaines par lien avec resolvectl status. Évitez de laisser le VPN revendiquer le domaine de routage par défaut à moins que vous ne vouliez que tout passe par lui.
7) Dois-je rendre /etc/resolv.conf immuable avec chattr ?
Seulement si vous aimez les pannes auto-infligées. Cela bloque les mises à jour légitimes du DNS (renouvellements DHCP, connexions VPN) et crée des modes d’échec déroutants. Préférez une bonne propriété et configuration.
8) Comment déboguer « le DNS marche sur l’hôte mais pas dans les conteneurs » ?
Vérifiez quel /etc/resolv.conf le conteneur voit. S’il pointe vers 127.0.0.53 mais que le conteneur ne peut pas atteindre cette adresse (espace de noms réseau différent), configurez le runtime pour utiliser les serveurs en amont (souvent depuis /run/systemd/resolve/resolv.conf) ou fournissez un serveur DNS atteignable.
9) Désactiver systemd-resolved est-ce une mauvaise idée ?
Pas intrinsèquement. C’est un compromis. Cela simplifie certaines configurations de serveurs, mais peut rendre le split DNS et le comportement VPN plus difficiles. Si vous le désactivez, faites-le proprement et vérifiez que personne ne pointe encore vers 127.0.0.53.
Conclusion : DNS stable, vie stable
La correction durable pour « resolv.conf se réinitialise sans cesse » n’est pas de se battre contre le fichier. C’est de choisir un propriétaire du DNS et de faire en sorte que tous les autres composants l’alimentent au lieu de concurrencer.
Étapes suivantes qui tiennent vraiment au reboot, aux reconnexions VPN et aux renouvellements DHCP :
- Exécutez le diagnostic rapide : vérification du symlink → statut de resolved → mode DNS de NetworkManager → surveillez les changements en direct.
- Si vous voulez le split DNS moderne et un comportement multi-lien sensé, implémentez la Recette A et conservez le symlink stub.
- Si vous voulez le comportement classique pour un serveur simple, implémentez la Recette B et supprimez complètement le stub.
- Documentez le modèle choisi pour votre flotte. Les incidents DNS les plus coûteux commencent par « je pensais que cet hôte utilisait… »