DNS local pour utilisateurs VPN : stoppez les fuites DNS et les échecs de routage fractionné

Cet article vous a aidé ?

Vous pouvez construire un tunnel VPN parfait et pourtant livrer une fuite de confidentialité, un cauchemar de fiabilité et un incendie au support — rien qu’en mal configurant le DNS. Le symptôme habituel est « le VPN est connecté mais les applications internes ne fonctionnent pas », suivi de « et pourquoi mon portable parle à un résolveur aléatoire dans un hôtel ? »

Le DNS, ce sont de petits paquets et de grandes conséquences. Si votre tunnel fractionné n’envoie que le trafic « important » via le VPN mais que vos requêtes DNS continuent de s’échapper sur le réseau local, vous verrez des fuites, une résolution de noms internes cassée et des pics de latence étranges qui ressemblent à « le VPN est lent » alors que le tunnel va bien.

Le modèle mental : ce que « DNS local pour utilisateurs VPN » signifie réellement

« DNS local pour utilisateurs VPN » est une expression utilisée pour trois choses différentes. Si vous ne précisez pas laquelle vous implémentez, vous livrerez un système qui marche dans votre labo et qui échoue dans le hall d’un hôtel.

Signification n°1 : « Utiliser un résolveur interne accessible via le VPN »

C’est le modèle classique en entreprise : le client VPN doit envoyer les requêtes DNS à un résolveur à l’intérieur de votre réseau (ou dans votre VPC cloud), pas au résolveur que le Wi‑Fi local donne à l’utilisateur. C’est la base du split‑horizon DNS (les noms internes résolvent en IP internes), des zones internes exclusives et d’un journal cohérent.

Signification n°2 : « Faire tourner un résolveur sur le client et transférer intelligemment »

Vous exécutez un stub resolver local sur l’appareil (ou vous comptez sur le stub de l’OS) et vous configurez un transfert conditionnel : les domaines internes vont vers les DNS internes via le VPN ; tout le reste va vers un résolveur public local (ou aussi via le VPN, selon la politique). C’est souvent la manière la plus propre de faire fonctionner un split tunnel sans envoyer tout le DNS Internet via le réseau corporate.

Signification n°3 : « Fournir un service DNS proche de l’utilisateur pour réduire la latence »

C’est motivé par la performance : déployer des résolveurs régionalisés, accessibles via le VPN, pour que les travailleurs distants n’aient pas à faire un détour jusqu’au siège pour chaque résolution. Ça réduit aussi le rayon d’impact quand un nœud DNS tombe, car le « plus proche » change.

Toutes les trois sont valables. Les mélanger sans intention, c’est se retrouver avec des fuites partielles, un ordre de résolveurs imprévisible et des caches qui se battent entre eux.

Vérité opérationnelle : le DNS « fonctionne » jusqu’à ce que ça ne fonctionne plus, et alors il casse comme une bulle de savon — tranquillement, aléatoirement et toujours pendant une démo en direct.

Faits et historique qui expliquent le bazar d’aujourd’hui

  • Le DNS est antérieur aux VPN modernes. La spécification DNS (RFC 1034/1035) date de 1987, conçue pour un réseau plus indulgent que les Wi‑Fi hostiles et les portails captifs d’aujourd’hui.
  • Le « split horizon » est plus vieux que le cloud. Les entreprises faisaient déjà des vues internes vs externes bien avant que Kubernetes ne donne l’impression que tout est nouveau.
  • UDP était un atout, puis une faiblesse. Le DNS sur UDP était parfait pour de petites requêtes, mais il est aussi facile à usurper, bloquer ou mal gérer sur des réseaux instables.
  • EDNS0 a changé la taille des paquets. Les réponses DNS plus grandes (pensez DNSSEC, lots d’enregistrements) ont accentué les problèmes de fragmentation — exactement le genre de chose qui devient étrange avec les MTU des VPN.
  • DNSSEC a amélioré l’intégrité, pas la confidentialité. Il évite la falsification mais ne prévient pas les fuites DNS ni n’empêche des observateurs de voir ce que vous interrogez.
  • DoH/DoT a changé qui « possède » la résolution de noms. Les applications peuvent contourner les paramètres de résolveur de l’OS, ce qui fait que le « définir un serveur DNS » poussé par le VPN peut être ignoré par le navigateur.
  • Windows NRPT existe pour une raison. Microsoft a ajouté le Name Resolution Policy Table pour contrôler quels espaces de noms utilisent quels résolveurs — parce que « juste définir un serveur DNS » ne suffisait pas.
  • systemd-resolved a rendu le split DNS courant sur Linux. C’est puissant, mais ça a aussi introduit de nouveaux modes de défaillance quand les admins supposent que /etc/resolv.conf dit toute l’histoire.
  • Le DNS d’entreprise est souvent la dernière ligne de garde. Beaucoup d’équipes modernisent l’auth, déploient des proxies sophistiqués et continuent pourtant de gérer le DNS comme en 2009 parce que « ça a toujours marché ».

Objectifs de conception : choisissez ce que vous optimisez

Avant de toucher aux configs, décidez ce que « correct » signifie pour votre organisation. Le DNS est de la politique déguisée en plomberie.

Objectif A : Stopper les fuites DNS (confidentialité + conformité)

Les fuites se produisent quand les requêtes DNS pour des domaines internes (ou n’importe quels domaines, selon la politique) vont vers un résolveur hors de votre contrôle. Corriger ça peut nécessiter de forcer le DNS sur l’interface VPN, bloquer le port 53 hors tunnel et gérer DoH.

Objectif B : Faire fonctionner réellement le split tunnel (fiabilité)

Split tunnel signifie généralement : applications internes via VPN, internet direct. La partie DNS doit correspondre à cette logique. Si les zones internes sont résolues via des résolveurs publics, les applis internes échouent. Si les zones publiques sont résolues via des résolveurs internes en travers d’un tunnel congestionné, l’internet « paraît lent ».

Objectif C : Garder latence et charge raisonnables (performance)

Centrer tout le DNS derrière un seul point VPN est simple, et c’est aussi la meilleure façon d’apprendre aux utilisateurs que « le VPN est lent ». Des résolveurs régionaux, du cache et une gestion correcte des TTL rendent le DNS assez rapide pour que personne n’y pense — ce qui est le plus grand compliment.

Objectif D : Rendre l’exploitation ennuyeuse (facilité de support)

Le débogage DNS sur postes distants est déjà pénible. Ne l’aggravez pas avec de la sophistication que vous ne pouvez pas observer. Préférez des designs où vous pouvez répondre : quel résolveur le client a‑t‑il utilisé, par quelle interface c’est passé, et qu’a‑t‑il reçu en retour ?

Idée paraphrasée de John Allspaw : la fiabilité se construit sur la capacité à répondre à l’imprévu, pas sur le fait de prétendre que l’imprévu n’arrivera pas.

Architectures de référence qui fonctionnent en production

1) DNS en tunnel complet : forcer tout le DNS via le VPN vers des résolveurs internes

Quand l’utiliser : conformité stricte, environnements réglementés, ou quand vous ne pouvez tolérer aucun DNS hors tunnel.

Comment ça marche : le VPN pousse des serveurs DNS internes ; le client route les requêtes DNS via le tunnel ; le pare‑feu bloque les sorties DNS sur l’interface locale ; optionnellement on intercepte/redirige vers le résolveur interne.

Compromis : plus de charge sur votre VPN et DNS ; latence plus élevée pour les résolutions publiques sauf si votre résolveur interne gère bien ses upstreams ; il faut traiter DoH séparément.

2) Split DNS avec transfert conditionnel (par défaut recommandé)

Quand l’utiliser : la plupart des organisations avec split tunnel et namespaces internes.

Comment ça marche : les domaines internes (ex. corp.example, svc.cluster.local, zones privées cloud) vont vers des résolveurs internes via le VPN ; tout le reste utilise le résolveur du réseau local ou un résolveur public choisi.

Compromis : complexité de configuration plus élevée selon les OS ; nécessite un contrôle précis de l’ordre des résolveurs et des règles de routage de domaines ; il faut quand même considérer les chemins de fuite.

3) Résolveur local côté client + upstream chiffré (DoT) via le VPN

Quand l’utiliser : vous voulez un comportement cohérent et moins de bizarreries OS, et vous pouvez gérer un agent.

Comment ça marche : exécuter un stub cache local (comme unbound) sur le client ; transférer les zones internes vers le DNS interne ; transférer le public vers des endpoints DoT soit via le VPN soit en direct. Cela peut calmer les courses entre résolveurs et réduire les requêtes répétées sur des liens instables.

Compromis : gestion du cycle de vie d’un agent ; un composant supplémentaire ; le débogage passe des outils OS aux logs de votre stub.

4) Résolveurs anycast accessibles via VPN (pour l’échelle)

Quand l’utiliser : grande force de travail distante répartie, besoin de faible latence, et vous gérez déjà bien le routage global.

Comment ça marche : annoncer la même IP de résolveur dans plusieurs régions accessible via le VPN ; BGP ou un overlay amène le client à l’instance la plus proche. Fonctionne mieux avec des health checks et bascule rapide.

Compromis : maturité opérationnelle requise ; anycast + pare‑feux stateful peut être délicat ; déboguer « quel nœud a répondu » nécessite une bonne observabilité.

Opinion : si vous n’êtes pas contraint à un DNS full‑tunnel, commencez par le split DNS et le transfert conditionnel. C’est le meilleur compromis expérience utilisateur / contrôle — si vous l’implémentez honnêtement et testez sur de vrais OS clients.

Comportement des clients : Windows, macOS, Linux, mobile (et leurs mauvaises habitudes)

Windows : plusieurs résolveurs, listes de suffixes et tables de politique

Windows peut maintenir des serveurs DNS différents par interface et a des règles pour déterminer quelle interface prévaut. Il a aussi des listes de suffixes qui peuvent générer des requêtes surprenantes. Pour le split DNS, NRPT peut diriger des namespaces spécifiques vers des serveurs DNS spécifiques. Si vous gérez un VPN corporate à grande échelle, apprenez NRPT. C’est la différence entre « fonctionne pour l’IT » et « fonctionne pour tout le monde ».

macOS : l’ordre des résolveurs est réel, et parfois c’est capricieux

macOS utilise une configuration de résolveur dynamique. Vous pouvez avoir plusieurs résolveurs actifs avec routage par domaine. L’interface utilisateur et le client VPN peuvent afficher une chose tandis que le résolveur sous‑jacent en fait une autre. Inspectez toujours l’état réel du résolveur, pas seulement le panneau réseau.

Linux : /etc/resolv.conf est un menteur sur les systèmes modernes

Sur beaucoup de distributions, /etc/resolv.conf pointe vers un stub local (par ex. 127.0.0.53) géré par systemd-resolved, NetworkManager ou autre. Le débogage nécessite d’interroger le gestionnaire de résolveur, pas seulement de lire le fichier.

Mobile : portails captifs, fonctionnalités « utiles » de confidentialité et DNS par application

Les téléphones rôdent, changent de réseau et essaient vigoureusement de maintenir la connectivité. Certaines applis utilisent leurs propres méthodes DNS, et les plateformes modernes peuvent préférer le DNS chiffré si configuré. Votre stratégie « pousser le DNS via le VPN » peut ne pas couvrir le réglage DoH du navigateur ou un agent de sécurité qui fait sa propre résolution.

Blague #1 : Le DNS, c’est comme les potins au bureau — si vous ne contrôlez pas où ça va, ça finira absolument dans le mauvais couloir.

D’où viennent les fuites DNS et les échecs de routage fractionné

Chemin de fuite n°1 : serveur DNS configuré, mais route manquante

Le VPN pousse une IP de serveur DNS interne, mais le client ne route pas cette IP via le tunnel (fréquent en split tunnel). Résultat : le serveur DNS est « configuré » mais injoignable. L’OS bascule sur un autre résolveur — souvent le résolveur local — causant des fuites et des pannes.

Chemin de fuite n°2 : ordre des résolveurs et basculement

Les clients peuvent interroger plusieurs résolveurs. Si le résolveur interne tarde (latence, problème de MTU, perte de paquets), l’OS utilise le résolveur suivant. Félicitations, vous venez de construire une politique de confidentialité probabiliste.

Chemin de fuite n°3 : DNS au niveau application (DoH/DoT)

Si des navigateurs ou agents utilisent DoH directement vers un fournisseur public, vos paramètres DNS VPN peuvent être contournés. Parfois c’est voulu. Souvent non. Décidez de votre politique, puis appliquez‑la via la gestion des endpoints et/ou des contrôles réseau.

Échec de routage fractionné : les noms internes résolvent en IP publiques (ou NXDOMAIN)

Si les zones internes ne sont pas routées vers des résolveurs internes, les utilisateurs obtiennent soit NXDOMAIN, soit, pire, résolvent des noms internes vers des enregistrements publics du même nom. Le split horizon DNS existe parce que la réutilisation de noms arrive. Ignorer ce fait, c’est ouvrir des tickets que vous ne méritez pas.

Échec de routage fractionné : les noms internes se résolvent, mais le trafic va direct

Même si le DNS est correct, l’enregistrement A/AAAA résultant doit pointer vers une plage IP routée via le VPN. Si votre split tunnel ne route que certains préfixes, et que les services internes se trouvent ailleurs, la résolution réussit et la connectivité échoue quand même. Les utilisateurs appelleront ça « DNS » de toute façon. Parfois ils ont raison, mais pas pour la raison qu’ils pensent.

Tâches pratiques : commandes, sorties et ce que vous en décidez

Ce sont les contrôles que j’exécute à peu près dans cet ordre quand quelqu’un dit « le DNS du VPN est cassé ». Chaque tâche inclut la commande, à quoi ressemble une sortie typique, ce que cela signifie et la décision suivante.

Task 1: Identify which DNS server the system is actually using (Linux with systemd-resolved)

cr0x@server:~$ resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
 resolv.conf mode: stub
Current DNS Server: 10.20.0.53
       DNS Servers: 10.20.0.53 1.1.1.1
DNS Domain: corp.example

Link 3 (wg0)
    Current Scopes: DNS
         Protocols: +DefaultRoute
Current DNS Server: 10.20.0.53
       DNS Servers: 10.20.0.53
        DNS Domain: ~corp.example

Ce que cela signifie : le DNS est scindé : wg0 gère ~corp.example et utilise 10.20.0.53. Il y a aussi un fallback global (1.1.1.1).

Décision : si les requêtes internes fuient encore, vérifiez que les requêtes internes sont routées vers wg0 et que ~corp.example est correctement défini. Si c’est manquant, corrigez le routage par domaine.

Task 2: Check /etc/resolv.conf without being fooled by it

cr0x@server:~$ ls -l /etc/resolv.conf
lrwxrwxrwx 1 root root 39 Jan  2 10:11 /etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

Ce que cela signifie : vous utilisez un stub resolver. Lire le fichier n’affichera pas les vrais upstreams.

Décision : utilisez resolvectl (ou les outils NetworkManager) pour la vérité. Si des applis contournent le stub, vous avez un problème différent.

Task 3: Confirm that internal DNS server is reachable via the VPN route

cr0x@server:~$ ip route get 10.20.0.53
10.20.0.53 dev wg0 src 10.20.0.10 uid 1000
    cache

Ce que cela signifie : la route vers le résolveur interne passe par wg0. Bien.

Décision : si ça route via wlan0 ou une autre interface locale, corrigez les routes du split tunnel (AllowedIPs, routes poussées ou policy routing).

Task 4: Test internal resolution explicitly against the internal resolver

cr0x@server:~$ dig @10.20.0.53 git.corp.example +time=2 +tries=1

; <<>> DiG 9.18.24 <<>> @10.20.0.53 git.corp.example +time=2 +tries=1
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40211
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; ANSWER SECTION:
git.corp.example. 60 IN A 10.30.4.21

;; Query time: 21 msec
;; SERVER: 10.20.0.53#53(10.20.0.53)

Ce que cela signifie : le serveur DNS répond rapidement et retourne une IP interne.

Décision : si cela fonctionne mais que les applis échouent, le client n’utilise peut‑être pas ce résolveur (problème d’ordre des résolveurs) ou le routage vers 10.30.4.21 est incorrect.

Task 5: Test the same name using the system default path (catch leaks and misrouting)

cr0x@server:~$ dig git.corp.example +time=2 +tries=1

; <<>> DiG 9.18.24 <<>> git.corp.example +time=2 +tries=1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 5851
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

Ce que cela signifie : le chemin résolveur par défaut du système ne connaît pas la zone interne (probablement utilisation d’un DNS externe).

Décision : corrigez le routage split DNS pour que corp.example aille vers le résolveur interne. Sur Linux c’est le routage par lien ; sur Windows c’est souvent NRPT ; sur macOS ce sont des entrées résolveur par domaine.

Task 6: Detect whether DNS packets actually traverse the VPN interface

cr0x@server:~$ sudo tcpdump -ni wg0 port 53 -c 5
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:22:41.111112 IP 10.20.0.10.53321 > 10.20.0.53.53: 40211+ A? git.corp.example. (33)
10:22:41.132908 IP 10.20.0.53.53 > 10.20.0.10.53321: 40211 1/0/1 A 10.30.4.21 (49)

Ce que cela signifie : le DNS passe par le tunnel, et les réponses reviennent. C’est la ligne de base propre.

Décision : si vous ne voyez rien sur wg0 mais que vous voyez des requêtes sur wlan0, c’est une fuite. Corrigez le routage ou la sélection du résolveur.

Task 7: Catch “fallback resolver” behavior by watching multiple interfaces

cr0x@server:~$ sudo tcpdump -ni wlan0 port 53 -c 3
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
10:23:02.002201 IP 192.168.1.25.58732 > 192.168.1.1.53: 5851+ A? git.corp.example. (33)
10:23:02.004991 IP 192.168.1.1.53 > 192.168.1.25.58732: 5851 NXDomain 0/1/0 (102)

Ce que cela signifie : votre appareil fuit des requêtes internes vers le résolveur du réseau local.

Décision : stoppez le basculement en implémentant correctement le split DNS et/ou en bloquant le DNS hors tunnel. Si la politique le permet, appliquez « les zones internes doivent passer par le VPN » au niveau de l’OS.

Task 8: Check for MTU/fragmentation problems that look like “DNS timeouts”

cr0x@server:~$ ping -M do -s 1472 10.20.0.53 -c 2
PING 10.20.0.53 (10.20.0.53) 1472(1500) bytes of data.
ping: local error: message too long, mtu=1420
ping: local error: message too long, mtu=1420

--- 10.20.0.53 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1026ms

Ce que cela signifie : le MTU du chemin est plus petit (1420). Les grosses réponses UDP peuvent fragmenter ou être perdues, entraînant des échecs DNS intermittents.

Décision : ajustez le MTU du VPN, activez le fallback TCP pour la fiabilité, ou assurez que les réponses DNS restent petites dans la mesure du possible. Si vous utilisez DNSSEC‑lourd, soyez particulièrement vigilant.

Task 9: Verify the client is not using DoH in a way that bypasses your plan (network-side view)

cr0x@server:~$ sudo tcpdump -ni wg0 'tcp port 443 and (host 1.1.1.1 or host 8.8.8.8)' -c 3
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
10:24:10.500000 IP 10.20.0.10.41220 > 1.1.1.1.443: Flags [S], seq 123456, win 64240, options [mss 1360,sackOK,TS val 1 ecr 0], length 0

Ce que cela signifie : vous voyez du trafic HTTPS vers un fournisseur de résolveur public. Cela peut être du trafic web normal — ou du DoH.

Décision : si votre politique interdit le contournement via DoH, appliquez‑la via la gestion des endpoints et des contrôles d’egress ; sinon documentez le comportement et son impact sur les zones internes.

Task 10: Confirm which DNS server answered a query (trace in dig)

cr0x@server:~$ dig git.corp.example +trace +time=2 +tries=1
; <<>> DiG 9.18.24 <<>> git.corp.example +trace +time=2 +tries=1
;; Received 525 bytes from 192.168.1.1#53(192.168.1.1) in 3 ms

Ce que cela signifie : la trace a démarré auprès de votre résolveur local (192.168.1.1). C’est déjà une fuite pour un nom interne.

Décision : corrigez la sélection du résolveur et le routage par domaine. Le trace est utile pour prouver « qui a répondu » sans discuter autour de captures d’écran.

Task 11: Validate that internal service IPs are routed through VPN (post-DNS)

cr0x@server:~$ ip route get 10.30.4.21
10.30.4.21 dev wg0 src 10.20.0.10 uid 1000
    cache

Ce que cela signifie : le trafic vers le service interne ira via le VPN. Le DNS n’est peut‑être pas votre vrai problème.

Décision : si ça route hors tunnel, corrigez les préfixes du split tunnel. Le DNS est correct ; le routage ne l’est pas.

Task 12: Check whether the internal resolver can reach upstreams (resolver-side)

cr0x@server:~$ dig @127.0.0.1 example.com +time=2 +tries=1

; <<>> DiG 9.18.24 <<>> @127.0.0.1 example.com +time=2 +tries=1
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 30001
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; Query time: 2000 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)

Ce que cela signifie : le résolveur local (sur un serveur DNS) échoue à résoudre des noms publics. Les upstreams sont bloqués, cassés ou en timeout.

Décision : corrigez la sortie du résolveur, la configuration des upstreams ou les règles de pare‑feu. Sinon, les utilisateurs VPN accuseront le « DNS du VPN » alors que le vrai souci est le chemin upstream du résolveur.

Task 13: Check firewall counters for blocked DNS (server-side sanity)

cr0x@server:~$ sudo nft list ruleset | sed -n '1,120p'
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iifname "wg0" udp dport 53 accept
    iifname "wg0" tcp dport 53 accept
    counter packets 1203 bytes 90211 drop
  }
}

Ce que cela signifie : le DNS depuis l’interface VPN est autorisé ; tout le reste est droppé par défaut.

Décision : si les clients VPN ne peuvent toujours pas résoudre, ce n’est probablement pas parce que le serveur DNS les bloque (du moins pas dans la chaîne input). Passez à la santé du service, au routage ou aux vérifications MTU.

Task 14: Check resolver performance and cache hit rate (Unbound example)

cr0x@server:~$ sudo unbound-control stats_noreset | egrep 'total.num.queries|total.num.cachehits|total.num.cachemiss|avg'
total.num.queries=145233
total.num.cachehits=109887
total.num.cachemiss=35346
total.requestlist.avg=8.132

Ce que cela signifie : le ratio de hit du cache est correct ; la moyenne de la file de requêtes suggère une certaine concurrence mais pas nécessairement une surcharge.

Décision : si les hits du cache sont faibles et la latence élevée, ajoutez plus de cache proche des utilisateurs, ajustez le prefetching, ou augmentez la capacité des résolveurs. Si le taux de misses grimpe lors d’incidents, vous subissez peut‑être des instabilités upstream.

Blague #2 : Le split DNS, c’est comme la politique de « travail à domicile » — tout le monde est d’accord en principe, puis les cas limites s’installent gratuitement.

Mode opératoire de diagnostic rapide

Voici l’ordre d’opérations « arrêter de deviner ». Exécutez‑le comme une checklist, pas comme un débat.

Premier : confirmez quel résolveur le client utilise

  • Sur Linux : resolvectl status (ne vous fiez pas seulement à /etc/resolv.conf).
  • Sur macOS : inspectez la configuration résolveur (vous voulez du routage par domaine, pas seulement des « serveurs DNS » dans l’UI).
  • Sur Windows : vérifiez le DNS par interface plus les règles NRPT si vous les utilisez.

Décision : si le client n’est pas configuré pour utiliser le DNS interne pour les domaines internes, arrêtez‑vous. Corrigez la configuration avant de chasser des « problèmes réseau ».

Second : confirmez la route vers le serveur DNS interne passe par le VPN

  • Exécutez ip route get <dns_ip> (Linux) ou un outil équivalent.
  • Si ça route hors tunnel, vous avez une défaillance de politique de split‑tunnel.

Décision : corrigez les routes (AllowedIPs, routes poussées, policy routing) avant de toucher aux serveurs DNS.

Troisième : testez la résolution interne directement contre le DNS interne

  • dig @internal-dns internalhost.corp.example
  • Mesurez latence, codes de réponse et IP retournées.

Décision : si les requêtes directes échouent, le résolveur est malsain ou inaccessible. Si les requêtes directes fonctionnent, l’ordre des résolveurs du client ou le routage par domaine est incorrect.

Quatrième : sniff pour confirmer où passent les paquets DNS

  • tcpdump sur l’interface VPN et sur l’interface locale pour le port 53.
  • Cherchez des zones internes qui fuient vers des résolveurs locaux.

Décision : si vous voyez des fuites, appliquez le split DNS ou bloquez le DNS hors tunnel. Si vous voyez des timeouts, investigatez MTU et perte de paquets.

Cinquième : gérez la réalité du « contournement DoH »

  • Décidez si vous autorisez le DNS chiffré au niveau application hors de votre résolveur.
  • Si non, imposez‑le via la politique endpoint et les contrôles d’egress ; sinon documentez le comportement et son impact sur les zones internes.

Erreurs courantes (symptômes → cause racine → correction)

1) « VPN connecté, sites internes non résolus »

Symptôme : les noms internes retournent NXDOMAIN ou se résolvent en IP publiques.

Cause racine : le client utilise encore le DNS du réseau local ; pas de routage conditionnel pour le suffixe interne ; NRPT/entrées résolveur manquantes.

Correction : implémentez le split DNS : routez corp.example vers le DNS interne via le VPN ; vérifiez avec dig et capture de paquets que les requêtes passent par le tunnel.

2) « Ça marche en Ethernet, échoue en Wi‑Fi/hôtel »

Symptôme : timeouts intermittents, surtout pour les réponses plus grandes ; parfois seules certaines entrées échouent.

Cause racine : mismatch MTU causant des pertes de fragments ; tronquage des réponses UDP mal géré.

Correction : ajustez le MTU du VPN ; assurez le fallback TCP pour les résolveurs ; envisager de limiter la taille EDNS si nécessaire.

3) « Seuls certains utilisateurs fuient le DNS »

Symptôme : fuites incohérentes ; des utilisateurs avec la même config VPN se comportent différemment.

Cause racine : différences d’OS (systemd-resolved vs resolvconf legacy), multiples interfaces actives, comportement de fallback des résolveurs.

Correction : standardisez les outils de gestion DNS client ; testez sur chaque build OS que vous supportez ; configurez explicitement le routage par domaine et les priorités de résolveurs.

4) « La résolution interne fonctionne, mais les applis ne peuvent pas se connecter »

Symptôme : le DNS retourne les IP internes correctes ; les connexions TCP échouent.

Cause racine : les routes du split tunnel n’incluent pas les plages IP des services ; groupes de sécurité/pare‑feu bloquent ; routage asymétrique.

Correction : corrigez l’annonce des routes et la politique de sécurité ; validez avec ip route get et des traceroutes via le tunnel.

5) « Le DNS public est lent quand le VPN est activé »

Symptôme : navigation lente ; beaucoup de « waiting for DNS » dans les outils développeur.

Cause racine : vous avez forcé tout le DNS vers des résolveurs internes dans une seule région ; la latence et la congestion s’accumulent ; les misses de cache amplifient la douleur.

Correction : utilisez le split DNS pour les résolutions publiques ou déployez des résolveurs régionaux accessibles via le VPN ; assurez le cache et la sélection upstream.

6) « Nous avons bloqué le port 53, mais les fuites persistent »

Symptôme : des requêtes pour des domaines internes sont encore visibles à l’extérieur.

Cause racine : contournement via DoH/DoT ; DNS embarqué dans des applis ; résolveurs utilisant des ports non standards.

Correction : gérez explicitement la politique DNS chiffré : configs endpoint, proxy DNS, ou endpoints DoH contrôlés. Ne supposez pas que le port 53 couvre tout.

7) « Tout casse après activation de la validation DNSSEC »

Symptôme : SERVFAIL sur de nombreux domaines ; succès intermittents.

Cause racine : MTU fragmentation sur le chemin upstream, middleboxes défectueux, ou dérive horaire affectant les chaînes de validation.

Correction : validez le MTU, autorisez TCP/53, assurez la synchronisation horaire correcte et procédez par déploiement progressif. DNSSEC n’est pas un interrupteur ; c’est un engagement.

Trois mini-histoires du monde corporate (anonymisées)

Mini‑histoire 1 : Un incident causé par une mauvaise hypothèse

Une société SaaS de taille moyenne a déployé un VPN split‑tunnel pour réduire les coûts de bande passante. Le VPN poussait des serveurs DNS internes, et l’équipe a supposé que cela signifiait « le DNS est pris en charge ». Un test basique est passé : connexion depuis le Wi‑Fi à domicile, résolution du Git interne, déploiement.

Puis est arrivé le lundi. Des utilisateurs dans des espaces de coworking ont signalé des applications internes en échec, mais seulement parfois. Le support a escaladé en « VPN instable ». L’équipe réseau a vérifié l’état du tunnel : vert. Authentification : OK. CPU sur les gateways VPN : correct. Pendant ce temps, quelqu’un a remarqué que des requêtes internes apparaissaient dans les logs d’un fournisseur DNS public — parce qu’un sous‑ensemble de clients basculait en fallback lorsque le résolveur interne avait un timeout.

La mauvaise hypothèse était subtile : « si un serveur DNS est configuré, les requêtes iront là ». En réalité, si la route vers ce résolveur n’est pas garantie via le VPN, les clients essaient, échouent, puis utilisent silencieusement le résolveur suivant. Le split tunnel avait des routes pour des sous‑réseaux d’applications, mais pas pour le sous‑réseau du DNS. Donc l’IP du résolveur était configurée, mais injoignable depuis de nombreux réseaux.

La correction fut ennuyeuse : garantir que les IP des résolveurs soient toujours routées via le tunnel, et appliquer le routage conditionnel pour les domaines internes. Ils ont aussi ajouté des captures de paquets au runbook pour prouver si les requêtes sortaient du tunnel. L’incident s’est terminé non pas par un patch héroïque, mais par un changement de table de routage et une décision politique pour arrêter de compter sur le « fallback ».

Mini‑histoire 2 : Une optimisation qui s’est retournée contre eux

Une grande entreprise voulait « DNS rapide partout », alors ils ont déployé des résolveurs internes régionaux et se sont amusés avec des règles de forwarding. Les résolutions publiques étaient transférées aux résolveurs ISP locaux (faible latence !) tandis que les résolutions internes passaient via le VPN vers des serveurs autoritatifs internes. Sur le papier, c’était propre.

En pratique, cela a créé un problème de cohérence de cache et un cauchemar de dépannage. Certains clients avaient leurs propres couches de cache ; d’autres utilisaient un agent corporate ; d’autres encore utilisaient des stubs OS. Les TTL divergeaient selon la chaîne. Un changement d’enregistrement pour un service interne s’est propagé de manière inégale, et une partie des utilisateurs atteignait encore d’anciennes IP après le déplacement du service.

Puis le vrai retour de bâton : dans certaines régions, les résolveurs ISP appliquaient un filtrage agressif et répondaient parfois bizarrement à des types d’enregistrements peu courants. Cela ne gênait pas la navigation normale mais a cassé quelques produits de sécurité et workflows développeur comptant sur un comportement DNS spécifique. Soudainement la « optimisation DNS » est devenue « les développeurs ne peuvent plus construire » et l’équipe réseau a dû déboguer des bizarreries de résolveurs tiers.

La solution finale fut d’arrêter d’externaliser la moitié publique du comportement DNS à des résolveurs ISP aléatoires. Ils ont conservé des résolveurs internes régionaux, mais ont forwardé le public vers un ensemble upstream contrôlé et cohérent (toujours régional) avec un comportement prévisible et de l’observabilité. La performance est restée bonne. Les pages d’astreinte ont diminué. L’optimisation est restée, mais la variable non maîtrisée a été retirée.

Mini‑histoire 3 : Une pratique ennuyeuse mais correcte qui a sauvé la mise

Une petite fintech faisait tourner deux résolveurs récursifs internes par région, accessibles via le VPN, et traitait le DNS comme n’importe quelle autre couche : monitoring, alertes, gestion des changements et planification de capacité. Rien d’exotique. Juste de la discipline.

Un jour, un fournisseur cloud a eu un incident réseau partiel causant une perte de paquets intermittente entre l’ingress VPN et un nœud résolveur. Les utilisateurs finaux voyaient « certains noms internes échouer ». Ça sentait l’appli, puis le VPN, puis « peut‑être le DNS ». Enquête classique.

La raison pour laquelle ils n’ont pas paniqué : ils avaient des métriques de latence par résolveur et des compteurs d’échecs de requêtes, et ils enregistraient quel résolveur répondait chaque requête (au moins pour les forwarders stub corporate). L’on‑call a vu qu’un résolveur avait des timeouts en hausse tandis que l’autre restait normal. Ils ont retiré le nœud fautif du service et ont vu les taux d’erreur s’effondrer.

Pas de magie. Juste des résolveurs supervisés, de la redondance et de l’observabilité. Le post‑mortem fut court, ce qui est le vrai signe de maturité.

Listes de contrôle / plan pas-à-pas

Étape 1 : Décidez votre politique DNS (mettez‑la par écrit)

  • Les requêtes de domaines internes sont‑elles autorisées à quitter l’appareil hors tunnel ? (Généralement : non.)
  • Les requêtes pour domaines publics peuvent‑elles utiliser le DNS du réseau local ? (Dépend : performance vs conformité.)
  • Autorisez‑vous DoH/DoT directement depuis les clients ? Si oui, pour quelles applis et quels endpoints ?
  • Exigez‑vous la journalisation des requêtes DNS ? Si oui, où et combien de temps ?

Étape 2 : Définissez les namespaces et frontières de routage

  • Listez les zones DNS internes : corp.example, internal.example, zones privées cloud, clusters Kubernetes.
  • Listez les IPs des résolveurs et assurez‑vous qu’elles sont joignables via les routes VPN.
  • Listez les CIDR des services internes qui doivent être routés via le VPN (pas seulement le sous‑réseau DNS).

Étape 3 : Implémentez explicitement le split DNS

  • Linux : configurez des domaines par lien (ex. ~corp.example) et des serveurs DNS sur le lien VPN.
  • Windows : utilisez NRPT pour les namespaces internes si vous avez une flotte gérée.
  • macOS : assurez‑vous qu’il existe des entrées résolveur par domaine pour les zones internes.

Étape 4 : Bouchez les chemins de fuite réels

  • Bloquez UDP/TCP 53 hors tunnel si la politique exige qu’aucun DNS externe ne soit permis.
  • Gérez DoH/DoT avec politique et application ; ne comptez pas sur l’espoir.
  • Empêchez les résolveurs de fallback de capturer les namespaces internes.

Étape 5 : Rendez le DNS résilient et observable

  • Au moins deux résolveurs par région ou par POP VPN.
  • Health checks qui reflètent une résolution réelle, pas seulement « port 53 ouvert ».
  • Logs ou métriques : taux de requêtes, SERVFAIL, NXDOMAIN, distribution de latence, taux de cache hit.

Étape 6 : Testez depuis des réseaux hostiles

  • Wi‑Fi d’hôtel, café, hotspot mobile, portails captifs.
  • Scénarios IPv6 activé/désactivé (certaines fuites passent par des chemins IPv6 oubliés).
  • Clients avec multiples interfaces actives (Wi‑Fi + Ethernet + adaptateurs virtuels).

Étape 7 : Publiez un runbook qui reflète la réalité

  • Incluez les commandes de la section « Tâches pratiques ».
  • Incluez une définition de « fuite DNS » pour votre org (zones internes uniquement ou tous domaines).
  • Incluez les limites d’escalade : équipe endpoint vs équipe réseau vs équipe DNS.

FAQ

1) Qu’est‑ce qu’on considère exactement comme une fuite DNS ?

Une fuite DNS est toute requête DNS envoyée à un résolveur hors de votre périmètre de confiance prévu. Pour beaucoup d’organisations, les fuites concernent spécifiquement les namespaces internes (comme corp.example) envoyés à des résolveurs publics ou locaux. Dans des environnements plus stricts, tout DNS hors tunnel est une fuite.

2) Pourquoi le split tunneling complique‑t‑il le DNS ?

Parce que le DNS doit refléter l’intention du trafic. Si le VPN ne route que certains sous‑réseaux, mais que le DNS est configuré pour utiliser un résolveur interne, ce résolveur doit être joignable via le tunnel. Sinon, les clients basculent vers d’autres résolveurs, souvent hors VPN.

3) Si je pousse des serveurs DNS via le VPN, est‑ce suffisant ?

Non. Vous devez garantir que la route vers ces serveurs DNS passe par le VPN, et vous devez contrôler les règles de sélection de résolveur pour que les namespaces internes ne soient pas traités par des fallback. Configurer n’est pas appliquer.

4) Faut‑il exécuter nos propres résolveurs récursifs ou forwarder vers des DNS publics ?

Si vous tenez à un comportement cohérent, à l’observabilité et aux zones internes, exécutez vos propres résolveurs récursifs (ou un résolveur managé que vous contrôlez) et forwardez upstream de manière prédictible. Forwarder vers des résolveurs locaux aléatoires est un pari de fiabilité déguisé en économies.

5) Qu’en est‑il du DNS chiffré (DoH/DoT) ?

DoH/DoT protège la confidentialité du DNS sur le fil, mais peut contourner le routage DNS de votre VPN. Décidez d’une politique : autorisez‑le avec garde‑fous, ou bloquez/redirigez via des contrôles endpoint et réseau. Faire semblant que ça n’existe pas est la façon dont les fuites survivent au « blocage DNS ».

6) Comment gérer le DNS interne quand les utilisateurs sont sur des réseaux IPv6 ?

Assurez‑vous que votre VPN et votre plan DNS prennent en charge l’IPv6 explicitement : joignabilité des résolveurs, routes et réponses d’enregistrements (AAAA). Si vous ne traitez que l’IPv4, certains clients résoudront et se connecteront en IPv6 hors tunnel, et vous courrez après des fantômes.

7) Pourquoi certaines résolutions internes fonctionnent et d’autres timeout ?

Causes courantes : problèmes MTU faisant perdre de grosses réponses, perte de paquets sur le chemin VPN, résolveurs surchargés, ou comportement de fallback des résolveurs. Validez avec tcpdump, tests MTU et dig directs vers le résolveur interne.

8) Peut‑on « juste bloquer le port 53 » pour arrêter les fuites ?

Bloquer le port 53 aide, mais ce n’est pas suffisant. Les applis peuvent utiliser DoH sur le port 443, et certains environnements utilisent le DNS sur des ports non standards. De plus, bloquer 53 sans fournir un résolveur fonctionnel via le tunnel transforme la « prévention de fuite » en « panne Internet ».

9) Quelle est l’approche la plus simple et sûre pour une flotte hétérogène d’OS ?

Utilisez le split DNS avec transfert conditionnel, plus des routes garanties aux résolveurs internes. Standardisez la configuration client via MDM/GPO quand c’est possible. Ajoutez du monitoring sur les résolveurs. Puis testez depuis des réseaux hostiles.

10) Comment prouver qu’on a corrigé la fuite ?

Capturez les paquets sur le client : vérifiez que les requêtes de zones internes apparaissent sur l’interface VPN et n’apparaissent pas sur l’interface locale. Journalisez aussi les requêtes sur les résolveurs internes et corrélez. La preuve bat les captures d’écran.

Prochaines étapes pratiques

  1. Choisissez une politique. Décidez ce que signifie « fuite » pour vous et si le DNS public doit passer par le VPN.
  2. Rendez la joignabilité des résolveurs non négociable. Assurez‑vous que les IP des serveurs DNS routent via le VPN même en split tunnel.
  3. Implémentez le split DNS délibérément. Routage conditionnel pour les namespaces internes, pas seulement « définir un serveur DNS ».
  4. Observez‑le. Ajoutez des health checks des résolveurs, métriques de latence et journalisation suffisante pour savoir « quel résolveur a répondu ».
  5. Testez dans le monde réel. Hôtels, portails captifs, réseaux IPv6 et appareils avec plusieurs interfaces — parce que vos utilisateurs vivent là.

Si vous faites ces cinq choses, le DNS cesse d’être un mystère hebdomadaire et redevient ce qu’il aurait dû être : une infrastructure ennuyeuse qui fait tranquillement son travail.

← Précédent
La fluidité n’est pas les FPS : le temps de trame expliqué en 2 minutes
Suivant →
ZFS sync : le réglage qui peut vous rendre rapide… et dangereux

Laisser un commentaire