Waarom interne gasheername wel in dig oplos, maar in curl misluk op ’n VPN
dig antwoord, maar curl rapporteer dat dit die gasheer nie kan oplos nie. Vergelyk die twee opsoekkettings en maak dan nsswitch, DNS per skakel of ’n verkeerde soekagtervoegsel reg.
Jou skootrekenaar is op die VPN, dig service.internal.example antwoord met ’n 10.x-adres, en curl stop steeds met Could not resolve host. Die tonnel is nie die probleem nie: dit het die dig-navraag sonder klagte vervoer. Wat verskil, is wie die vraag stel. dig stuur een navraag na een bediener wat jy noem, terwyl curl deur die bedryfstelsel se opsoekketting gaan, en daardie ketting het sy eie reëls oor watter bediener gevra word.
Twee opsoeke vir dieselfde naam
dig is sy eie stub-resolver. Dit lees /etc/resolv.conf, kies ’n naamdiener, stuur ’n enkele A- of AAAA-navraag en druk die antwoord. Dit slaan nsswitch heeltemal oor en weet niks van die per-skakel-toestand wat systemd-resolved of NetworkManager buite daardie lêer hou nie, en daarom kan ’n dig-antwoord korrek wees en jou steeds niks vertel oor wat jou toepassing sal sien nie.
Toepassings roep getaddrinfo, en getaddrinfo volg ’n langer ketting: die modulevolgorde van nsswitch, dan die module wat die naam hanteer, en dan die resolver wat uit die huidige skakelkonfigurasie gebou is. Op ’n systemd-masjien gaan die navraag na 127.0.0.53 en kies systemd-resolved ’n opstroom-bediener per skakel op grond van die roeteringdomein wat aan die tun-koppelvlak geheg is.
Twee opdragte skei daardie lae sonder om te raai:
getent ahosts service.internal.example
resolvectl query service.internal.example
getent gebruik dieselfde pad as curl, so ’n getent-fout langs ’n werkende dig plaas die fout by die opsoekbeleid eerder as by die paketroetering. resolvectl query druk ook die koppelvlak en die opstroom wat die antwoord gegee het, wat wys of die tonnelskakel of die fisiese skakel die besluit gewen het.
Lees die resolver wat die toepassing werklik gebruik
/etc/resolv.conf word op die meeste skootrekenaars gegenereer, en ’n VPN-kliënt het drie maniere om daarmee te werk: ’n naamdiener vooraan plaas, die lêer oorskryf, of sy bedieners aan NetworkManager gee en die daemon dit laat herskryf. Net die derde patroon behou DNS per skakel, want die bedieners bly aan ’n koppelvlak geheg in plaas daarvan om in een globale lys platgeslaan te word.
Op NetworkManager-stelsels hang die uitkoms af van die backend in /etc/NetworkManager/NetworkManager.conf:
[main]
dns=systemd-resolved
Met dns=default word die kliënt se bedieners in resolv.conf saamgevoeg in watter orde ook al wen, en ’n private opsoek kan steeds na die publieke resolver gestuur word. Met ’n backend wat skakels verstaan, systemd-resolved of dnsmasq, bly die tonnel se bedieners tot die tonnel beperk en gaan net name wat by sy roeteringdomein pas daarheen. Daardie beperking is wat split DNS in die praktyk beteken, en dit is die stuk wat die meeste ontbreek wanneer ’n kliënt beweer dat hy dit ondersteun.
Lees die toestand voordat jy iets wysig:
resolvectl status
resolvectl dns tun0
Jy wil die tun-koppelvlak gelys sien met ’n DNS-bediener en ’n roeteringdomein vir die private agtervoegsel, vertoon as ~internal.example. Geen bediener op die skakel beteken die kliënt het niks gestuur nie. ’n Bediener sonder domein beteken opsoeke gaan óf almal daarheen óf glad nie, afhangend van die kliënt, en nie een van die twee is split DNS nie.
Waar nsswitch die opsoek vroeg beëindig
’n Standaardlyn op ’n skootrekenaar lyk so:
hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns myhostname
mdns4_minimal hanteer multicast-DNS en maak aanspraak op elke naam wat op .local eindig. ’n Kubernetes-diens soos api.infra.svc.cluster.local eindig ook op .local. Wanneer die mDNS-module NOTFOUND rapporteer, beëindig die aksie [NOTFOUND=return] die hele opsoek in plaas daarvan om na die dns-module voort te gaan, so die naam word nooit na die VPN-resolver gestuur nie. dig omseil die lêer heeltemal, en dit is presies waarom die twee gereedskap dit nie eens is nie.
Dit is die skerpste kontras in hierdie probleem, en dit kom neer op een woord in ’n konfigurasielêer wat ouer as jou VPN is. Om die aksie na [NOTFOUND=continue] te verander, behou mDNS vir drukkers en plaaslike toestelle terwyl DNS die naam kan sien. Om die lyn deur hosts: files dns te vervang werk ook en is growwer: dit laat vaar die .local-resolusie vir die drukker wat jy werklik gebruik.
Name wat in presies een netwerk woon
Private sones is op presies een plek gesaghebbend. ’n AWS-naam soos ip-10-0-4-31.eu-west-1.compute.internal word deur daardie streek se VPC-resolver beantwoord, en net solank jou VPN-eindpunt in dieselfde streek as die hulpbron is. Koppel aan ’n eindpunt in Frankfurt, soek ’n compute.internal-naam uit Ierland op, en geen plaaslike instelling sal help nie: die sone wat die rekord hou, is daarvandaan onbereikbaar.
Soekdomeine lewer die spieëlbeeld. ’n Kaal service word aangevul met die agtervoegsel wat die resolver van toepassing ag, en met ’n VPN-skakel kan die plaaslike domein die korporatiewe een wen. Soek met ’n punt aan die einde om die raaiwerk te verwyder, getent ahosts service.internal.example., en as dit werk terwyl die kort naam misluk, is die regstelling die soekdomein op die tonnel, nie die bedieneradres nie.
Bestuurde kliënte voeg ’n derde laag bo die bedryfstelsel se resolver by. ’n Windows-VPN-profiel kan sy eie naamresolusiebeleid, reëls per toepassing en ’n NRPT-tabel dra wat geld selfs wanneer die tonnel af is. Toepassings met hul eie DNS-kas, algemeen in .NET- en Java-runtimes, hou ’n verouderde fout lank nadat die ketting reggemaak is. Apple-kliënte stel split DNS op via pasdomeine in die DNS-instellings eerder as via resolv.conf, en Chromium of Firefox in secure-DNS-modus kan die stelselresolver vir publieke name omseil. Microsoft se naslaanwerk oor VPN-naamresolusie beskryf die Windows-kant van daardie beleidslaag.
Besluit watter laag om reg te maak
Werk van die simptoom na die laag eerder as om regstellings in volgorde te probeer:
| Symptom | What it means | Check first |
|---|---|---|
| dig answers, getent fails | lookup chain, not the packet path | nsswitch line and resolvectl status |
| Timeout rather than NXDOMAIN | private resolver unreachable through the tunnel | resolvectl dns tun0, route to that address |
| NXDOMAIN | an authority answered and does not know the name | zone owner, endpoint region |
| FQDN works, short name fails | search suffix mismatch | resolvectl domain on the tun link |
| getent works, app fails | app cache or its own resolver | restart the app, check secure DNS |
Twee rye dra die meeste gewig. ’n Timeout is ’n bereikbaarheidsprobleem: die private resolver antwoord nie deur die tonnel nie, so kyk na die roete na sy adres en of die DNS-bediener op die skakel die een is wat jy dink. NXDOMAIN is ’n gesagsprobleem: iets het geantwoord en ken nie die naam nie, wat op die sone, die streek of ’n resolver wys wat nooit die navraag moes ontvang het nie.
Die laaste ry is die een wat mense mis omdat albei helftes soos sukses lyk. ’n Kort naam wat anders as die FQDN oplos, is ’n agtervoegsel-wanpassing, en om die tonnel weer te koppel sal nie verander watter agtervoegsel die kliënt stuur nie.
Vang die toestand voordat jy ’n konfigurasielêer wysig, sodat jy kan sien of die wysiging iets gedoen het:
resolvectl status > before.txt
getent ahosts service.internal.example >> before.txt
Voer die kontroles in hierdie volgorde uit en stop by die eerste een wat misluk. getent en resolvectl query moet ooreenstem; as getent misluk terwyl dig antwoord, bly in die opsoekketting en laat roetering met rus. resolvectl status moet ’n DNS-bediener en ’n roeteringdomein op die tun-koppelvlak wys. nsswitch mag nie vroeg op NOTFOUND terugkeer vir die agtervoegsel wat jy toets nie. Die naam moet gesaghebbend wees in die netwerk waaraan jou eindpunt geheg is, getoets met ’n punt aan die einde. Die toepassing mag nie sy eie kas of ’n secure-DNS-oorheersing hou nie.
Maak net die eerste laag reg wat misluk en voer dan dieselfde opdragte weer uit. Twee wysigings op ’n slag laat jou nie sê watter een saak gemaak het nie, en die volgende onderbreking begin die ondersoek van nul af.