Защо заявките на dnsmasq излизат извън VPN след DNS пренасочване
REDIRECT от страна на рутера превръща LAN DNS заявката в нов сокет на резолвера. Маркировките върху клиентския поток никога не стигат до него, затова задайте изхода на upstream направо.
LAN клиентът достига своя VPN правилно, а DNS заявките му все още се показват на грешния изходящ канал. Това не е изтичане в обичайния смисъл; това е, което се случва, когато рутерът спре да препраща заявка и отговори сам. Прихващането пренаписва дестинацията към локален сокет и след това резолверът отваря втори, несвързан разговор със свой собствен адрес на източника и свое собствено решение за маршрут. Маркировките, приложени към клиентския поток, описват първия разговор и нищо абсолютно за втория.
Маркировката не пътува със заявката
Маркировките на пакетите живеят в запис на conntrack и в пакета по време на полет. Правило REDIRECT прекратява този полет: полезният товар се предава на локален сокет и оригиналният запис е свършил работата си. Това, което напуска рутера след това, е нов сокет, създаден от процеса на резолвера, с адрес на източника — адреса на самия рутер.
Затова маршрут по политика, обвързан с адреса на LAN клиента, никога не съвпада с upstream заявката. Новият сокет принадлежи на dnsmasq, а не на клиента, и ядрото оценява маршрута за собствения трафик на рутера. Правилата за източник, за интерфейс и за маркировка виждат различен набор. Предполагането, че маркировката се разпространява, е най-честата грешка в тази подредба и е невидимо в прихващане от страна на клиента.
Двата разговора наистина споделят име и време и точно това ги кара да изглеждат като един поток, когато прегледате прихващане набързо.
Къде препращането се превръща в локално разрешаване
Започнете като установите дали порт 53 е пренасочен, преобразуван към друг хост или оставен непокътнат, защото трите случая се държат различно. Пренасочването към локален порт прекратява препращането, докато преобразуването към друга машина държи пакета в движение и запазва набора на клиента смислен.
Разгледайте и двата протокола. Резолвер, достъпен по UDP и TCP, ще бъде тестван по двата, а набор от правила, покриващ само UDP, оставя тиха дупка за големи отговори. Правилата, генерирани от собствения мениджър на конфигурация на рутера, също се броят, а редактирането на генериран файл обикновено губи от следващото презареждане.
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'
Тези изходи отговарят на три въпроса по ред: какво пренаписва заявката, какво я получава и кой процес притежава слушащия сокет. Щом собственикът е известен, политиката за upstream има къде да живее.
Дайте на резолвера собствена политика за изход
Upstream, специфичен за домейн, е най-чистият инструмент, когато само някои имена се нуждаят от тунела. dnsmasq приема ред server, ограничен до домейн, с незадължителен интерфейс или адрес на източника, който насочва заявката извън избрано устройство. Точно това насочване кара втория разговор да следва VPN.
server=/corp.example/10.30.0.53@tun_work
log-queries
Домейнът, адресът и интерфейсът по-горе са заместители за вашите собствени стойности. Изборът на домейн и контролът на изхода остават отделни решения: маршрутът трябва да съществува, адресът на източника трябва да бъде разрешен от upstream резолвера и защитната стена трябва да позволи отговора. Самото насочване на интерфейса не е fail-closed, защото изчезнал тунел може да остави резолвера да падне към друг път. Дръжте всеки публичен резервен път далеч от пространство от имена, което трябва да остане частно.
Поставете реда в собственика на конфигурацията, който рутерът поддържа, а не в генериран файл, иначе следващото презареждане изтрива поправката.
Какво не може да запази споделен кеш
Един препращач с един кеш обслужва всеки LAN клиент и това срива разлика, от която някои мрежи се нуждаят. Ако двама клиенти трябва да разрешат едно и също име различно, споделеният сокет няма как да възстанови кой клиент е попитал. Политиката за клиент трябва да живее в отделни инстанции на резолвера или във функция за препращане, която запазва идентичността.
Кешираният отговор също не е доказателство за новия път. Отговорът може да дойде от паметта, докато upstream маршрутът остава счупен.
Правилата за порт 53 не казват нищо за приложения, които говорят DNS през HTTPS или през TLS. Тези заявки никога не стигат до пренасочването, затова политика, изградена само върху порт 53, описва подмножество от трафика и трябва да бъде документирана като подмножество.
Проверете втория разговор, не първия
Тествайте с едно име, което контролирате, и наблюдавайте двете страни. Прихващане от страна на клиента доказва, че заявката е напуснала LAN; само страната на рутера доказва накъде е отишла след това.
sudo tcpdump -ni tun_work udp port 53
ip route get 10.30.0.53
dig +short corp.example @10.30.0.53
Изчистете кеша преди всеки опит, защото топъл отговор скрива счупен upstream. Повторете по TCP, след това повторете със спрян тунел, за да видите какво прави резолверът, когато предпочитаният му път изчезне. Това последно поведение решава дали дизайнът е fail-closed или просто късметлия.