Pourquoi les requêtes de dnsmasq échappent au VPN après une redirection DNS
Une REDIRECT côté routeur transforme une requête DNS du LAN en une nouvelle socket du résolveur. Les marques posées sur le flux du client ne l’atteignent jamais, alors réglez l’egress amont directement.
Le client du LAN atteint correctement son VPN et, pourtant, ses requêtes DNS apparaissent sur le mauvais lien montant. Ce n’est pas une fuite au sens habituel ; c’est ce qui se produit quand le routeur cesse de transmettre une requête et y répond lui-même. L’interception réécrit la destination vers une socket locale, puis le résolveur ouvre une seconde conversation, sans rapport, avec sa propre adresse source et sa propre décision de routage. Les marques appliquées au flux du client décrivent la première conversation et absolument rien de la seconde.
La marque ne voyage pas avec la requête
Les marques de paquet vivent sur une entrée conntrack et sur le paquet en vol. Une règle REDIRECT met fin à ce vol : la charge utile est remise à une socket locale, et l’entrée d’origine a fait son travail. Ce qui quitte le routeur ensuite est une socket neuve créée par le processus du résolveur, dont la source est l’adresse du routeur lui-même.
C’est pourquoi une route de politique indexée sur l’adresse du client du LAN ne correspond jamais à la requête amont. La nouvelle socket appartient à dnsmasq et non au client, et le noyau évalue la route pour le trafic du routeur lui-même. Les règles de source, les règles d’interface et les règles de marque voient toutes un tuple différent. Supposer que la marque se propage est l’erreur la plus courante dans cette configuration, et elle est invisible dans une capture côté client.
Les deux conversations partagent bien un nom et un moment, et c’est ce qui les fait ressembler à un seul flux quand on parcourt une capture.
Où le transfert devient résolution locale
Commencez par déterminer si le port 53 est redirigé, traduit vers un autre hôte ou laissé intact, car les trois cas se comportent différemment. Une redirection vers un port local met fin au transfert, tandis qu’une traduction vers une autre machine maintient le paquet en mouvement et garde le tuple du client significatif.
Regardez les deux protocoles. Un résolveur joignable en UDP et en TCP sera testé sur les deux, et un jeu de règles qui ne couvre qu’UDP laisse un trou discret pour les réponses volumineuses. Les règles générées par le gestionnaire de configuration du routeur comptent aussi, et modifier un fichier généré perd généralement contre le prochain rechargement.
sudo nft list ruleset | grep -n -B2 -A4 'dport 53'
sudo iptables -t nat -L -n -v | grep -E ':53|dns'
sudo ss -lunp | grep ':53'
Ces sorties répondent à trois questions dans l’ordre : ce qui réécrit la requête, ce qui la reçoit, et quel processus possède la socket à l’écoute. Une fois le propriétaire connu, la politique amont a où vivre.
Donnez au résolveur sa propre politique de sortie
Un amont propre à un domaine est l’outil le plus propre quand seuls certains noms ont besoin du tunnel. dnsmasq accepte une ligne server limitée à un domaine, avec une interface ou une adresse source facultative qui dirige la requête hors d’un périphérique choisi. C’est ce guidage qui fait que la seconde conversation suit le VPN.
server=/corp.example/10.30.0.53@tun_work
log-queries
Le domaine, l’adresse et l’interface ci-dessus sont des espaces réservés pour vos propres valeurs. Le choix du domaine et le contrôle de sortie restent des décisions distinctes : la route doit exister, l’adresse source doit être autorisée par le résolveur amont, et le pare-feu doit autoriser la réponse. Le guidage par interface seul n’est pas fail-closed, car un tunnel disparu peut laisser le résolveur retomber sur un autre chemin. Gardez tout repli public loin d’un espace de noms qui doit rester privé.
Placez la ligne chez le propriétaire de configuration que le routeur prend en charge plutôt que dans un fichier généré, sinon le prochain rechargement efface la correction.
Ce qu’un cache partagé ne peut pas préserver
Un seul redirecteur avec un seul cache sert chaque client du LAN, et cela effondre une distinction dont certains réseaux ont besoin. Si deux clients doivent résoudre le même nom différemment, la socket partagée n’a aucun moyen de retrouver quel client a demandé. La politique par client doit vivre dans des instances de résolveur séparées ou dans une fonction de transfert qui conserve l’identité.
Une réponse en cache n’est pas non plus une preuve au sujet du nouveau chemin. La réponse peut venir de la mémoire pendant que la route amont reste cassée.
Les règles de port 53 ne disent rien des applications qui parlent DNS sur HTTPS ou sur TLS. Ces requêtes n’atteignent jamais la redirection, donc une politique construite uniquement sur le port 53 décrit un sous-ensemble du trafic et devrait être documentée comme un sous-ensemble.
Vérifiez la seconde conversation, pas la première
Testez avec un nom que vous contrôlez et observez les deux côtés. Une capture côté client prouve que la requête a quitté le LAN ; seul le côté routeur prouve où elle est allée ensuite.
sudo tcpdump -ni tun_work udp port 53
ip route get 10.30.0.53
dig +short corp.example @10.30.0.53
Videz le cache avant chaque tentative, car une réponse chaude cache un amont cassé. Répétez en TCP, puis répétez avec le tunnel coupé pour voir ce que fait le résolveur quand son chemin préféré a disparu. Ce dernier comportement décide si la conception est fail-closed ou simplement chanceuse.