Modifier resolv.conf ne répare pas le DNS après la déconnexion du VPN
Un résolveur de tunnel mort en tête de liste coûte un délai d’attente par requête. Vérifiez qui possède le fichier, réinitialisez l’état du lien et cessez de modifier une sortie générée.
Vous déconnectez le VPN, ping 1.1.1.1 répond encore, et chaque résolution de nom reste suspendue avant que la page finisse par abandonner. Puis cat /etc/resolv.conf montre un serveur de noms qui n’a jamais existé qu’à l’intérieur du tunnel, généralement en tête de liste. Supprimer cette ligne semble corriger le problème pendant une dizaine de minutes, jusqu’à ce qu’une suspension, une itinérance Wi-Fi ou un redémarrage la remette. Le fichier que vous avez modifié n’est pas le réglage ; c’est un rendu de l’état du lien que possède un autre composant.
Pourquoi une entrée obsolète coûte des secondes par requête
Le résolveur glibc parcourt la liste des serveurs de noms dans l’ordre et attend l’expiration d’un délai avant d’essayer le suivant, et resolv.conf(5) limite cette liste à trois entrées. Placez un résolveur côté tunnel comme 10.8.0.1 en tête une fois le tunnel disparu, et chaque requête paie le délai avant de basculer vers un serveur qui répond. C’est pourquoi le symptôme ressemble à une connexion morte plutôt qu’à une erreur DNS : les navigateurs bloquent, expirent et servent parfois une adresse en cache qui deviendra obsolète plus tard.
Cela explique aussi pourquoi la plainte arrive sous la forme « internet est cassé ». Un ping vers une adresse IP prouve que le lien est bon, ce qui fait ressembler la panne à l’application. La liste des résolveurs est la première chose à lire et la dernière à modifier.
Le mythe : resolv.conf est un fichier de réglages
Demandez ce qu’est réellement ce chemin avant de le changer :
ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
Sur un hôte systemd-resolved, c’est un lien symbolique vers un fichier stub pointant vers 127.0.0.53, et les vrais serveurs vivent dans l’état par lien que resolvectl affiche. Sur un hôte NetworkManager, ce peut être un fichier que NetworkManager écrit depuis la connexion active. Avec certains clients d’éditeurs, c’est un fichier simple réécrit sur place à la connexion et, si vous n’avez pas de chance, jamais restauré à la déconnexion. Ce sont trois propriétaires différents, et modifier les deux premiers à la main soit ne fait rien, soit tient jusqu’au prochain événement réseau.
resolvectl status est la vue qui dit la vérité : serveurs DNS par lien, domaines de routage, et si le lien du tunnel existe encore. resolvectl query example.com va plus loin et montre quelle interface a répondu. Utilisez les deux avant de toucher un fichier, et gardez à l’esprit qu’un navigateur doté de son propre DNS sécurisé ignore tout cela.
Trouvez le propriétaire avant de modifier quoi que ce soit
Trois composants se disputent généralement le même réglage : systemd-resolved, NetworkManager et ce que le client VPN a installé. Identifiez d’abord celui qui est actif :
systemctl is-active systemd-resolved
nmcli connection show --active
ps aux | grep -E "openvpn|wg-quick|vpn"
Si resolved est actif et que le lien symbolique pointe vers son stub, le fichier global est une sortie générée et votre modification est cosmétique. Si NetworkManager possède la connexion, les serveurs appartiennent au profil de connexion, donc le correctif est un changement de propriété via nmcli et non une modification de fichier. Si un démon d’éditeur tourne, seul son propre chemin de restauration survit à la connexion suivante.
Nettoyez l’état du lien laissé par le client
Un client tué ne peut pas exécuter son hook de nettoyage. SIGKILL ne peut pas être intercepté du tout, alors que SIGINT et SIGTERM le peuvent, donc un tunnel qui « s’est simplement arrêté » après un kill forcé laisse souvent en place à la fois l’enregistrement de l’interface et l’entrée du résolveur. Trouvez le PID précis et n’envoyez le signal qu’à celui-là :
ps aux | grep -E "openvpn|wg-quick"
sudo kill <pid>
resolvectl revert tun0
Ne vous précipitez pas sur pkill -f vpn ou killall vpn avant d’avoir lu la liste complète des correspondances. -f correspond à toute la ligne de commande, il peut donc terminer un script d’enveloppe, une session d’éditeur ou un processus sans rapport dont le chemin contient la chaîne. Terminer le mauvais processus en pleine exécution, c’est ainsi qu’un problème de résolveur devient un fichier perdu.
resolvectl revert réinitialise la configuration DNS d’exécution de ce lien, ce qui est plus étroit que redémarrer le résolveur et bien plus étroit que modifier le fichier global. Si le lien du tunnel a entièrement disparu, systemctl restart NetworkManager reconstruit l’état de la connexion et c’est l’étape à laquelle les fils sources reviennent sans cesse. Surveillez un gestionnaire de services avec Restart=always, car il peut remettre un client tué, et ses réglages DNS, directement en place.
L’autre direction : un DNS poussé qui n’est jamais arrivé
L’image miroir de l’entrée obsolète est un tunnel sans aucun résolveur utilisable. Une option DNS dans le profil est une demande ; le composant qui gère la connexion doit la transmettre au résolveur. Si le journal montre que le serveur a été reçu mais que le lien du tunnel ne porte aucun réglage DNS, c’est l’intégration qui manque, pas le serveur.
Testez la transmission en la faisant à la main, ce qui sépare « le serveur est faux » de « personne ne l’a appliquée » :
resolvectl dns tun0 10.10.10.10
resolvectl domain tun0 ~.
Le domaine de routage fourre-tout envoie chaque nom vers ce lien, ce que veut un client tunnel complet et ce que le DNS scindé ne doit pas utiliser. Ces réglages disparaissent à la connexion suivante. Pour les rendre persistants dans NetworkManager, désactivez le DNS automatique, définissez le serveur sur la connexion et ajoutez le domaine :
nmcli connection modify office ipv4.ignore-auto-dns yes
nmcli connection modify office ipv4.dns 10.10.10.10
nmcli connection modify office ipv4.dns-search "~."
Pour un tunnel d’entreprise qui ne doit répondre qu’aux noms internes, listez ces zones avec un tilde initial au lieu du fourre-tout, afin que les noms publics continuent d’utiliser le résolveur local.
Des contournements qui deviennent la prochaine panne
Copier resolv.conf avant de se connecter et le restaurer ensuite est une ligne légitime dans un runbook, et c’est un contournement plutôt qu’une réparation. Il échoue exactement quand cela compte, parce qu’un plantage ou un redémarrage forcé saute la restauration. Notez-le comme contournement pour que la personne suivante ne construise pas dessus.
Désactiver systemd-resolved et coder en dur des serveurs publics est l’autre geste populaire. Il rend la connexion et la déconnexion prévisibles et supprime le DNS par lien pour tout autre réseau, ce qui casse le DNS scindé pour les noms internes et anéantit le but d’un tunnel censé garder les requêtes à l’intérieur. Installer resolvconf et épingler des serveurs publics coûte la même chose avec une couche de plus. Traitez l’un ou l’autre comme un diagnostic : s’il rétablit la navigation, vous avez appris que l’intégration du résolveur est fautive, pas que les serveurs publics sont corrects.
Le correctif durable est un propriétaire par couche : décidez quel composant possède le DNS du lien du tunnel et lequel possède la valeur globale par défaut, notez-le et retirez les autres du chemin. Puis vérifiez après une déconnexion avec un nom que seul le VPN résout. Si un nom privé répond encore, l’enregistrement n’a pas été retiré ; si rien ne se résout, le fichier pointe vers un serveur qui n’existe plus. Les deux sont visibles dans resolvectl avant d’ouvrir un navigateur.