Как да проверите DNS резолверите, които вашият Mac използва през VPN
scutil --dns отпечатва състоянието на резолвера, което macOS действително е изградил. Свържете всеки блок с интерфейс, задайте заявка за реално име и докажете кой сървър е отговорил.
scutil --dns отпечатва конфигурацията на резолвера, която macOS действително ползва, а не единствения DNS сървър, който сте въвели в панел за настройки. Изходът е по-дълъг, отколкото повечето хора очакват, защото системата пази отделни блокове на резолвера за пътя по подразбиране, за обхванати интерфейси и за пренасочване по конкретни домейни. Блокът в началото на изхода не е непременно този, който отговаря на заявката. Ако частно име се разрешава в офиса и се проваля в момента, в който VPN се вдигне, несъответствието е в правилата за съпоставяне и в маршрутите, не в адреса на сървъра. Прочетете първо реда, после докажете отговора с истинско търсене.
Прочетете реда на блоковете преди адресите
Всеки запис започва с resolver #N и изброява nameserver[0], понякога if_index, ред flags, reach, а когато блокът не е обикновен по подразбиране — domain и списък search domain. Резолвер №1 без домейн е този по подразбиране, който обслужва публични имена. Всичко с Scoped във флаговете е вързано към интерфейса, посочен от if_index, а всичко отбелязано с Supplemental важи само за домейните, изброени под него.
Изборът е съпоставяне на наставка. За име като intranet.corp.example macOS предпочита резолвера, чийто запис domain е най-дългата съвпадаща наставка, така че блок с domain : corp.example побеждава този по подразбиране, дори когато стои далеч долу в изхода. order решава равенствата между домейни с еднаква дължина. Първият поглед рядко се нуждае от повече: целият изход, когато искате да прочетете един блок от начало до край, началните редове, за да научите реда на блоковете, и филтриран преглед, който печата заглавията на блоковете до редовете на полетата. Обхванатите блокове се появяват под собствено заглавие и се четат като продължение на списъка над тях, затова дръжте заглавие в полезрението си, когато цитирате изхода.
scutil --dns
scutil --dns | sed -n '1,45p'
scutil --dns | grep -nE '^resolver #|^DNS configuration'
scutil --dns | grep -nE 'resolver #[0-9]+|if_index|domain|flags|nameserver'
Съпоставете if_index с интерфейса на тунела
Индексът е полезен само ако можете да назовете интерфейса зад него. scutil --nwi изброява мрежовата информация, която системата пази, включително основния интерфейс и достъпността, докато ifconfig -l ви дава имената, където utun0 до utun9 са кандидатите за тунел, които клиентът обикновено създава. Apple използва scutil --dns като свой собствен пример за проверка в ръководството за внедряване, и документира как Network Extension може да насочва избрани домейни към избрани резолвери — точно механизмът, който тези обхванати блокове разкриват.
Проверката, която решава въпроса, е дали резолверът стои на пътя, който тунелът е инсталирал:
scutil --nwi
ifconfig utun4
route -n get 10.20.0.53
netstat -rn | grep -m5 utun
Ако route -n get върне шлюз и интерфейс, които не съвпадат със записа на резолвера, адресът може да е напълно правилен и все пак недостъпен. Разделен тунел, който носи само корпоративните подмрежи, изхвърля заявките към DNS сървър извън тях, а отказът се проявява като изтичане на времето, затова изходът на конфигурацията продължава да изглежда чист.
Питайте системния резолвер, после сървъра
Три инструмента отговарят на три различни въпроса и объркването им поражда повечето грешни заключения в тази област. dscacheutil -q host -a name минава през същия системен резолвер, който ползват обикновените приложения, затова обхванатите и допълнителните блокове важат. dig без аргумент за сървър чете /etc/resolv.conf, което не е източникът на истина за обхванато разрешаване на macOS, и напълно пропуска правилата за отделните домейни. dig @address достига точно до един сървър и не казва нищо за избора.
dscacheutil -q host -a name intranet.corp.example
dig intranet.corp.example
dig @10.20.0.53 intranet.corp.example
nslookup intranet.corp.example
Когато първата команда отговори, а втората върне NXDOMAIN, вие сте намерили разделението, което търсихте, и нищо не е счупено. Когато първата изтече, докато dig @10.20.0.53 отговаря, резолверът работи, но не е достъпен по пътя, който тунелът е избрал, затова следващата стъпка е route -n get, а не промяна на DNS настройките. Пазете частните имена далеч от всичко, което поставяте в билет или споделена бележка.
Какво изходът не може да ви покаже
Няколко слоя стоят над или до списъка с резолвери и всеки може да изпрати заявка някъде, което изходът не споменава. Браузър с включен защитен DNS може да разрешава през собствения си криптиран канал, така че страница, която се зарежда, докато dscacheutil изтича, не е противоречие. DNS прокси, инсталирано от софтуер за сигурност, работи като доставчик на Network Extension и само препраща заявките, а scutil --dns показва какво е било конфигурирано, а не адреса нагоре по веригата, който проксито накрая е използвало. Домейните за търсене добавят трета особеност: към неквалифицирано име се добавя всяка изброена наставка по ред, така че блокът, който е отговорил, може да е такъв, който изобщо не сте подозирали.
Остарелите отговори са най-евтиното за изключване и най-често пропусканото:
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
scutil --dns | head -20
Ако изходът се промени след изчистването, състоянието е било кеширано и по-ранният изход е описвал тунел, който вече не е съществувал. Ако не се промени, конфигурацията е такава, каквато е, и въпросът се мести към маршрутите и към политиката на приложенията.
Кратък наръчник за преди и след
Снемайте базова линия само там, където политиката позволява, и пазете файловете извън всяка синхронизирана папка. Последователността по-долу е това, което изпълнявам на клиентски машини: снеми базовата линия, свържи се, снеми отново, после сравни и потърси.
scutil --dns > ~/dns-before.txt
# connect the VPN, then:
scutil --dns > ~/dns-after.txt
diff -u ~/dns-before.txt ~/dns-after.txt
dscacheutil -q host -a name intranet.corp.example
Четете разликата по блокове, не по редове. Нов обхванат резолвер с индекса на интерфейса на тунела и запис domain за частната наставка е очакваната форма. Нов резолвер по подразбиране, сочещ към публичен адрес, е находка, която си струва да се повдигне пред този, който притежава клиентския профил. След това повторете търсенето в приложението, което действително се е провалило, не само в обвивката, и запишете интерфейса от route -n get до резултата.
За да отмените промяна, прекъснете връзката и повторете снемането на базовата линия. Ако обхванатият блок е изчезнал, клиентът е почистил след себе си. Ако блокът все още е изброен срещу интерфейс, който вече не съществува, състоянието е остаряло, а изчистване плюс повторно свързване е най-меката поправка, преди някой да пипне профила.
Четири проверки в този ред: съвпада ли блок на резолвера с най-дългата наставка на името; вързан ли е този блок към интерфейса, който тунелът е инсталирал; използва ли маршрутът до неговия сървър за имена тунела; и връща ли отговора системният резолвер, а не dig. Първата проверка, която се провали, ви казва дали да промените DNS политиката, маршрутите на тунела или приложението. Ако и четирите минат, а името все още се проваля, проблемът е над DNS и следващото за оглед е това, което отговаря на порт 53 пред него.