Routage par politiques sous OpenWrt : la chaîne qui attrape le DNS local
Les requêtes des clients et celles du routeur lui-même entrent par des crochets différents. Une politique visant prerouting transporte chaque requête du LAN et laisse le routeur sur l’uplink du fournisseur.
Les clients du LAN résolvent via le tunnel, et les propres requêtes du routeur, en silence, ne le font pas. Les mises à jour de paquets, la synchronisation de l’heure et le DNS dynamique sortent tous par l’uplink ordinaire, tandis que chaque requête transmise emprunte le VPN, et rien dans l’interface ne suggère que deux chemins différents existent. L’explication n’est pas un bug de la politique mais une question de quel crochet voit le paquet. Deux flux, une adresse de résolveur, et un seul d’entre eux traverse le routeur. Les séparer, c’est toute la correction.
Deux flux, une adresse de résolveur
Le premier flux est celui que les gens imaginent. Un client interroge le résolveur du routeur, le résolveur transmet en amont, et ce paquet transmis traverse le routeur en sortant. Ce paquet est visible pour tout ce qui observe le trafic transmis.
Le second flux n’arrive jamais de nulle part. Le routeur le crée, donc il n’y a ni paquet entrant ni étape de transmission à faire correspondre.
Les deux peuvent viser la même adresse de résolveur, et c’est précisément pourquoi la différence est facile à manquer. Même destination, origine différente, chaîne différente. Une fois l’origine vue, le reste du diagnostic suit.
Les paquets transmis et générés localement entrent différemment
Le trafic transmis est évalué lorsqu’il arrive d’une autre interface. Les paquets de routage par politiques l’exposent comme une chaîne prerouting, et une règle placée là voit chaque paquet qui traverse le routeur. C’est pourquoi les requêtes des clients se comportent exactement comme la politique le décrit, et pourquoi le routeur l’ignore. La règle n’est pas fausse, elle est simplement attachée à un crochet que le routeur n’atteint jamais. Déplacez-la, et la même correspondance commence à fonctionner.
Le trafic généré localement est créé par un processus sur le routeur et entre dans le chemin de sortie. Il est routé par la décision du routeur lui-même et ne rencontre la politique que si celle-ci couvre cette chaîne. Il n’y a aucune interface entrante à faire correspondre ni décision de transmission à observer.
C’est une propriété de l’endroit où naissent les paquets, non d’un paquet particulier. Une règle écrite pour une chaîne n’a tout simplement pas d’avis sur l’autre. Aucun réglage de règle n’y change quoi que ce soit.
Choisissez la chaîne de sortie, puis resserrez la correspondance
La correction consiste à attacher la même intention à la chaîne de sortie aussi, ou à déplacer la règle là-bas lorsque ce sont les requêtes du routeur lui-même qui vous importent. Dans une installation OpenWrt bâtie sur un paquet de routage par politiques, cela signifie choisir output plutôt que prerouting dans le réglage de chaîne de la règle. Gardez les deux règles si les deux populations ont besoin d’être couvertes.
Resserrez ensuite ce que la règle fait correspondre. Les adresses de résolveur de destination sur le port que le résolveur utilise réellement sont une décision bien plus petite qu’envoyer au tunnel tout ce que le routeur origine.
Gardez les deux règles explicites plutôt que d’essayer d’en écrire une qui couvre les deux chaînes. Des règles séparées sont plus faciles à lire, et elles vous permettent de désactiver le chemin du routeur sans perturber le trafic des clients pendant que vous déboguez. Elles rendent aussi les compteurs significatifs un par un.
Gardez le transport propre du tunnel hors de la règle
La connexion extérieure du tunnel est aussi créée par le routeur. Une règle qui envoie tout le trafic généré localement dans le tunnel routrera le tunnel à travers lui-même, et il ne montera pas du tout.
L’accès de gestion est la seconde victime. Les sessions administratives originaires du routeur, ou les réponses qui leur sont faites, peuvent être tirées dans le tunnel par une règle locale trop large et devenir injoignables depuis le LAN.
Excluez le point de terminaison du tunnel de la correspondance, et gardez la règle limitée aux adresses de résolveur. Cela suffit pour l’exigence DNS et c’est assez petit pour raisonner dessus.
Testez les deux populations, pas une
Observez le routeur faire sa propre requête et notez quelle interface l’a portée. Répétez la requête depuis un hôte du LAN et notez le chemin qu’elle a pris. Les compteurs des règles de politique rendent les deux réponses visibles sans deviner.
Traitez les résultats comme deux constats. Un client qui résout via le tunnel ne dit rien du routeur, et un routeur qui résout correctement ne dit rien d’un client sur un autre écouteur. Écrivez-les comme des lignes séparées dans le journal des changements.
Vérifiez aussi le port : une règle qui correspond au port de destination 53 manque un résolveur atteint via DNS over TLS sur 853 ou un point de terminaison HTTPS. Faites correspondre le transport que l’upstream configuré utilise réellement, et la fuite se ferme pour la bonne raison.