Pourquoi les noms DNS privés échouent sur les clients VPN et où vérifier
Les noms privés ne se résolvent que si le client fait confiance à votre résolveur, si le suffixe est délimité et si la réponse peut revenir par le tunnel.
Vous ouvrez un portable dans une chambre d’hôtel, démarrez le client, tapez le nom du serveur de fichiers interne et n’obtenez rien. Le tunnel indique connecté, et un ping vers une adresse du même sous-réseau répond encore, donc le transport lui-même est correct. Seul le nom échoue, et cet écart réduit le problème à deux endroits : quel résolveur le client a interrogé et si la réponse obtenue peut revenir par le tunnel. Réglez l’un et négligez l’autre, et la panne se déplace simplement.
Avant de modifier un profil, vérifiez ce que le client fait du nom. Sous Linux, resolvectl query files.corp.example indique quelle interface et quel résolveur ont produit la réponse. Sous Windows, Resolve-DnsName files.corp.example montre le serveur qui a répondu et l’adresse qu’il a renvoyée.
Lisez la réponse avant de changer quoi que ce soit
Si le nom revient en NXDOMAIN en quelques millisecondes, la requête n’a jamais atteint votre zone et un résolveur public ou d’hôtel a répondu à sa place. S’il revient après une longue pause, quelque chose abandonne le port UDP 53 en route et le client a fini par se rabattre. S’il répond avec la bonne adresse mais que la connexion bloque encore, la résolution est correcte et votre problème vient du routage ou du service lui-même.
Ce découpage en trois épargne une heure de tâtonnements. Il vous dit aussi s’il faut toucher au VPN : un nom qui se résout vers la bonne adresse privée a déjà prouvé le chemin du résolveur, donc le travail restant se situe sur le chemin des données.
Distribuez le résolveur depuis l’intérieur du tunnel
Les clients se répartissent en deux groupes. L’un peut recevoir un résolveur du serveur pendant l’établissement de la connexion ; l’autre garde le réglage dans un fichier local qu’aucune passerelle ne peut modifier à distance.
OpenVPN appartient au premier groupe. Sur le serveur, push "dhcp-option DNS 10.8.0.53" et push "dhcp-option DOMAIN corp.example" descendent par le canal de contrôle, mais seulement si la configuration du client a encore pull activé. Un client modifié à la main et portant pull-filter ignore "dhcp-option" ne les verra jamais, et cette seule ligne explique un nombre surprenant de cas où « le serveur le pousse mais mon portable n’est pas d’accord ».
WireGuard appartient au second groupe, car le protocole n’a aucune négociation d’options. Le résolveur et le domaine de recherche vont dans le bloc [Interface] du client, sous la forme DNS = 10.8.0.53, corp.example. wg-quick l’applique via resolvconf ou systemd-resolved, et sous Windows le client officiel installe des règles NRPT qui n’existent que tant que le tunnel est monté : Get-DnsClientNrptPolicy les liste, ce qui en fait un moyen rapide de voir si le client a un jour appliqué votre fichier.
IPsec/IKEv2 se situe entre les deux. Le plugin attr de strongSwan peut renvoyer un serveur DNS tiré d’un pool, et un client Windows l’accepte normalement, mais un profil qui impose son propre serveur de noms l’emporte sur ce que la passerelle propose. Sur un client Linux, l’étape manuelle équivalente est resolvectl dns wg0 10.8.0.53 puis resolvectl domain wg0 '~corp.example' ; les deux disparaissent avec l’interface, ce qui est exactement ce que l’on veut pour un réglage limité au tunnel.
Délimitez le suffixe au lieu d’avaler chaque requête
Pointer toute la liste de résolveurs du client vers votre serveur interne est simple et généralement faux. Chaque nom public se résout alors depuis la sortie de votre centre de données, les CDN renvoient des adresses lointaines, et une panne du résolveur emporte la navigation de l’utilisateur avec elle.
N’envoyez vers l’intérieur que le suffixe privé. Sous systemd-resolved, un domaine commençant par ~ ne sert qu’au routage, donc ~corp.example signifie que les requêtes sous ce suffixe vont aux serveurs de ce lien tandis que tout le reste continue d’utiliser le réseau physique. Windows fait de même avec des règles NRPT limitées à un espace de noms, et macOS avec un fichier de résolveur supplémentaire sous /etc/resolver/.
Les noms de multidiffusion méritent leur propre réponse. Les noms .local sont locaux au lien par conception (RFC 6762) et une interface tun point à point ne transporte pas ce groupe de multidiffusion, donc ajouter un résolveur public ne les publiera pas et interroger un résolveur interne en monodiffusion à leur sujet renvoie NXDOMAIN. Un réflecteur comme avahi en mode réflecteur peut relier deux segments, mais c’est une décision côté serveur qu’aucun client ne peut demander. Si une imprimante ou un NAS doit être joignable par nom, donnez-lui plutôt un enregistrement A dans votre zone.
Prouvez que la réponse peut revenir
Une réponse correcte pointant vers une adresse injoignable ressemble exactement à un problème de résolveur jusqu’à ce que vous vérifiiez la route. Demandez au noyau où la réponse irait : ip route get 10.20.5.20 nomme l’interface et, plus utile, l’adresse source qu’elle utiliserait.
Surveillez l’adresse du résolveur elle-même. Un client avec DNS = 10.8.0.53 à côté de AllowedIPs = 10.20.0.0/16 envoie ses requêtes par la carte réseau physique, où elles meurent en silence, car le résolveur n’est dans aucun préfixe que le tunnel revendique. Cette incohérence est la cause unique la plus fréquente dans tout ce domaine, et elle reste invisible tant que vous ne comparez pas le réglage DNS avec les préfixes autorisés ligne par ligne.
Des plages qui se chevauchent provoquent la panne inverse. La réponse est juste, la route existe, et elle pointe vers le mauvais hôte, car 192.168.0.0/24 à la maison est plus spécifique que la route du tunnel vers la même plage. Renumérotez un côté ou poussez une route plus étroite, puis confirmez le pare-feu et le chemin de retour de l’hôte du service ; les notes de strongSwan sur le transfert couvrent le côté sysctl de ce chemin.
Les certificats relèvent d’un contrôle d’identité distinct que les gens imputent au DNS. Si le navigateur signale une incohérence de nom au lieu d’une erreur de résolution, la recherche a déjà fonctionné et c’est le SAN du certificat qu’il faut corriger. Testez HTTPS sur le nom, jamais sur l’IP nue.
Retestez depuis le client, pas depuis la passerelle
Testez dans l’application dont l’utilisateur se plaint, car une recherche en ligne de commande ne prouve pas que le navigateur emprunte le même chemin. Le DNS sécurisé de Chrome et network.trr.mode de Firefox peuvent contourner entièrement le résolveur système, et quand ils le font, un nom privé échoue ou fuit vers un résolveur public. Comparer resolvectl query à un dig @10.8.0.53 files.corp.example lancé à la main vous dit lequel des deux s’est produit.
Déconnectez puis reconnectez avant de déclarer le problème résolu. Les réglages appliqués à la main sur une interface disparaissent avec elle, et un profil qui ne semblait correct qu’à cause d’une modification locale oubliée échouera au prochain démarrage.
Une courte liste pour la machine suivante : le nom se résout via le résolveur du tunnel, le suffixe est délimité plutôt que global, l’adresse du résolveur se situe dans les préfixes autorisés, l’hôte de la réponse répond sur le port du service et le certificat couvre le nom saisi par l’utilisateur.