Ձեր նոթբուքը VPN-ում է, dig service.internal.example-ը պատասխանում է 10.x հասցեով, և curl-ը դեռ ավարտվում է Could not resolve host-ով։ Թունելը խնդիրը չէ. այն փոխանցեց dig հարցումը առանց բողոքի։ Տարբերությունը նրանում է, թե ով է տալիս հարցը։ dig-ը մեկ հարցում է ուղարկում ձեր նշած մեկ սերվերին, մինչդեռ curl-ը անցնում է օպերացիոն համակարգի որոնման շղթայով, և այդ շղթան ունի իր կանոնները, թե որ սերվերին է հարցվում։

Երկու որոնում նույն անվան համար

dig-ը սեփական stub resolver է։ Այն կարդում է /etc/resolv.conf-ը, ընտրում անվանասերվեր, ուղարկում է մեկ A կամ AAAA հարցում և տպում պատասխանը։ Այն ամբողջությամբ բաց է թողնում nsswitch-ը և ոչինչ չգիտի կապի մակարդակի այն վիճակի մասին, որը systemd-resolved-ը կամ NetworkManager-ը պահում են այդ ֆայլից դուրս, և դրա համար է, որ dig-ի պատասխանը կարող է ճիշտ լինել և միևնույն ժամանակ ոչինչ չասել այն մասին, ինչ կտեսնի ձեր ծրագիրը։

Ծրագրերը կանչում են getaddrinfo, և getaddrinfo-ն անցնում է ավելի երկար շղթայով. nsswitch-ի մոդուլների հերթականությունը, ապա այն մոդուլը, որը մշակում է անունը, և վերջում ընթացիկ կապի կոնֆիգուրացիայից կառուցված resolver-ը։ systemd մեքենայում հարցումը գնում է 127.0.0.53-ին, և systemd-resolved-ը tun ինտերֆեյսին կցված երթուղային դոմենի հիման վրա յուրաքանչյուր կապի համար ընտրում է վերին սերվեր։

Երկու հրաման բաժանում են այդ շերտերը առանց գուշակելու.

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

getent-ը օգտագործում է նույն ուղին, ինչ curl-ը, ուստի աշխատող dig-ի կողքին getent-ի ձախողումը թերությունը տեղորոշում է որոնման քաղաքականության մեջ, ոչ թե փաթեթների երթուղավորման մեջ։ resolvectl query-ն նաև տպում է ինտերֆեյսը և այն վերին սերվերը, որը տվել է պատասխանը, ինչը ցույց է տալիս՝ արդյոք որոշումը հաղթել է թունելի կապը, թե ֆիզիկական կապը։

Կարդացեք այն resolver-ը, որն իրականում օգտագործում է ծրագիրը

/etc/resolv.conf-ը գեներացվում է աշխատասեղանների մեծ մասում, և VPN հաճախորդն ունի դրա հետ փոխազդելու երեք եղանակ. անվանասերվեր ավելացնել սկզբում, վերագրել ֆայլը կամ իր սերվերները տալ NetworkManager-ին և թույլ տալ դեմոնին վերագրել այն։ Միայն երրորդ ձևն է պահպանում կապի մակարդակի DNS-ը, որովհետև սերվերները մնում են կցված ինտերֆեյսին՝ մեկ գլոբալ ցանկի մեջ հարթեցվելու փոխարեն։

NetworkManager համակարգերում արդյունքը կախված է /etc/NetworkManager/NetworkManager.conf-ի backend-ից.

[main]
dns=systemd-resolved

dns=default-ի դեպքում հաճախորդի սերվերները միաձուլվում են resolv.conf-ում հաղթող հերթականությամբ, և մասնավոր հարցումը դեռ կարող է ուղարկվել հանրային resolver-ին։ Կապերը հասկացող backend-ի դեպքում, systemd-resolved կամ dnsmasq, թունելի սերվերները մնում են սահմանափակված թունելով, և այնտեղ գնում են միայն նրա երթուղային դոմենին համապատասխան անունները։ Այդ սահմանափակումն է, ինչ split DNS-ը նշանակում է գործնականում, և հենց այն է, որ ամենից հաճախ բացակայում է, երբ հաճախորդը պնդում է, թե աջակցում է դրան։

Կարդացեք վիճակը, նախքան որևէ բան փոխելը.

resolvectl status
resolvectl dns tun0

Դուք ուզում եք տեսնել tun ինտերֆեյսը թվարկված DNS սերվերով և մասնավոր վերջածանցի երթուղային դոմենով՝ ցուցադրված որպես ~internal.example։ Կապի վրա սերվերի բացակայությունը նշանակում է, որ հաճախորդը ոչինչ չի ուղարկել։ Առանց դոմեն սերվերը նշանակում է, որ հարցումները կա՛մ բոլորը գնում են այնտեղ, կա՛մ ոչ մեկը՝ կախված հաճախորդից, և ոչ մեկը split DNS չէ։

Որտեղ nsswitch-ը վաղ է ավարտում որոնումը

Սովորական աշխատասեղանի տողը այսպիսի տեսք ունի.

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

mdns4_minimal-ը զբաղվում է multicast DNS-ով և հավակնում է .local-ով ավարտվող ցանկացած անվան։ api.infra.svc.cluster.local-ի նման Kubernetes ծառայությունը նույնպես ավարտվում է .local-ով։ Երբ mDNS մոդուլը հաղորդում է NOTFOUND, [NOTFOUND=return] գործողությունը ավարտում է ամբողջ որոնումը՝ dns մոդուլին անցնելու փոխարեն, ուստի անունը երբեք չի ուղարկվում VPN resolver-ին։ dig-ը ամբողջությամբ շրջանցում է ֆայլը, և հենց դրա համար է, որ երկու գործիքները համաձայն չեն։

Սա այս խնդրի ամենասուր հակադրությունն է, և այն հանգում է մեկ բառի VPN-իցդ հին կոնֆիգուրացիոն ֆայլում։ Գործողությունը [NOTFOUND=continue]-ի փոխելը պահպանում է mDNS-ը տպիչների և տեղական սարքերի համար, միաժամանակ թույլ տալով DNS-ին տեսնել անունը։ Տողը hosts: files dns-ով փոխարինելը նույնպես աշխատում է և ավելի կոպիտ է. այն հանում է .local լուծումը այն տպիչի համար, որն իրականում օգտագործում եք։

Անուններ, որոնք ապրում են ուղիղ մեկ ցանցում

Մասնավոր զոնաները հեղինակավոր են ուղիղ մեկ տեղում։ ip-10-0-4-31.eu-west-1.compute.internal-ի նման AWS անունը պատասխանվում է այդ տարածաշրջանի VPC resolver-ով, և միայն այնքան ժամանակ, քանի դեռ ձեր VPN վերջնակետը նույն տարածաշրջանում է, ինչ ռեսուրսը։ Միացեք Ֆրանկֆուրտի վերջնակետին, հարցրեք Իռլանդիայի compute.internal անունը, և ոչ մի տեղական կարգավորում չի օգնի. գրառումը պահող զոնան այնտեղից հասանելի չէ։

Որոնման դոմենները ստեղծում են հայելային պատկերը։ Մերկ service-ը լրացվում է այն վերջածանցով, որը resolver-ը համարում է կիրառելի, և VPN կապի դեպքում տեղական դոմենը կարող է հաղթել կորպորատիվին։ Հարցրեք վերջում կետով՝ գուշակությունը վերացնելու համար, getent ahosts service.internal.example., և եթե դա աշխատում է, մինչ կարճ անունը ձախողվում է, ուղղումը թունելի որոնման դոմենն է, ոչ թե սերվերի հասցեն։

Կառավարվող հաճախորդները երրորդ շերտ են ավելացնում համակարգի resolver-ի վրա։ Windows VPN պրոֆիլը կարող է կրել իր անվանալուծման քաղաքականությունը, յուրաքանչյուր ծրագրի կանոններ և NRPT աղյուսակ, որն ուժի մեջ է նույնիսկ թունելն անջատված լինելու դեպքում։ Սեփական DNS քեշ ունեցող ծրագրերը, որոնք սովորական են .NET և Java միջավայրերում, երկար պահում են հնացած ձախողումը շղթան ուղղելուց հետո։ Apple-ի հաճախորդները split DNS-ը կարգավորում են DNS կարգավորումների համապատասխան դոմեններով, ոչ թե resolv.conf-ով, իսկ Chromium-ը կամ Firefox-ը անվտանգ DNS ռեժիմում կարող են շրջանցել համակարգի resolver-ը հանրային անունների համար։ Microsoft-ի VPN անվանալուծման տեղեկագիրը նկարագրում է այդ քաղաքականության շերտի Windows կողմը։

Որոշեք, թե որ շերտն ուղղել

Աշխատեք ախտանիշից դեպի շերտը՝ ուղղումները հերթով փորձելու փոխարեն.

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

Երկու տող են կրում հիմնական ծանրությունը։ Ժամանակի սպառումը հասանելիության խնդիր է. մասնավոր resolver-ը չի պատասխանում թունելով, ուստի ստուգեք դեպի նրա հասցեն տանող ուղին և արդյոք կապի DNS սերվերը ձեր մտքում եղածն է։ NXDOMAIN-ը հեղինակության խնդիր է. ինչ-որ բան պատասխանել է և չգիտի անունը, ինչը մատնանշում է զոնան, տարածաշրջանը կամ resolver, որը երբեք չպետք է ստանար հարցումը։

Վերջին տողն այն է, որ մարդիկ բաց են թողնում, որովհետև երկու կեսերն էլ հաջողություն են թվում։ FQDN-ից տարբեր լուծվող կարճ անունը վերջածանցի անհամապատասխանություն է, և թունելի վերակապակցումը չի փոխի, թե ինչ վերջածանց է ուղարկում հաճախորդը։

Գրանցեք վիճակը, նախքան կոնֆիգուրացիոն ֆայլ խմբագրելը, որպեսզի կարողանաք ասել՝ խմբագրումը որևէ բան արեց թե ոչ.

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

Կատարեք ստուգումները այս հերթականությամբ և կանգ առեք առաջին ձախողվածի վրա։ getent-ը և resolvectl query-ն պետք է համընկնեն. եթե getent-ը ձախողվում է, մինչ dig-ը պատասխանում է, մնացեք որոնման շղթայում և չհպեք երթուղավորմանը։ resolvectl status-ը պետք է ցույց տա DNS սերվեր և երթուղային դոմեն tun ինտերֆեյսի վրա։ nsswitch-ը չպետք է շուտ վերադառնա NOTFOUND-ով փորձարկվող վերջածանցի համար։ Անունը պետք է հեղինակավոր լինի այն ցանցում, որին կցված է ձեր վերջնակետը, ստուգված վերջում կետով։ Ծրագիրը չպետք է պահի սեփական քեշ կամ անվտանգ DNS-ի վերագրանցում։

Ուղղեք միայն առաջին ձախողված շերտը, ապա նորից կատարեք նույն հրամանները։ Միաժամանակ երկու փոփոխությունը թույլ չի տալիս ասել, թե որն էր կարևոր, և հաջորդ խափանումը հետաքննությունը սկսում է զրոյից։

Առնչվող հոդվածներ