Varför resolv.conf visar din VPN-DNS men uppslag ignorerar den
På en värd med resolved är filen en vy, inte tillståndet. Följ stubben, servrarna per länk och nsswitch-raden för att se vilken ett uppslag faktiskt använder.
Ingenting i loggarna ser fel ut: gränssnittet är uppe, resolvern rapporterar VPN:ens DNS-server och filen på disken listar den. Ändå slås ett internt värdnamn fortfarande upp via den lokala routern. De tre påståendena motsäger inte varandra, eftersom filen, tillståndet per länk och uppslagets väg är olika objekt som råkar dela ett namn. Följande är den väg en fråga faktiskt tar på en värd med systemd-resolved.
Tre objekt som kallas resolv.conf
På en värd med resolved är /etc/resolv.conf vanligtvis en symbolisk länk till /run/systemd/resolve/stub-resolv.conf. Det målet innehåller adressen till en lokal stub-lyssnare, 127.0.0.53, plus de sökdomäner som resolved beräknat. Det är en vy av tillståndet, inte tillståndet självt.
Tillståndet lever i resolveds konfiguration per länk, och därför kan resolvectl status vara oense med filen och ändå ha rätt. Varje länk bär sina egna servrar och sina egna routingdomäner, och stubben konsulterar dessa data när en fråga kommer in. Handboken för systemd-resolved beskriver de genererade filerna och modellen per länk; uppdelningen mellan vy och tillstånd är den del som är värd att minnas. Att ändra den symboliska länkens mål ändrar vad traditionella klienter läser, inte vad resolvern vet.
Ett tredje objekt, /run/systemd/resolve/resolv.conf, plattar ut varje länk till en enda serverlista. Ett program som pekar på den filen skickar frågor direkt till de listade servrarna och hoppar över stubben, så policyn per länk gäller inte längre för det. Därför kan två program på samma maskin svara olika på samma namn, och ingen av dem är trasig.
Följ ett uppslag genom NSS
glibc läser /etc/nsswitch.conf för att avgöra vem som svarar på ett namn. En hosts-rad med resolve skickar frågan till nss-resolve, som frågar resolved via D-Bus och får svaret per länk. En rad med bara files dns skickar frågan till adressen som /etc/resolv.conf har.
Den enda raden förklarar de flesta meningsskiljaktigheter mellan en webbläsare och dig. dig läser resolv.conf direkt och rör aldrig NSS, så den testar stubben eller en uppströms server i stället för vägen programmet använder. getent hosts internal.example går genom NSS, och att jämföra dess svar med dig:s är den första användbara mätningen.
Program som har en egen resolver inbyggd, eller talar DNS över HTTPS med en fast slutpunkt, kringgår båda vägarna. Ingenting i resolv.conf eller i resolved-tillståndet begränsar dem.
Kontrollera vem som äger filen och vart den pekar
Läs länkkedjan innan du ändrar något, eftersom ägandet avgör vilken fil som är auktoritativ. Varje kommando nedan läser bara tillstånd.
stat -c '%N' /etc/resolv.conf
resolvectl status --no-pager
grep '^hosts' /etc/nsswitch.conf
ls -l /run/systemd/resolve/
Den första raden skriver ut länken och dess mål tillsammans, och en vanlig fil som ägs av ett VPN-skript betyder att resolvern aldrig behandlar den skrivningen som indata. Statusutdata listar servrar per länk plus de routingdomäner som avgör vart varje fråga tar vägen. nsswitch-raden säger om stubben alls konsulteras, så en stub-adress i filen utan resolve där betyder att frågorna når den lokala lyssnaren medan ingenting hanterar delningen. Den sista listan spelar också roll, eftersom en värd utan stub-resolv.conf inte kör arrangemanget som beskrivs här.
Om kedjan slutar i en fil som ett annat paket hanterar, är VPN-klienten och det paketet de två ägarna som måste förenas. Att ersätta länken kastar den ena ägarens arbete och låter den andras ligga kvar.
Reparera hos länkens ägare
En VPN-anslutning bör registrera sina servrar och sina domäner på sin egen länk och sedan dra tillbaka dem vid frånkoppling. NetworkManagers resolved-integration och en klients egen hjälpare fungerar båda så; ett skript som bara skriver om resolv.conf gör det inte.
På en länk som redan finns visar körtidsinställningarna mekanismen. resolvectl dns tun0 10.40.0.53 kopplar en server, och resolvectl domain tun0 '~corp.example' kopplar en routingdomän. Tilden är det bärande tecknet: den begränsar frågor för det suffixet till den här länken och lämnar allt annat i fred, medan samma värde utan den blir en sökdomän och delningen förångas. Adresserna är laboratorieexempel, inte en bestående konfiguration. Bekräfta med resolvectl query host.corp.example och läs vilken länk som svarade.
En registrerad server behöver fortfarande en rutt. När frågan når rätt länk och sedan tar timeout ligger felet i nåbarheten genom tunneln och inte i resolverns ägande.
Hur ett fungerande tillstånd ser ut
Ett friskt resultat är konsekvent i alla tre vyerna: servrarna per länk matchar det VPN:en delade ut, routingdomänerna täcker bara interna suffix, och programmet som spelar roll slår upp ett internt namn medan ett publikt namn fortfarande följer den lokala vägen. Ett lyckat uppslag bevisar mindre än den överensstämmelsen.
Koppla sedan från och upprepa båda uppslagen. En klient som låter sina domäner vara registrerade efter nedmonteringen ger en maskin som misslyckas med interna uppslag timmar senare, utan öppen tunnel och utan uppenbar orsak.