WireGuard DNS DNAT: håll svarsvägen fungerande
DNAT skriver om destinationen, inte källan. Bestäm hur den uppströms resolvern kan svara innan du lägger till regeln, och håll varje träff snäv.
Att rikta en WireGuard-klients DNS-fråga mot en annan resolver ser ut som en regel och beter sig som tre beslut. Destinationen måste skrivas om, paketet måste vidarebefordras, och svaret måste hitta vägen tillbaka genom det översättningstillstånd som gatewayen skapade. Hoppa över det tredje och frågan lämnar rent medan klienten väntar för evigt.
Ta exemplet med auktoriserade klienter i 10.77.0.0/24 som kommer in via wg0, frågar efter den annonserade adressen 10.77.0.1 och behöver en resolver på 203.0.113.53. Den uppströms adressen är en platshållare för dokumentation, inte en tjänst som fungerar.
Omdirigering av en fråga ändrar bara dess destination
En destinations-NAT-regel i PREROUTING skriver om adressen innan routingbeslutet fattas, så paketet dirigeras därefter mot den nya destinationen i stället för den gamla. Klientens källadress lämnas orörd av den operationen. Därför kan en regel som ser komplett ut ändå ge tystnad: förfrågan färdas nu till en resolver som aldrig har hört talas om klientens privata intervall. Gatewayen översatte ett fält och ärvde ett andra problem.
Båda DNS-transporterna behöver matchande regler, eftersom en klient faller tillbaka till TCP när ett svar trunkeras.
Reglerna nedan väljer ett inkommande gränssnitt, ett klientintervall och en ursprunglig destinationsadress. Inget annat på gatewayen påverkas, och en fråga från gatewayen själv matchar inte alls.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -i wg0 -s 10.77.0.0/24 -d 10.77.0.1 -p udp --dport 53 -j DNAT --to-destination 203.0.113.53:53
iptables -t nat -A PREROUTING -i wg0 -s 10.77.0.0/24 -d 10.77.0.1 -p tcp --dport 53 -j DNAT --to-destination 203.0.113.53:53
Svarsvägen är ett eget beslut
Två arrangemang låter svaret komma tillbaka, och att välja ett tidigt sparar en felsökningssession. Antingen har den uppströms resolvern en väg tillbaka till 10.77.0.0/24 genom denna gateway, eller så översätter gatewayen källan vid utgången så att svaret anländer till en adress som uppströms redan känner till. Båda fungerar; bara en matchar den kontroll du har över uppströms.
Routing förtjänar det första försöket, eftersom det håller klientens adress synlig för resolvern och undviker ett andra översättningslager. När uppströms ligger utanför din kontroll är källöversättning på det specifika utgångsgränssnittet det praktiska valet.
Begränsa den översättningen lika snävt som omdirigeringen, annars blir regeln en NAT för allmänna ändamål för allt som råkar matcha:
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -d 203.0.113.53 -o eth0 -p udp --dport 53 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -d 203.0.113.53 -o eth0 -p tcp --dport 53 -j MASQUERADE
Anslutningsspårning håller mappningen i par, så svaret skrivs tillbaka till klientens ursprungliga tuple på väg tillbaka. Utan utgångsregeln skickar resolvern sitt svar mot en privat adress som den inte kan nå, och klienten ser en tidsgräns i stället för ett fel.
Skriv reglerna snävare än uppgiften ser ut
Vidarebefordranstillstånd hör till samma omfång. Tillåt flödet från klient till resolver och den returtrafik som conntrack redan känner igen, i stället för att acceptera varje DNAT-anslutning på maskinen. En blanket-acceptans auktoriserar också portvidarebefordringar som inte har något med DNS att göra.
Gatewayens egen resolver är en annan kodväg. En fråga som utfärdas lokalt går genom OUTPUT, så test från gatewayens skal övar varken PREROUTING-regeln eller vidarebefordringspolicyn. Därför kan ett lokalt test lyckas medan varje klient misslyckas, och det omvända är lika vanligt.
Inget här täcker DNS över HTTPS på port 443 eller DNS över TLS på port 853, och inget täcker IPv6. En klient med konfigurerad IPv6-resolver ignorerar gärna hela arrangemanget.
Vad en färsk fråga bevisar
Anslutningsspårning kommer ihåg tidigare mappningar, så en fråga som skickats före en regeländring kan besvaras från det gamla tillståndet och få den nya regeln att se trasig ut. Börja med en ny källport och, där klienten cachar svar, med ett nytt namn.
dig @10.77.0.1 example.com A +short
conntrack -L -p udp --dport 53 | head
Det första kommandot visar om klientvägen alls löses upp, och det andra visar den översättning som gatewayen faktiskt installerade, inklusive båda riktningarna av tuple. En mappning som pekar på rätt resolver med en svarsräknare fastlåst på noll är ett problem med returvägen och inte med filtreringen.
Bekräfta att resolvern känner till namnen du förväntar dig innan du omdirigerar något. En ersättare som svarar på offentliga namn men inte på din privata zon förvandlar en fungerande sökning till ett NXDOMAIN som ser ut som en trasig tunnel. Testa resolvern direkt, från gatewayen, innan klientvägen är inblandad. Och referensen för iptables-tillägg dokumenterar den DNAT- och masquerade-semantik som dessa regler bygger på.