AdGuard Home svarar WireGuard-klienter från din LAN-adress
En 0.0.0.0-bindning låter kärnan välja svarskällan. På en multi-homed värd kan det svaret komma från en adress som tunneln inte kan nå.
Tunneln är uppe, brandväggen tillåter port 53, AdGuard Home körs, och namn löser fortfarande inte för WireGuard-klienten. Förfrågan kommer normalt fram och ett svar går normalt ut, så paketräknare på resolvern ser friska ut och tjänsten verkar oskyldig. Det som går fel är källadressen på det svaret: det lämnar från en lokal adress som klienten aldrig efterfrågade, och klientens stub-resolver kastar bort det. En lista i AdGuard Homes konfiguration avgör detta, och dess vanliga standard överlämnar beslutet till kärnan.
Förfrågan kommer fram, svaret går ut från någon annanstans
En klient konfigurerad med 10.6.0.1 som sin resolver skickar en UDP-förfrågan till 10.6.0.1 port 53. Det paketet passerar tunneln och landar på värden, och AdGuard Home svarar på det. På ledningen är svaret dock ett nytt paket vars källadress väljs av värdens stack, inte av klientens förväntan.
När klientens resolver är en ansluten socket, vilket är vad systemd-resolved, dnsmasq och de flesta stub-resolvers använder, accepterar den bara svar från den exakta adressen den skickade till. Ett svar med källan 192.168.1.10 till en förfrågan skickad till 10.6.0.1 släpps innan någon bearbetning sker. Resolvern loggar ett lyckat svar, klienten loggar en timeout, och båda talar sanning.
Så räknarna ljuger inte och det gör inte klienten heller. Beviset du behöver finns på tre ställen, i denna ordning: adressen som lyssnaren är bunden till, den rutt som kärnan skulle använda tillbaka till klienten, och källadressen på själva svarspaketet.
Hur kärnan väljer svarskällan
En UDP-socket bunden till0.0.0.0har ingen egen källadress, så varje utgående svar utlöser en ruttuppslagning för destinationen. Kärnan tar sedan källan från den rutten: adressen som är fastställd av rutten, eller den primära adressen på det utgående gränssnittet. Ingenting om frågans destinationsadress kommer ihåg.
På en enkelvärd är detta osynligt, eftersom det bara finns ett rimligt svar. På en maskin som har en LAN-adress, en WireGuard-adress och en administrationsadress är flera svar rimliga, och vinnaren beror på routningstabellen vid det ögonblicket. Lägg till en extra rutt, en andra adress på samma gränssnitt, en NAT-omdirigering framför resolvern, eller kör AdGuard i en container med sitt eget namnrymd, och den valda källan kan skilja sig från den som klienten frågade.
ss -lunp | grep :53visar vilket spel du är i. En lyssnare på0.0.0.0:53är wildcard-fallet; en lyssnare på10.6.0.1:53har redan fastställt svaret. Att läsa socketen är snabbare än att läsa YAML, och det speglar vad som faktiskt körs snarare än vad som senast sparades.
Vad bind_hosts faktiskt styr
AdGuard Home:sdns.bind_hostsär listan över lokala adresser som DNS-lyssnaren använder. Standardinställningen som skickas med är jokertecknet, vilket betyder att alla lokala adresser accepteras och låter kärnan välja källan för varje svar. Att ersätta jokertecknet med den adress som klienterna frågar på ändrar sockeln, och med den även källadressen på varje svar.
Listan kan innehålla mer än en post, vilket är viktigt på en resolver som tjänar två nätverk. Att lista10.6.0.1och192.168.1.10ger två bundna socklar, och en fråga som anländer till någon av dem besvaras från den adress den anlände på. Det är beteendet som de flesta antar att jokertecknet redan ger.
YAML-filen är enkel, och adressen i den är den som dina tunnelklienter blev tillsagda att använda, inte värdens primära adress:
dns:
bind_hosts:
- 10.6.0.1
port: 53Varför två installationer av en resolver inte håller med varandra
Plugin-hanterad, i detta sammanhang, betyder att resolvern installerades och övervakas av ett annat paket: ett routerfirmwarepaket, ett NAS-paket eller ett tillägg för hemautomation. Det paketet levererar vanligtvis sin egen kopia av AdGuard Homes YAML och startar om processen enligt sin egen schema, medan en fristående instans är leverantörens binärfil eller container som du själv konfigurerar. Hur som helst tittar du på två oberoende processer med separata konfigurationsfiler och separata bindningsval, även när båda läser samma uppströmslista och samma filterlistor. Den ena kan binda den specifika tunneladressen medan den andra ärver jokertecknet, och webbgränssnittet ser identiskt ut från båda sidor.
Det är därför "samma resolver fungerade före migreringen" inte bevisar någonting om den nuvarande bindningen. Kontrollera sockeln, och sedan konfigurationsfilen som den körande processen faktiskt laddade. En gammal kopia i en annan katalog är en vanlig anledning till att ändringen verkar ha ingen effekt.
Fäst den, och testa sedan från tunnelsidan
Bytbind_hostsmot tunneladressen, starta om tjänsten och bekräfta att sockeln flyttades:ss -lunp | grep :53bör nu visa10.6.0.1:53och ingen wildcard-post. Om det fortfarande visar0.0.0.0,läser den körande processen inte filen du redigerade.
Testa sedan från klienten, eftersom det är den enda sidan som spelar roll. En fråga meddig @10.6.0.1 example.comanvänder den väg som användaren använder, och en fångst på värden medtcpdump -ni wg0 udp port 53visar svarens källadress på nätet. Jämför den med adressen i klientens resolver-inställning; när de är lika slutar timeouten vara ett mysterium.
ip route get 10.6.0.2förklarar eventuella återstående udda beteenden, eftersom den skriver ut gränssnittet och källan som värden skulle använda tillbaka till klienten. Om den utdata namnger LAN-gränssnittet, är bindändringen inte hela lösningen och rutttabellen är nästa sak att läsa.
Vad bind-inställningen inte kan fixa
Att fästa lyssnaren reparerar inte en åtkomstlista som utelämnar tunnelns subnet, en brandväggsregel som tillåter frågan men inte svaret, eller en saknad rutt tillbaka till WireGuard-poolen. Dessa misslyckas tidigare eller senare än källadressen, och varje har en annan ägare.
Det ändrar inte hellervilken uppströms resolvern skickar vidare till, huruvida skydd mot ombindning avvisar ett privat svar för ett privat namn, eller hur klienten tillämpar sina egna sökdomäner. Det är separata kontroller. Ändra bind-adressen när svarskällan är fel, och ändra något annat när den inte är det.