DNS via WireGuard herstellen: 3 oorzaken
Uw WireGuard-tunnel werkt, maar DNS faalt of lekt naar de lokale router. Herken de drie oorzaken en herstel de resolver-configuratie met de juiste oplossing.
Waarom DNS uitvalt zodra de WireGuard-tunnel wordt geactiveerd
DNS over WireGuard faalt op drie manieren, en voor elk probleem is een specifieke oplossing. Ofwel er wordt niets meer omgezet, ofwel namen worden wel omgezet maar de queries verlaten uw machine buiten de tunnel om, of de eigen resolver-manager van de client overschrijft de instelling seconden nadat de interface is gestart. De tunnel is vrijwel nooit het probleem. Het probleem is de regel die de client vertelt welke resolver hij moet raadplegen, en de routering die bepaalt hoe pakketten naar die resolver reizen.
WireGuard verplaatst IP-pakketten en weet niets van DNS (domain name system, de dienst die namen zoals example.com omzet naar IP-adressen). De DNS =-regel in een [Interface]-blok van een client is geen WireGuard-instelling. Deze wordt gelezen door wg-quick, de shell-wrapper die de interface opstart, waarna wg-quick de resolver-configuratie van de client aanpast terwijl de tunnel actief is en deze herstelt bij wg-quick down. Elk onderstaand probleem is dus een routeringsprobleem of een wg-quick-probleem, nooit een cryptografisch probleem. Als de tunnel zelf nog niet is opgezet, begin dan bij een zelfgehoste WireGuard VPN op uw eigen VPS en keer daarna terug naar deze pagina.
Controleer of de tunnel gezond is voordat u wijzigingen aanbrengt in DNS.
sudo wg show
ping -c 3 10.8.0.1
ping -c 3 1.1.1.1wg show hoort de peer met een recente latest handshake weer te geven, en beide pings zouden antwoord moeten geven. Als ping 1.1.1.1 een time-out geeft, heeft u hoogstwaarschijnlijk een probleem met forwarding of NAT (network address translation) in plaats van een DNS-probleem, en zal geen enkele wijziging in de resolver-configuratie helpen. Een firewall die ICMP blokkeert veroorzaakt dezelfde time-out, dus controleer dit met curl -sI https://1.1.1.1 voordat u begint met het wijzigen van forwarding-regels. Als de pings wel antwoord geven maar de doorvoer instort zodra er echt verkeer plaatsvindt, is dat een afzonderlijk probleem, en trage WireGuard is bijna altijd terug te voeren op MTU in plaats van op zaken op deze pagina. Elk voorbeeld hier gebruikt 10.8.0.0/24 als het tunnel-subnet en 10.8.0.1 als het tunnel-adres van de server. Vervang deze door uw eigen gegevens.
Fout één: niets wordt omgezet, omdat de resolver nooit antwoordt
Het symptoom is specifiek. ping 1.1.1.1 werkt en curl https://example.com geeft dit terug:
curl: (6) Could not resolve host: example.comBevraag de tunnel-resolver rechtstreeks vanaf de client. dig is afkomstig uit het dnsutils-pakket op Ubuntu en Debian.
dig +short @1.1.1.1 example.com
dig +short @10.8.0.1 example.comHet eerste commando geeft een adres terug, wat bewijst dat pakketten via de tunnel het internet bereiken. Het tweede geeft niets terug en toont ;; communication timed out; no servers could be reached. Dat is de volledige diagnose: uw client is ingesteld op 10.8.0.1 en 10.8.0.1 antwoordt niet op UDP-poort 53.
Twee oorzaken veroorzaken dit. Of er draait geen resolver op de server, of de serverfirewall blokkeert de query voordat deze aankomt. Controleer beide op de server.
sudo ss -ulnp | grep ':53'
sudo nft list rulesetEen resolver die draait en correct is gebonden, toont een regel met 10.8.0.1:53 of 0.0.0.0:53. Op Ubuntu is de verrassing meestal 127.0.0.53:53: dat is de systemd-resolved stub-listener, die een loopback-adres bindt en bewust onbereikbaar is vanaf andere machines. Een VPN-client instellen op een server waarvan de enige resolver die stub is, resulteert precies in deze time-out.
De oplossing is een resolver die luistert op het tunneladres, plus één firewallregel die toestaat dat peers deze bereiken.
sudo apt update && sudo apt install -y unbound
printf 'server:\n interface: 10.8.0.1\n access-control: 10.8.0.0/24 allow\n' \
| sudo tee /etc/unbound/unbound.conf.d/wireguard.conf
sudo systemctl restart unbound
sudo ss -ulnp | grep '10.8.0.1:53'Open vervolgens de poort alleen voor tunnelverkeer. Voeg met nftables deze twee regels toe aan de input-chain in /etc/nftables.conf en herlaad met sudo systemctl reload nftables.
udp dport 53 iifname "wg0" accept
tcp dport 53 iifname "wg0" acceptMet ufw doet sudo ufw allow in on wg0 to any port 53 hetzelfde. Open poort 53 nooit voor het openbare internet. Een open recursieve resolver wordt binnen enkele dagen gevonden door scanners en gebruikt om denial-of-service-aanvallen te versterken; uw provider zal dat verkeer eerder opmerken dan u.
Voer dig +short @10.8.0.1 example.com opnieuw uit vanaf de client. Een adres in de uitvoer betekent dat het resolverpad werkt, dus de client hoeft het nu alleen nog maar te gebruiken. Voeg de regel toe aan het [Interface]-blok van de client en herstart de interface met sudo wg-quick down wg0 && sudo wg-quick up wg0.
[Interface]
PrivateKey = <client private key>
Address = 10.8.0.2/32
DNS = 10.8.0.1Fout twee: DNS-lekken, omdat een split tunnel de resolver niet routeert
Dit is ernstiger, omdat alles lijkt te werken. Namen worden omgezet, pagina's laden en de zoekopdrachten reizen in leesbare tekst over het lokale netwerk dat u niet wilde vertrouwen.
Twee configuraties veroorzaken dit. De eerste is een client met AllowedIPs = 0.0.0.0/0, ::/0 en zonder DNS =-regel. wg-quick installeert de standaardroute in zijn eigen routeringstabel en voegt een regel toe met suppress_prefixlength 0, die specifiekere lokale routes bewust in stand houdt zodat de machine nog steeds zijn printer kan bereiken. De resolver die de client via DHCP heeft geleerd, meestal de router op 192.168.1.1, komt overeen met een van die lokale routes. Uw verkeer gaat door de tunnel. Het lokale netwerk ontvangt echter nog steeds de volledige lijst met namen die u opzoekt.
De tweede is een split tunnel: AllowedIPs = 10.8.0.0/24 met DNS = 9.9.9.9. Omdat 9.9.9.9 zich niet binnen AllowedIPs bevindt, heeft de client geen route ernaartoe via de tunnel, waardoor de zoekopdracht via de lokale verbinding vertrekt, precies zoals in het eerste geval.
Controleer welke resolver daadwerkelijk antwoordt. whoami.akamai.net is een publieke testnaam die antwoordt met het IP-adres van de recursieve resolver die de vraag stelde, zodat u het antwoord kunt vergelijken met het publieke adres van uw server.
resolvectl status
dig +short whoami.akamai.net
sudo tcpdump -ni any -c 10 port 53resolvectl status print één blok per verbinding. Als het blok voor uw ethernet- of draadloze verbinding nog steeds Current DNS Server: 192.168.1.1 toont terwijl het wg0-blok er geen toont, is dat het lek. dig +short whoami.akamai.net dat uw thuis-breedbandadres teruggeeft in plaats van het adres van uw server, bevestigt dit vanaf de andere kant. De tcpdump-regel is het bewijs dat discussies beëindigt: bij een gezonde configuratie wordt elk pakket op poort 53 dat de machine verlaat op wg0 geplaatst, en bij een lek op wlan0 of enp3s0. Pakketten op lo van of naar 127.0.0.53 zijn applicaties die communiceren met de lokale systemd-resolved stub; dit is geen lek.
De oplossing bestaat uit twee delen en beide zijn vereist. Stel DNS in op een adres dat zich binnen de tunnel bevindt en zorg ervoor dat dat adres binnen AllowedIPs valt.
[Interface]
Address = 10.8.0.2/32
DNS = 10.8.0.1
[Peer]
PublicKey = <server public key>
Endpoint = vpn.example.com:51820
AllowedIPs = 10.8.0.0/24, 10.20.0.0/1610.8.0.1 bevindt zich binnen 10.8.0.0/24, dus de zoekopdracht wordt versleuteld en naar de server verzonden. Als u op een split tunnel per se een publieke resolver wilt gebruiken, voeg deze dan toe als hostroute: AllowedIPs = 10.8.0.0/24, 9.9.9.9/32. De pakketten worden dan getunneld, hoewel het lokale netwerk nog steeds kan zien dat u die provider uit eerdere sessies hebt gekozen. Een resolver die u zelf beheert, voorkomt deze kwestie.
Resolver-toewijzing is een van de zichtbare verschillen tussen handmatig geconfigureerde WireGuard en een gecoördineerd mesh-netwerk, wat onderdeel is van de afweging in WireGuard vergeleken met Tailscale. Het draaien van een zelfgehoste Headscale-controleserver biedt u die coördinatie zonder uw sleutelmateriaal aan een derde partij te overhandigen. Als die laatste zinsnede u zorgen baart, bedenk dan dat Tailscale nooit de sleutels bezit die uw verkeer versleutelen, en dat de scherpere vraag is wat een gecompromitteerde coördinatieserver of een gestolen identiteitsaccount aan uw netwerk zou kunnen toevoegen.
Fout drie: resolvconf en systemd-resolved conflicteren op Linux-clients
macOS-, Windows-, iOS- en Android-clients passen DNS = toe via de officiële app en veroorzaken zelden problemen. Op Linux wordt de instelling toegepast door een shell-script dat moet raden welke van de verschillende resolver-managers u gebruikt.
De eerste fout is duidelijk zichtbaar. sudo wg-quick up wg0 stopt met:
resolvconf: command not foundwg-quick roept resolvconf aan, en dat binaire bestand is niet geïnstalleerd. Op Debian 12 en Ubuntu 24.04 of later wordt het resolvconf-commando dat communiceert met systemd-resolved meegeleverd in het systemd-resolved-pakket. Installeer dit pakket en breng de interface daarna opnieuw omhoog. Ubuntu 22.04 heeft geen apart pakket hiervoor; maak daar zelf de compatibiliteitslink aan met sudo ln -s /usr/bin/resolvectl /usr/local/bin/resolvconf en sla de installatieregel over.
sudo apt install -y systemd-resolved
sudo systemctl restart systemd-resolved
sudo wg-quick down wg0 && sudo wg-quick up wg0
resolvectl status wg0De tweede fout is minder opvallend en kost vaak een hele avond om op te lossen. De interface komt omhoog, resolvectl status wg0 toont correct DNS Servers: 10.8.0.1, maar opzoekingen bereiken nog steeds de oude resolver. systemd-resolved negeert wg0 niet. Een naam die niet overeenkomt met een routing-domein wordt naar de DNS-servers van elke verbinding gestuurd die als standaardroute geldt. Een verbinding met DNS-servers zonder 'route-only'-domein telt standaard als zodanig. De query gaat dus tegelijkertijd naar 10.8.0.1 en naar de router op de draadloze verbinding; het eerste succesvolle antwoord wint. De router is één hop verwijderd en antwoordt meestal als eerste, en de query is hoe dan ook al in platte tekst verzonden. Namen onder het eigen zoekdomein van de draadloze verbinding, zoals lan, gaan alleen naar die verbinding, omdat het meest specifieke routing-domein voorrang krijgt.
Wanneer wg-quick de instelling DNS = toepast via de eigen resolvconf-wrapper van systemd, wordt er al gevraagd om een 'catch-all' routing-domein. Dit probleem treedt daarom vooral op wanneer een andere resolvconf-implementatie of een netwerkbeheerder de instelling heeft toegepast. Door dit expliciet in te stellen, wordt giswerk voorkomen.
Stel de resolver in en claim het 'catch-all' routing-domein in dezelfde stap. %i wordt uitgebreid naar de interfacenaam, waardoor dit blok ongewijzigd werkt op elke interface.
[Interface]
Address = 10.8.0.2/32
PostUp = resolvectl dns %i 10.8.0.1; resolvectl domain %i ~.
PostDown = resolvectl revert %iVerwijder de DNS =-regel wanneer u PostUp op deze manier gebruikt, omdat anders twee mechanismen de resolver-status schrijven en slechts één daarvan achteraf opschoont. Het ~.-argument is het belangrijkste onderdeel: het maakt van wg0 het 'route-only'-domein voor elke naam. Hierdoor stopt systemd-resolved met het sturen van namen die niet overeenkomen met een specifieker domein naar de andere verbindingen. Namen onder het eigen domein van een andere verbinding, zoals lan, gaan nog steeds naar die verbinding; dit is meestal de gewenste situatie voor lokale hosts. Controleer dit.
resolvectl status wg0Een correcte uitvoer bevat DNS Servers: 10.8.0.1 en DNS Domain: ~.. Als ~. ontbreekt, is het resolvectl domain-gedeelte niet uitgevoerd en concurreert wg0 weer met de andere verbindingen. Gebruik de 'default route'-vlag niet als controle: deze leest yes (of +DefaultRoute op de Protocols-regel, afhankelijk van de systemd-versie), zelfs zonder ~., omdat een verbinding zonder 'route-only'-domein sowieso een standaardroute is.
Eén ander geval is het vermelden waard. Als /etc/resolv.conf een echt bestand is in plaats van een symbolische link naar /run/systemd/resolve/stub-resolv.conf, dan wordt het beheerd door iets anders, meestal NetworkManager of een container-runtime. Voer ls -l /etc/resolv.conf uit voordat u andere zaken gaat debuggen, omdat een tool die dat bestand bij elke netwerkwijziging overschrijft, uw werk ongedaan maakt op het minst gunstige moment.
De upgrade: uw eigen filterende resolver via de tunnel
Zodra DNS-queries betrouwbaar door de tunnel worden verstuurd, fungeert de resolver aan de andere kant als centraal controlepunt. Door daar AdGuard Home te draaien, krijgt elk verbonden apparaat blokkeerlijst-filtering en een query-log, zonder dat er client-software nodig is of configuratie per apparaat vereist is. Het officiële installatiescript, gecontroleerd in oktober 2026, bestaat uit één regel.
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -vDe installatiewizard luistert bij de eerste keer opstarten op poort 3000. Benader deze via de tunnel op http://10.8.0.1:3000 in plaats van die poort publiekelijk open te stellen. Stel in de wizard zowel het DNS-luisteradres als het beheer-luisteradres in op 10.8.0.1. Als unbound uit de eerste foutmelding nog steeds hetzelfde adres gebruikt, stop deze dan eerst met sudo systemctl disable --now unbound. Anders strijden beide om UDP-poort 53 op hetzelfde adres en sluit AdGuard Home af met listen udp 10.8.0.1:53: bind: address already in use.
Client-configuraties hoeven niet te worden gewijzigd als deze al naar DNS = 10.8.0.1 verwijzen. Het query-logboek toont nu elke opzoekopdracht die vanaf elke peer binnenkomt, tenzij u een client uitsluit van logging. Dit is een bewuste keuze voor privacy in plaats van een gratis voordeel: u verlegt het vertrouwen van uw internetprovider naar uzelf, en u bent degene die het systeem moet patchen. Een server die aan het internet wordt blootgesteld, moet eerst over de basisbeveiliging beschikken, en de eerste tien minuten op een nieuwe VPS behandelt deze stappen.
FAQ
Waarom brengt mijn WireGuard-tunnel verbinding tot stand, maar worden namen niet omgezet?
De tunnel transporteert pakketten en verwerkt zelf geen namen. Een werkende tunnel met falende opzoekingen betekent dat de resolver waarnaar u verwijst niet antwoordt. Test dit vanaf de client met dig +short @10.8.0.1 example.com. Een communication timed out-antwoord betekent dat er geen resolver luistert op dat tunneladres, vaak omdat de systemd-resolved stub alleen bindt op 127.0.0.53, of dat de serverfirewall UDP-poort 53 blokkeert die binnenkomt op wg0. Herstel eerst de listener en open de poort vervolgens uitsluitend voor wg0.
Hoe controleer ik of mijn DNS lekt via WireGuard?
Voer sudo tcpdump -ni any -c 10 port 53 uit op de client en observeer de interfacekolom terwijl u surft. Elk pakket dat de machine verlaat, moet via wg0 verlopen; pakketten op lo van of naar 127.0.0.53 zijn afkomstig van de lokale systemd-resolved stub en zijn in orde. Als ze verschijnen op uw draadloze of ethernet-interface, verlaten de queries het systeem in leesbare tekst. dig +short whoami.akamai.net biedt een tweede controle, omdat deze antwoordt met het publieke adres van de recursieve resolver die de vraag stelde. Een antwoord dat niet het adres van uw server is, bevestigt het lek.
Heb ik de DNS =-regel nodig als ik een split tunnel gebruik?
Ja, en het adres van de resolver moet zich ook binnen AllowedIPs bevinden, anders heeft de client geen route ernaartoe. Met AllowedIPs = 10.8.0.0/24 is een resolver op 10.8.0.1 gedekt en wordt de query versleuteld. Een publieke resolver zoals 9.9.9.9 is niet gedekt, waardoor de query via de lokale verbinding vertrekt, ook al lijkt de DNS-regel correct.
Waarom toont resolvectl de juiste server, maar gaan opzoekingen toch ergens anders heen?
systemd-resolved stuurt een naam die niet overeenkomt met een routingdomein naar elke link met een standaardroute tegelijk, inclusief wg0, en geeft het eerste succesvolle antwoord terug, dat meestal van de lokale router komt. Voeg PostUp = resolvectl dns %i 10.8.0.1; resolvectl domain %i ~. toe aan het [Interface]-blok van de client en verwijder de DNS =-regel. resolvectl status wg0 zou dan DNS Domain: ~. moeten rapporteren, en elke naam die niet door een andere link met een specifieker domein wordt geclaimd, gaat dan uitsluitend naar wg0.
Welke client moet ik als eerste repareren als er meerdere defect zijn?
Repareer één Linux-client, omdat dit het enige platform is dat u het mechanisme toont. resolvectl status en tcpdump vertellen u welke resolver antwoordde en welke interface het pakket transporteerde. Telefoon- en desktop-apps passen dezelfde DNS- en AllowedIPs-waarden toe zonder zichtbare techniek. Zodra de Linux-client correct is, kopieert u een configuratie die u al heeft bewezen.