Czytaj DNS Androida poprawnie: według sieci, nie w resolv.conf
Twoja aplikacja Android rozwiązuje nazwy przez resolver dla każdej sieci, a nie przez resolv.conf, który właśnie przeczytałeś. Sprawdź najpierw LinkProperties, powiązania gniazd i Private DNS.
Dostajesz powłokę na urządzeniu, czytasz /etc/resolv.conf albo wykopujesz starą wartość net.dns1 i dostajesz jeden adres. Aplikacja przed tobą rozwiązuje przez coś zupełnie innego. W bieżącym wydaniu Androida resolver jest dla każdej sieci: system trzyma politykę dla każdej Network i stosuje ją do gniazda, które wysłało żądanie. Plik i stara właściwość to pozostałości i żadne z nich nie opisuje drogi, którą naprawdę przeszło twoje zapytanie.
Ta luka ujawnia się przy wdrażaniu split-tunnelu i Private DNS, gdzie dwie aplikacje na tym samym telefonie mogą zgodnie z prawem widzieć różne odpowiedzi. Ten przewodnik zaczyna od błędnego lub brakującego rozwiązania i cofa się do konfiguracji, do której ono należy.
Resolver należy do sieci, nie do urządzenia
Rozwiązywanie nazw w Androidzie 9 i późniejszych przechodzi przez resolver systemowy, który opiera się na Network, do której przypisane jest gniazdo. Każda sieć ma własne LinkProperties, a te właściwości zawierają listę serwerów DNS, domeny wyszukiwania i stan Private DNS tylko dla tej jednej sieci. Nic w tym modelu nie odpowiada jednej liście dla całego urządzenia, którą można odczytać z pliku.
VPN czyni podział oczywistym. Gdy tunel wstaje, aplikacja VPN dostarcza serwery DNS zarejestrowane we własnej sieci VPN, więc aplikacje kierowane przez nią rozwiązują nazwy przez te serwery, a aplikacje wykluczone nadal korzystają z sieci bazowej. Jedno urządzenie, dwie ścieżki odpowiedzi, żadnej sprzeczności.
Odczytaj migawkę z wnętrza dotkniętej aplikacji
Zapytaj samą aplikację. Metoda, która ma Context i zwykłe uprawnienie android.permission.ACCESS_NETWORK_STATE, może odczytać migawkę bez dotykania właściwości systemu:
val cm = getSystemService(ConnectivityManager::class.java) ?: return
val network = cm.activeNetwork
val links = network?.let { cm.getLinkProperties(it) }
val dnsServers = links?.dnsServers
val privateDnsActive = links?.isPrivateDnsActive
val privateDnsName = links?.privateDnsServerNameactiveNetwork to domyślna sieć twojego procesu, nie jedyna sieć na urządzeniu, i może być null, gdy wywołujący nie ma użytecznej domyślnej. Zablokowany domyślny VPN to zwykła przyczyna. isPrivateDnsActive mówi, czy zapytania w tej sieci idą przez TLS do nazwanego resolvera, co zmienia to, co pokaże prosta sonda UDP 53. Powierzchnia API jest udokumentowana pod LinkProperties, a każda wartość w niej to migawka konfiguracji, nie dowód, że konkretne zapytanie dotarło do konkretnego serwera.
Gdy sieć domyślna nie jest tą, która wykonuje pracę
Migawka odpowiada tylko za domyślną. Aplikacja może przypisać swój proces albo jedno gniazdo do innej sieci, a wtedy rozwiązywanie idzie za tym wyborem, podczas gdy twoja diagnostyka nadal raportuje domyślną. Przeglądarka z własnym resolverem DNS-over-HTTPS w ogóle nie sięga do listy systemowej, więc jej odpowiedzi nic nie mówią o reszcie urządzenia. Aplikacja profilu służbowego działa pod osobnym użytkownikiem z własną polityką. Sprawdź powiązanie, zanim obwinisz serwery.
Integracja z VPN to druga połowa. Odebranie wiersza dhcp-option DNS w profilu OpenVPN i zarejestrowanie tego adresu w sieci VPN Androida to dwa osobne kroki, a brakująca trasa do serwera zawodzi równie cicho jak błędny adres. Z maszyny deweloperskiej adb shell dumpsys connectivity wypisuje te same właściwości łącza dla każdej sieci, gdy kompilacja na to pozwala, co potwierdza listę bez pisania kodu.
Porównaj konfigurację z jednym rozwiązaniem, na które możesz sobie pozwolić
Wybierz nazwę, która musi się rozwiązać w przestrzeni prywatnej, oraz jedną nazwę publiczną, i zapisz oba wyniki obok migawki: sieć, skonfigurowane serwery, stan Private DNS i dokładny tekst błędu. Bezpośrednie zapytanie do nazwanego serwera dowodzi, że ten serwer ci odpowiada; nie dowodzi, że zwykłe rozwiązywanie aplikacji go wybrało. Odpowiedź z pamięci podręcznej nie jest świeżym testem, więc wyczyść cache albo użyj nazwy, o którą nikt dziś nie pytał.
Jeśli resolver obsługuje tylko klientów z konkretnej sieci dostępu, to, co widzi po wyjściu z VPN, może zdecydować o wyniku, a to jest kwestia polityki dla tego, kto nim zarządza, a nie dowód, że operatorzy blokują UDP 53. Tam, gdzie Private DNS jest aktywne, niekwalifikowana nazwa hosta może zostać odrzucona z założenia, podczas gdy ten sam serwer normalnie odpowiada na nazwy publiczne. Odczyt właściwości mówi, który tryb obowiązuje, więc przestajesz zgadywać filtry pakietów.
Napraw warstwę, do której należy niezgodność
Pracuj w górę zamiast edytować stan globalny. Jeśli aplikacja jest przypisana do złej sieci, napraw powiązanie. Jeśli profil dostarcza złą opcję DNS, napraw profil. Jeśli Private DNS jest rygorystyczne w sieci, której resolver nie obsłuży twojej strefy prywatnej, to decyzja zarządzania urządzeniem, a nie powód, by wyłączać funkcję wszędzie.
Wpychanie publicznych resolverów do haka DHCP albo właściwości systemowej to naprawa, która nieustannie powoduje incydenty: nazwy prywatne przestają się rozwiązywać, zmiana przeżywa sesję VPN, a następna osoba na urządzeniu znajduje nieaktualny adres bez właściciela. Trzymaj zmianę w VPN, aplikacji albo warstwie zarządzania, do której należy niezgodność, a potem ponownie odczytaj migawkę, by potwierdzić, że lista serwerów naprawdę się zmieniła.
Czego chcesz na końcu, to jedno żądanie aplikacji powiązane z jedną siecią, listą resolverów i stanem Private DNS. Gdy potrafisz pokazać ten łańcuch, znany adres w pliku przestaje być dowodem na cokolwiek.