Wanneer de killswitch de tunnel laat vallen, neemt hij het DNS-pad mee, en de resolver die achterblijft is zelden degene die je verwacht. Twee ontwerpen pakken dat moment heel verschillend aan: elk DNS-pakket blokkeren dat niet in de tunnel zit, oféén resolver als uitzondering laten staan. Beide zijn verdedigbaar. Vanuit een browsertab zien de symptomen er bijna hetzelfde uit, dus de eerste taak is uitzoeken welk ontwerp je echt hebt uitgerold.

Ik houd dat onderscheid voor ogen omdat de oplossing in elk geval tegengesteld is. Het ene ontwerp heeft een bredere uitzondering nodig, het andere een smallere. Gokken kost je ofwel privacy ofwel een middag.

Twee DNS-ontwerpen voor dezelfde storing

Ontwerp A behandelt de resolver als een dienst als alle andere achter de tunnel. Firewallregels staan UDP en TCP 53 alleen toe op de tunnelinterface, en het adres dat de client krijgt is een resolver binnen de tunnel. Als de tunnel valt, stoppen de opzoekingen, en dat is het bedoelde resultaat, geen fout.

Ontwerp B houdt een resolver bereikbaar op het lokale netwerk, meestal de router op 192.168.1.1 of de stub van het besturingssysteem op 127.0.0.53, met de redenering dat naamresolutie niet met de tunnel mag sterven. Op een thuis-LAN waar de router voor het hele huis resolveert is dat handig. Op de Wi-Fi van een hotel of luchthaven wijst diezelfde uitzondering naar andermans server, en elke naam die je typt wordt onthuld, ook al blijft je webverkeer geblokkeerd.

De grens is wie de resolver bezit. Vertrouw je de lokale, dan is een uitzondering een klein, eerlijk gat. Doe je dat niet, dan is het alleen-tunnelontwerp het enige dat standhoudt, en de prijs is dat een gevallen tunnel alle namen meeneemt.

Waarom het opzoeken van de VPN-client zelf blijft werken

De client moet de hostnaam van de gateway resolven voordat er een tunnel bestaat, dus een strikte blokkade mag het bootstrap-pad van de client niet dekken. De meeste clients cachen het endpointadres of leveren een gedocumenteerde bootstrap-uitzondering voor precies die ene host. Blokkeert je regelset die opzoeking, dan komt de tunnel nooit terug en tonen de logs een client die zijn eigen server niet bereikt; dat is een beleidsfout en geen DNS-fout.

Gesplitst DNS is de andere plek waar dit opduikt. De client duwt een interne zone naar een private resolver en laat al het andere bij de systeemresolver. Na een val kunnen publieke namen nog resolven terwijl interne namen time-out lopen, omdat de private zone geen route meer heeft. Voor de gebruiker is dat "de VPN heeft internet gesloopt"; voor het resolverlog is het een query die nooit aankwam.

Onder systemd-resolved zie je de splitsing direct.resolvectl statustoont de DNS-servers per link en de routingdomeinen, en nadat de tunnel is weggevallen blijft het interne domein wijzen naar een server op een link die niet meer bestaat. De stub op 127.0.0.53 neemt de query nog aan en wacht dan op een upstream die niet zal antwoorden, en daarom duurt de fout seconden in plaats van meteen terug te keren.

Versleuteld DNS gaat niet om een pakketfilter heen

DNS over HTTPS en DNS over TLS reizen over 443 en 853, dus een regel die poort 53 blokkeert heeft daar niets over gezegd. "DNS" op poort blokkeren is beleid over een poort, niet over naamresolutie. Als je killswitch al het verkeer buiten de tunnel blokkeert, is DoH toevallig gedekt. Heb je een uitzondering gemaakt voor een captive portal of een publieke resolver, dan niet.

Bediening aan de clientkant is de goedkopere hefboom. Firefox laat zijn DoH-resolver vallen als de kanariehostnaamuse-application-dns.netniet resolvet, en daarom publiceren beheerde netwerken dat domein als NXDOMAIN; bedrijfsbeleid kan hem ook uitgeschakeld vastzetten. Android Private DNS en Chrome's beveiligde DNS hebben hun eigen schakelaars en hun eigen standaardwaarden. Die uitzetten is betrouwbaarder dan achter resolveradressen aanjagen, want de adressenlijst verandert en je regelset niet.

Er is een versie hiervan die helemaal niet over lekken gaat. Een applicatie met een vastgezette resolver heeft nog steeds een netwerkpad nodig om hem te bereiken. Versleuteling verandert wie de query kan lezen, niet of het pakket de machine kan verlaten, dus een blokkade voor het hele apparaat verslaat de instelling zonder hem aan te raken.

Koppel het symptoom aan de laag

De meeste meldingen komen binnen als één zin, en die zin noemt vaak al de laag. De tabel hieronder is wat ik doorloop voordat ik een regel aanraak; het doel is beslissen of de query geblokkeerd, verkeerd gerouteerd of nooit verzonden is.

SymptomLikely layerFirst check
Every name fails at once, instantlyResolver answering with a refusalQuery the resolver by address, not by name
Lookups hang for seconds, then time outPackets dropped with no responseWatch port 53 on the physical link
Public names resolve, internal ones do notSplit-DNS routing domainPer-link DNS servers on the tunnel
Names resolve, the page still failsNot DNS: routing or MTUConnect to the IP directly
Only one application failsPinned resolver or cached answerCheck that app's DNS setting

De eerste twee rijen zijn degene die mensen verkeerd diagnosticeren. Een stille val en een weigering zien er in een browser allebei uit als "DNS is stuk", maar slechts één ervan betekent dat je killswitch zijn werk doet. Een weigering betekent dat er iets antwoordde, dus de blokkade zit niet waar je denkt.

Herstel het resolverbeleid en bewijs het daarna

Repareer het ontwerp, niet het symptoom. Voor resolutie alleen in de tunnel sta je 53 toe op de tunnelinterface, duw je de interne resolver mee met de tunnelconfiguratie en laat je de fysieke link zonder enige DNS-toestemming. Bij wg-quick is de regelDNS =degene die de resolver in de interfaceconfiguratie schrijft, dus een tunnel die hem weglaat laat de oude resolver staan en elke query op het verkeerde pad.wg-quick-handleidingdocumenteert dat gedrag per platform.

Controleer daarna in deze volgorde. Op Linux toontresolvectl statusde actieve link,dig +short example.comtest een publieke naam,dig @10.8.0.1 internal.example.comtest de private, ensudo tcpdump -ni any port 53toont welke interface de pakketten gebruiken terwijl je beide draait. Op Windows gevenGet-DnsClientServerAddress -AddressFamily IPv4enResolve-DnsName example.comdezelfde twee feiten: wie is geconfigureerd en wie antwoordt.

Sluit af met de negatieve test. Ontkoppel de tunnel, bevestig dat een verse publieke naam faalt, bevestig dat de private naam faalt, enbevestig dat er geen enkel poort 53-pakket de fysieke adapter heeft verlaten. Een blokkade die alleen voor gecachte antwoorden houdt, houdt helemaal niet.

Checklist voordat je het ticket sluit:

  • De resolver die tijdens de storing werd gebruikt is degene die het beleid bedoelt.
  • Het opzoeken van het eigen endpoint door de client is nog toegestaan, via cache of uitzondering.
  • DoH en DoT zijn ofwel gedekt door de blokkade ofwel uitgeschakeld door beleid.
  • Private zones falen gesloten, niet open, zodra de tunnel weg is.

Gerelateerde artikelen