scutil --dns wypisuje konfigurację resolvera, z której macOS naprawdę korzysta, a nie ten jeden serwer DNS wpisany w panel ustawień. Wynik jest dłuższy, niż większość się spodziewa, ponieważ system trzyma osobne bloki resolvera dla ścieżki domyślnej, dla interfejsów z zakresem i dla przekazywania właściwego domenom. Blok na górze wyniku nie musi być tym, który odpowiada na zapytanie. Jeśli prywatna nazwa rozwiązuje się w biurze i zawodzi w momencie, gdy VPN wstaje, niezgodność jest w regułach dopasowania i trasach, nie w adresie serwera. Przeczytaj najpierw kolejność, a potem udowodnij odpowiedź prawdziwym zapytaniem.

Przeczytaj kolejność bloków przed adresami

Każdy wpis otwiera resolver #N i wymienia nameserver[0], czasem if_index, wiersz flags, reach oraz, gdy blok nie jest zwykłym domyślnym, domain i listę search domain. Resolver numer 1 bez domeny jest domyślnym, który obsługuje nazwy publiczne. Wszystko, co w swoich flagach niesie Scoped, jest związane z interfejsem nazwanym przez if_index, a wszystko oznaczone Supplemental dotyczy tylko domen wymienionych pod nim.

Wybór polega na dopasowaniu przyrostka. Dla nazwy takiej jak intranet.corp.example macOS preferuje resolver, którego wpis domain jest najdłuższym pasującym przyrostkiem, więc blok z domain : corp.example wygrywa z domyślnym, nawet gdy znajduje się bardzo nisko w wyniku. order rozstrzyga remisy między domenami o tej samej długości. Pierwsze spojrzenie rzadko wymaga więcej: całego wyniku, gdy chcesz przeczytać jeden blok od początku do końca, pierwszych wierszy, by poznać kolejność bloków, i przefiltrowanego przebiegu, który wypisuje nagłówki bloków obok wierszy pól. Bloki z zakresem pojawiają się pod własnym nagłówkiem i czyta się je jak kontynuację listy powyżej, więc trzymaj nagłówek w zasięgu wzroku, ilekroć cytujesz wynik.

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'

Dopasuj if_index do interfejsu tunelu

Indeks jest przydatny tylko wtedy, gdy potrafisz nazwać interfejs za nim. scutil --nwi wymienia informacje sieciowe, które system przechowuje, w tym interfejs podstawowy i osiągalność, natomiast ifconfig -l podaje nazwy, gdzie utun0 do utun9 to kandydaci na tunel, których klient zwykle tworzy. Apple używa scutil --dns jako własnego przykładu sprawdzenia w przewodniku wdrożeniowym, i dokumentuje, jak Network Extension może kierować wybrane domeny do wybranych resolverów, co jest mechanizmem, który ujawniają te bloki z zakresem.

Sprawdzenie, które rozstrzyga sprawę, polega na tym, czy resolver siedzi na ścieżce zainstalowanej przez tunel:

scutil --nwi
ifconfig utun4
route -n get 10.20.0.53
netstat -rn | grep -m5 utun

Jeśli route -n get zwraca bramę i interfejs, które nie pasują do wpisu resolvera, adres może być całkowicie poprawny i mimo to nieosiągalny. Tunel dzielony, który niesie tylko podsieci firmowe, wyrzuca zapytania skierowane do serwera DNS poza nimi, a awaria objawia się przekroczeniem limitu czasu, dlatego wynik konfiguracji wciąż wygląda czysto.

Zapytaj resolver systemowy, potem serwer

Trzy narzędzia odpowiadają na trzy różne pytania, a ich mylenie tworzy większość błędnych wniosków w tej dziedzinie. dscacheutil -q host -a name przechodzi przez ten sam resolver systemowy, którego używają zwykłe aplikacje, więc obowiązują bloki z zakresem i uzupełniające. dig bez argumentu serwera czyta /etc/resolv.conf, co nie jest źródłem prawdy dla rozwiązywania z zakresem na macOS, i całkowicie pomija reguły dla poszczególnych domen. dig @address dociera dokładnie do jednego serwera i nie mówi nic o wyborze.

dscacheutil -q host -a name intranet.corp.example
dig intranet.corp.example
dig @10.20.0.53 intranet.corp.example
nslookup intranet.corp.example

Gdy pierwsze polecenie odpowiada, a drugie zwraca NXDOMAIN, znalazłeś podział, którego szukałeś, i nic nie jest zepsute. Gdy pierwsze kończy się przekroczeniem limitu czasu, a dig @10.20.0.53 odpowiada, resolver działa, ale jest nieosiągalny na ścieżce wybranej przez tunel, więc następnym krokiem jest route -n get, a nie zmiana ustawień DNS. Trzymaj prywatne nazwy poza wszystkim, co wklejasz do zgłoszenia lub wspólnej notatki.

Czego wynik nie może ci pokazać

Kilka warstw siedzi nad listą resolverów lub obok niej, i każda może wysłać zapytanie gdzieś, czego wynik nigdy nie wspomina. Przeglądarka z włączonym bezpiecznym DNS może rozwiązywać przez własny szyfrowany kanał, więc strona, która się ładuje, gdy dscacheutil przekracza limit czasu, nie jest sprzecznością. Proxy DNS instalowany przez oprogramowanie bezpieczeństwa działa jako dostawca Network Extension i sam przekazuje zapytania, a scutil --dns pokazuje, co skonfigurowano, a nie adres nadrzędny, którego proxy ostatecznie użyło. Domeny wyszukiwania dodają trzecią fałdę: do niepełnej nazwy dopisywany jest po kolei każdy wymieniony przyrostek, więc blok, który odpowiedział, może być takim, którego nigdy nie podejrzewałeś.

Nieaktualne odpowiedzi najtaniej wykluczyć i najczęściej się je pomija:

sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
scutil --dns | head -20

Jeśli wynik zmieni się po opróżnieniu, stan był w pamięci podręcznej i wcześniejszy wynik opisywał tunel, którego już nie było. Jeśli się nie zmieni, konfiguracja jest taka, jaka jest, a pytanie przenosi się na trasy i na politykę aplikacji.

Krótki podręcznik na przed i po

Rejestruj linię bazową tylko tam, gdzie pozwala na to polityka, i trzymaj pliki poza każdym synchronizowanym folderem. Podana kolejność to ta, którą wykonuję na maszynach klientów: zarejestruj linię bazową, połącz się, zarejestruj ponownie, a następnie porównaj i poszukaj.

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

Czytaj różnicę po blokach, a nie po wierszach. Nowy resolver z zakresem niosący indeks interfejsu tunelu i wpis domain dla prywatnego przyrostka to oczekiwana forma. Nowy resolver domyślny wskazujący na publiczny adres to odkrycie, które warto podnieść wobec właściciela profilu klienta. Następnie powtórz wyszukiwanie wewnątrz aplikacji, która naprawdę zawiodła, nie tylko w powłoce, i zapisz interfejs z route -n get obok wyniku.

Aby cofnąć zmianę, rozłącz się i powtórz rejestrowanie linii bazowej. Jeśli blok z zakresem zniknął, klient posprzątał po sobie. Jeśli blok wciąż jest wymieniony wobec interfejsu, którego już nie ma, stan jest nieaktualny, a opróżnienie wraz z ponownym połączeniem to najłagodniejsza poprawka, zanim ktoś dotknie profilu.

Cztery sprawdzenia w tej kolejności: czy jakiś blok resolvera pasuje do najdłuższego przyrostka nazwy; czy ten blok jest związany z interfejsem zainstalowanym przez tunel; czy trasa do jego serwera nazw korzysta z tunelu; i czy odpowiedź zwraca resolver systemowy, a nie dig. Pierwsze sprawdzenie, które zawiedzie, mówi ci, czy zmienić politykę DNS, trasy tunelu czy aplikację. Jeśli wszystkie cztery przejdą, a nazwa wciąż zawodzi, problem siedzi ponad DNS, a następną rzeczą do zbadania jest wszystko, co przed nim odpowiada na porcie 53.

Powiązane artykuły