Kannettavasi on VPN:ssä, dig service.internal.example vastaa 10.x-osoitteella ja curl päättyy yhä Could not resolve host. Tunneli ei ole ongelma: se kuljetti dig-kyselyn valittamatta. Ero on siinä, kuka kysymyksen esittää. dig lähettää yhden kyselyn yhdelle itse nimeämällesi palvelimelle, kun taas curl kulkee käyttöjärjestelmän hakuketjun läpi, ja tuolla ketjulla on omat sääntönsä siitä, miltä palvelimelta kysytään.

Kaksi hakua samalle nimelle

dig on oma stub-resolverinsa. Se lukee /etc/resolv.conf-tiedoston, valitsee nimipalvelimen, lähettää yhden A- tai AAAA-kyselyn ja tulostaa vastauksen. Se ohittaa nsswitchin kokonaan eikä tiedä mitään siitä linkkikohtaisesta tilasta, jota systemd-resolved tai NetworkManager pitävät kyseisen tiedoston ulkopuolella, ja siksi dig-vastaus voi olla oikea ja silti kertoa sinulle mitään siitä, mitä sovelluksesi näkee.

Sovellukset kutsuvat getaddrinfoa, ja getaddrinfo kulkee pidemmän ketjun: nsswitchin moduulijärjestys, sitten nimen käsittelevä moduuli ja lopuksi nykyisestä linkkikonfiguraatiosta rakennettu resolver. systemd-koneella kysely menee 127.0.0.53:lle ja systemd-resolved valitsee linkkikohtaisen ylävirran palvelimen tun-rajapintaan liitetyn reititystoimialueen perusteella.

Kaksi komentoa erottavat nämä kerrokset arvaamatta:

getent ahosts service.internal.example
resolvectl query service.internal.example

getent käyttää samaa polkua kuin curl, joten getent-virhe toimivan digin rinnalla paikantaa vian hakukäytäntöön eikä pakettireititykseen. resolvectl query tulostaa myös rajapinnan ja ylävirran, joka vastauksen antoi, mikä näyttää, voittiko ratkaisun tunnelilinkki vai fyysinen linkki.

Lue resolveri, jota sovellus todella käyttää

/etc/resolv.conf luodaan useimmilla työpöydillä, ja VPN-asiakkaalla on kolme tapaa käsitellä sitä: lisätä nimipalvelin eteen, korvata tiedosto tai antaa palvelimensa NetworkManagerille ja antaa daemonin kirjoittaa se uudelleen. Vain kolmas malli säilyttää linkkikohtaisen DNS:n, koska palvelimet pysyvät rajapintaan kiinnitettyinä sen sijaan, että ne litistettäisiin yhdeksi globaaliksi listaksi.

NetworkManager-järjestelmissä tulos riippuu /etc/NetworkManager/NetworkManager.conf-tiedoston backendistä:

[main]
dns=systemd-resolved

Asetuksella dns=default asiakkaan palvelimet sulautetaan resolv.conf-tiedostoon voittavassa järjestyksessä, ja yksityinen haku voi silti päätyä julkiselle resolverille. Linkit ymmärtävällä backendillä, systemd-resolved tai dnsmasq, tunnelin palvelimet pysyvät tunneliin rajattuina ja vain sen reititystoimialueeseen sopivat nimet menevät sinne. Tämä rajaus on se, mitä split DNS käytännössä tarkoittaa, ja se on osa, joka useimmin puuttuu, kun asiakas väittää tukevansa sitä.

Lue tila ennen kuin muutat mitään:

resolvectl status
resolvectl dns tun0

Haluat nähdä tun-rajapinnan listattuna DNS-palvelimella ja yksityisen suffiksin reititystoimialueella, näytettynä muodossa ~internal.example. Ei palvelinta linkillä tarkoittaa, ettei asiakas työntänyt mitään. Palvelin ilman toimialuetta tarkoittaa, että haut menevät joko kaikki sinne tai ei yhtään, asiakkaasta riippuen, eikä kumpikaan ole split DNS.

Missä nsswitch lopettaa haun liian aikaisin

Tavallinen työpöytärivi näyttää tältä:

hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns myhostname

mdns4_minimal hoitaa multicast-DNS:n ja vaatii jokaisen .local-loppuisen nimen. Kubernetes-palvelu kuten api.infra.svc.cluster.local päättyy myös .localiin. Kun mDNS-moduuli raportoi NOTFOUND, toiminto [NOTFOUND=return] lopettaa koko haun sen sijaan, että jatkaisi dns-moduuliin, joten nimeä ei koskaan lähetetä VPN:n resolverille. dig ohittaa tiedoston kokonaan, ja juuri siksi kaksi työkalua ovat eri mieltä.

Tämä on tämän ongelman terävin vastakohta, ja se tiivistyy yhteen sanaan konfiguraatiotiedostossa, joka on vanhempi kuin VPN:si. Toiminnon muuttaminen muotoon [NOTFOUND=continue] säilyttää mDNS:n tulostimille ja paikallisille laitteille samalla kun DNS voi nähdä nimen. Rivin korvaaminen muodolla hosts: files dns toimii myös ja on karkeampi: se pudottaa .local-ratkaisun siltä tulostimelta, jota todella käytät.

Nimet, jotka elävät täsmälleen yhdessä verkossa

Yksityiset vyöhykkeet ovat valtuutettuja täsmälleen yhdessä paikassa. AWS-nimi kuten ip-10-0-4-31.eu-west-1.compute.internal vastataan kyseisen alueen VPC-resolverin kautta, ja vain niin kauan kuin VPN-päätepisteesi on samalla alueella kuin resurssi. Yhdistä Frankfurtin päätepisteeseen, kysy irlantilaista compute.internal-nimeä, eikä mikään paikallinen asetus auta: tietueen sisältävään vyöhykkeeseen ei pääse sieltä.

Hakutoimialueet tuottavat peilikuvan. Paljas service täydennetään suffiksilla, jota resolver pitää soveltuvana, ja VPN-linkillä paikallinen toimialue voi voittaa yrityksen toimialueen. Kysy loppupisteellä arvailun poistamiseksi, getent ahosts service.internal.example., ja jos se toimii lyhyen nimen epäonnistuessa, korjaus on tunnelin hakutoimialue, ei palvelimen osoite.

Hallinnoidut asiakkaat lisäävät kolmannen kerroksen järjestelmän resolverin päälle. Windows-VPN-profiili voi kantaa oman nimiratkaisukäytäntönsä, sovelluskohtaiset sääntönsä ja NRPT-taulukon, joka on voimassa myös silloin, kun tunneli on alas. Sovellukset, joilla on oma DNS-välimuisti, yleisiä .NET- ja Java-ajoympäristöissä, pitävät vanhentunutta virhettä kauan sen jälkeen, kun ketju on korjattu. Apple-asiakkaat määrittävät split DNS:n DNS-asetusten vastaavuustoimialueilla resolv.confin sijaan, ja Chromium tai Firefox suojatun DNS:n tilassa voivat ohittaa järjestelmän resolverin julkisille nimille. Microsoftin VPN-nimiratkaisun viite kuvaa tämän käytäntökerroksen Windows-puolen.

Päätä, mikä kerros korjata

Etene oireesta kerrokseen sen sijaan, että kokeilisit korjauksia järjestyksessä:

SymptomWhat it meansCheck first
dig answers, getent failslookup chain, not the packet pathnsswitch line and resolvectl status
Timeout rather than NXDOMAINprivate resolver unreachable through the tunnelresolvectl dns tun0, route to that address
NXDOMAINan authority answered and does not know the namezone owner, endpoint region
FQDN works, short name failssearch suffix mismatchresolvectl domain on the tun link
getent works, app failsapp cache or its own resolverrestart the app, check secure DNS

Kaksi riviä kantaa suurimman osan painosta. Aikakatkaisu on tavoitettavuusongelma: yksityinen resolver ei vastaa tunnelin kautta, joten tarkista reitti sen osoitteeseen ja se, onko linkin DNS-palvelin se, mitä luulet. NXDOMAIN on valtuusongelma: jokin vastasi eikä tunne nimeä, mikä viittaa vyöhykkeeseen, alueeseen tai resolveriin, jonka ei koskaan pitänyt saada kyselyä.

Viimeinen rivi on se, jonka ihmiset ohittavat, koska molemmat puolet näyttävät menestykseltä. Lyhyt nimi, joka ratkeaa eri tavalla kuin FQDN, on suffiksin epäsopivuus, eikä tunnelin uudelleenyhdistäminen muuta sitä, minkä suffiksin asiakas lähettää.

Tallenna tila ennen kuin muokkaat konfiguraatiotiedostoa, jotta voit sanoa, tekikö muokkaus mitään:

resolvectl status > before.txt
getent ahosts service.internal.example >> before.txt

Suorita tarkistukset tässä järjestyksessä ja pysähdy ensimmäiseen, joka epäonnistuu. getentin ja resolvectl queryn on oltava samaa mieltä; jos getent epäonnistuu digin vastatessa, pysy hakuketjussa äläkä koske reititykseen. resolvectl statusin on näytettävä DNS-palvelin ja reititystoimialue tun-rajapinnalla. nsswitch ei saa palata aikaisin NOTFOUNDilla testattavalle suffiksille. Nimen on oltava valtuutettu verkossa, johon päätepisteesi on liitetty, testattuna loppupisteellä. Sovellus ei saa pitää omaa välimuistiaan tai suojatun DNS:n ohitusta.

Korjaa vain ensimmäinen epäonnistuva kerros ja suorita sitten samat komennot uudelleen. Kaksi muutosta kerralla jättää sinut sanomaan, mikä niistä merkitsi, ja seuraava katkos aloittaa tutkinnan nollasta.

Aiheeseen liittyvät artikkelit