De ce interogările dnsmasq ies din VPN după o redirecționare DNS
Un REDIRECT pe partea routerului transformă o interogare DNS din LAN într-un socket nou al resolverului. Marcajele de pe fluxul clientului nu ajung niciodată acolo, așa că setați ieșirea către upstream direct.
Clientul din LAN ajunge corect la VPN-ul său și totuși interogările sale DNS apar pe legătura superioară greșită. Nu este o scurgere în sensul obișnuit; este ceea ce se întâmplă când routerul nu mai redirecționează o interogare și răspunde el însuși la ea. Interceptarea rescrie destinația către un socket local, iar apoi resolverul deschide o a doua conversație, fără legătură, cu propria adresă sursă și propria decizie de rutare. Marcajele aplicate fluxului clientului descriu prima conversație și absolut nimic despre a doua.
Marcajul nu călătorește cu interogarea
Marcajele de pachet trăiesc pe o intrare conntrack și pe pachetul în zbor. O regulă REDIRECT încheie acel zbor: încărcătura este predată unui socket local, iar intrarea originală și-a făcut treaba. Ceea ce părăsește routerul după aceea este un socket nou creat de procesul resolverului, cu adresa routerului însuși ca sursă.
De aceea o rută de politică legată de adresa clientului din LAN nu se potrivește niciodată cu interogarea către upstream. Noul socket aparține dnsmasq și nu clientului, iar kernelul evaluează ruta pentru traficul routerului însuși. Regulile de sursă, regulile de interfață și regulile de marcaj văd toate un tuplu diferit. Presupunerea că marcajul se propagă este cea mai frecventă greșeală în această configurație și este invizibilă într-o captură pe partea clientului.
Cele două conversații împart într-adevăr un nume și un moment, și exact asta le face să pară un singur flux când răsfoiești o captură.
Unde redirecționarea devine rezolvare locală
Începeți prin a afla dacă portul 53 este redirecționat, tradus către alt host sau lăsat neatins, pentru că cele trei cazuri se comportă diferit. O redirecționare către un port local termină redirecționarea, în timp ce o traducere către altă mașină ține pachetul în mișcare și păstrează tuplul clientului semnificativ.
Priviți ambele protocoale. Un resolver accesibil prin UDP și TCP va fi testat prin ambele, iar un set de reguli care acoperă doar UDP lasă o gaură tăcută pentru răspunsurile mari. Contează și regulile generate de managerul de configurare al routerului însuși, iar editarea unui fișier generat pierde de obicei în fața următoarei reîncărcări.
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'
Acele ieșiri răspund la trei întrebări în ordine: ce rescrie interogarea, ce o primește și ce proces deține socketul care ascultă. Odată ce proprietarul este cunoscut, politica către upstream are unde să locuiască.
Dați resolverului propria politică de ieșire
Un upstream specific domeniului este cea mai curată unealtă când doar unele nume au nevoie de tunel. dnsmasq acceptă o linie server limitată la un domeniu, cu o interfață sau adresă sursă opțională care direcționează interogarea în afara unui dispozitiv ales. Acea direcționare este ce face a doua conversație să urmeze VPN-ul.
server=/corp.example/10.30.0.53@tun_work
log-queries
Domeniul, adresa și interfața de mai sus sunt substituenți pentru valorile dumneavoastră. Selecția domeniului și controlul ieșirii rămân decizii separate: ruta trebuie să existe, adresa sursă trebuie permisă de resolverul upstream, iar firewallul trebuie să permită răspunsul. Doar direcționarea prin interfață nu este fail-closed, pentru că un tunel dispărut poate lăsa resolverul să cadă pe altă cale. Țineți orice alternativă publică departe de un spațiu de nume care trebuie să rămână privat.
Puneți linia la proprietarul configurației pe care routerul îl acceptă, nu într-un fișier generat, altfel următoarea reîncărcare șterge corectura.
Ce nu poate păstra un cache partajat
Un singur forwarder cu un singur cache deservește fiecare client din LAN, iar asta dărâmă o distincție de care unele rețele au nevoie. Dacă doi clienți trebuie să rezolve același nume diferit, socketul partajat nu are cum să recupereze care client a întrebat. Politica pe client trebuie să trăiască în instanțe de resolver separate sau într-o funcție de redirecționare care păstrează identitatea.
Un răspuns din cache nu este nici el o dovadă despre noua cale. Răspunsul poate veni din memorie în timp ce ruta către upstream rămâne ruptă.
Regulile pentru portul 53 nu spun nimic despre aplicațiile care vorbesc DNS prin HTTPS sau prin TLS. Acele interogări nu ajung niciodată la redirecționare, deci o politică construită doar pe portul 53 descrie o submulțime a traficului și ar trebui documentată ca submulțime.
Verificați a doua conversație, nu prima
Testați cu un nume pe care îl controlați și urmăriți ambele părți. O captură pe partea clientului dovedește că interogarea a părăsit LAN-ul; doar partea routerului dovedește unde a mers mai departe.
sudo tcpdump -ni tun_work udp port 53
ip route get 10.30.0.53
dig +short corp.example @10.30.0.53
Goliți cache-ul înainte de fiecare încercare, pentru că un răspuns cald ascunde un upstream rupt. Repetați prin TCP, apoi repetați cu tunelul oprit pentru a vedea ce face resolverul când calea sa preferată a dispărut. Acel ultim comportament decide dacă proiectul este fail-closed sau doar norocos.