Android-DNS richtig lesen: pro Netzwerk, nicht in resolv.conf
Ihre Android-App löst über einen Resolver pro Netzwerk auf, nicht über die resolv.conf, die Sie gerade gelesen haben. Prüfen Sie zuerst LinkProperties, Socket-Bindungen und Private DNS.
Sie holen sich eine Shell auf dem Gerät, lesen /etc/resolv.conf oder graben einen alten net.dns1-Wert aus, und erhalten eine Adresse. Die App vor Ihnen löst über etwas völlig anderes auf. In einem aktuellen Android-Release ist der Resolver pro Netzwerk zuständig: Das System hält pro Network eine Richtlinie und wendet sie auf den Socket an, der die Anfrage gestellt hat. Die Datei und die alte Eigenschaft sind Überreste, und keine von beiden beschreibt den Weg, den Ihre Abfrage tatsächlich genommen hat.
Diese Lücke zeigt sich beim Rollout von Split-Tunnel und Private DNS, wo zwei Apps auf demselben Telefon legitimerweise unterschiedliche Antworten sehen können. Dieser Durchgang beginnt bei der falschen oder fehlenden Auflösung und arbeitet sich rückwärts zur Konfiguration vor, der sie gehört.
Der Resolver gehört zu einem Netzwerk, nicht zum Gerät
Die Namensauflösung unter Android 9 und später läuft über einen System-Resolver, der sich nach dem Network richtet, an das ein Socket gebunden ist. Jedes Netzwerk führt seine eigenen LinkProperties mit, und diese Eigenschaften enthalten die DNS-Serverliste, die Suchdomains und den Private-DNS-Zustand nur für dieses Netzwerk. Nichts in diesem Modell entspricht einer geräteweiten Liste, die Sie aus einer Datei lesen könnten.
Ein VPN macht die Aufteilung offensichtlich. Wenn der Tunnel hochkommt, liefert die VPN-App DNS-Server, die im eigenen Netzwerk des VPN registriert sind, sodass Apps, die durch ihn geroutet werden, gegen diese Server auflösen, während ausgeschlossene Apps weiter das darunterliegende Netzwerk nutzen. Ein Gerät, zwei Antwortwege, kein Widerspruch.
Den Snapshot aus der betroffenen App heraus lesen
Fragen Sie die App selbst. Eine Methode, die über einen Context und die normale Berechtigung android.permission.ACCESS_NETWORK_STATE verfügt, kann den Snapshot lesen, ohne Systemeigenschaften anzufassen:
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 ist der Standard für Ihren Prozess, nicht das einzige Netzwerk auf dem Gerät, und kann null sein, wenn der Aufrufer keinen brauchbaren Standard hat. Ein blockiertes VPN als Standard ist der übliche Grund. isPrivateDnsActive sagt Ihnen, ob Abfragen in diesem Netzwerk per TLS zu einem benannten Resolver gehen, was ändert, was eine einfache UDP-53-Sonde zeigt. Die API-Oberfläche ist unter LinkProperties dokumentiert, und jeder Wert darin ist ein Snapshot der Konfiguration und kein Beweis dafür, dass eine bestimmte Abfrage einen bestimmten Server erreicht hat.
Wenn das Standardnetzwerk nicht das ist, das die Arbeit macht
Der Snapshot beantwortet nur den Standard. Eine App kann ihren Prozess oder einen einzelnen Socket an ein anderes Netzwerk binden, und dann folgt die Auflösung dieser Wahl, während Ihre Diagnose weiter den Standard meldet. Ein Browser, der seinen eigenen DNS-over-HTTPS-Resolver mitbringt, zieht die Systemliste überhaupt nicht heran, seine Antworten sagen also nichts über das übrige Gerät aus. Eine Arbeitsprofil-App läuft unter einem separaten Benutzer mit eigener Richtlinie. Prüfen Sie die Bindung, bevor Sie die Server beschuldigen.
Die VPN-Integration ist die andere Hälfte davon. Eine dhcp-option DNS-Zeile in einem OpenVPN-Profil zu empfangen und diese Adresse im Android-VPN-Netzwerk zu registrieren, sind zwei getrennte Schritte, und eine fehlende Route zum Server scheitert genauso still wie eine falsche Adresse. Von einem Entwicklungsrechner aus gibt adb shell dumpsys connectivity dieselben Link-Eigenschaften pro Netzwerk aus, wenn der Build es zulässt, was die Liste ohne Code bestätigt.
Konfiguration mit einer Auflösung vergleichen, die Sie machen dürfen
Wählen Sie einen Namen, der im privaten Namensraum auflösen muss, und einen öffentlichen Namen, und notieren Sie beide Ergebnisse neben dem Snapshot: Netzwerk, konfigurierte Server, Private-DNS-Zustand und den genauen Fehlertext. Eine direkte Abfrage an einen benannten Server beweist, dass dieser Server Ihnen antwortet; sie beweist nicht, dass die normale Anwendungsauflösung ihn gewählt hat. Eine zwischengespeicherte Antwort ist kein frischer Test, also leeren Sie den Cache oder nehmen Sie einen Namen, den heute noch niemand abgefragt hat.
Wenn der Resolver nur Clients aus einem bestimmten Zugangsnetz bedient, kann entscheiden, was er nach dem VPN-Egress sieht, und das ist eine Richtlinienfrage für den Betreiber und kein Beweis dafür, dass Mobilfunkanbieter UDP 53 blockieren. Wo Private DNS aktiv ist, kann ein unqualifizierter Hostname designbedingt abgelehnt werden, während derselbe Server öffentliche Namen normal beantwortet. Die Eigenschaften zu lesen sagt Ihnen, welcher Modus gilt, sodass Sie aufhören, an Paketfiltern zu raten.
Die Schicht reparieren, der die Abweichung gehört
Arbeiten Sie sich nach oben, statt globalen Zustand zu bearbeiten. Ist die App an das falsche Netzwerk gebunden, reparieren Sie die Bindung. Liefert das Profil die falsche DNS-Option, reparieren Sie das Profil. Ist Private DNS in einem Netzwerk strikt, dessen Resolver Ihre private Zone nicht bedienen kann, ist das eine Entscheidung des Gerätemanagements und kein Grund, die Funktion überall abzuschalten.
Öffentliche Resolver in einen DHCP-Hook oder eine Systemeigenschaft zu erzwingen, ist die Reparatur, die immer wieder Vorfälle verursacht: Private Namen lösen nicht mehr auf, die Änderung überlebt die VPN-Sitzung, und die nächste Person am Gerät findet eine veraltete Adresse ohne Besitzer. Halten Sie die Änderung in dem VPN, der App oder der Management-Schicht, der die Abweichung gehört, und lesen Sie dann den Snapshot erneut, um zu bestätigen, dass sich die Serverliste tatsächlich geändert hat.
Am Ende wollen Sie eine App-Anfrage, gebunden an ein Netzwerk, eine Resolverliste und einen Private-DNS-Zustand. Sobald Sie diese Kette zeigen können, ist eine vertraute Adresse in einer Datei kein Beweis mehr für irgendetwas.