DNS-Resolver

Das DNS-Resolver-Modul bietet Schutz vor DNS-Abfangen und Konfigurationsaktualisierungsangriffen sowie eine verbesserte Netzwerkleistung für DNS-Auflösungen. Das Modul enthält den Code, der den DNS-Stub-Resolver implementiert, der Namen wie www.google.com in IP-Adressen wie 2001:db8::1 umwandelt. Der DNS-Stub-Resolver unterstützt Java API-Elemente wie InetAddress#getAllByName und Network#getAllByName sowie native Netzwerkfunktionen. Außerdem werden DNS-Abfragen gesendet und empfangen und die Ergebnisse im Cache gespeichert.

Änderungen in Android 10

Auf Geräten mit Android 9 und niedriger ist der DNS-Resolver-Code auf Bionic und netd verteilt. DNS-Suchanfragen werden zentral im netd-Daemon ausgeführt, um systemweites Caching zu ermöglichen. Apps rufen Funktionen wie getaddrinfo in Bionic auf. Die Abfrage wird über einen UNIX-Socket an /dev/socket/dnsproxyd und dann an den netd-Daemon gesendet. Dieser analysiert die Anfrage und ruft getaddrinfo noch einmal auf, um DNS-Suchanfragen auszuführen. Die Ergebnisse werden dann im Cache gespeichert, damit sie von anderen Apps verwendet werden können. Die DNS-Resolver-Implementierung war hauptsächlich in bionic/libc/dns/ und teilweise in system/netd/server/dns enthalten.

In Android 10 wird der DNS-Resolver-Code in system/netd/resolv, verschoben, in C++ konvertiert und dann modernisiert und umstrukturiert. Der Code in Bionic ist aus Gründen der App-Kompatibilität weiterhin vorhanden, wird aber nicht mehr vom System aufgerufen. Diese Quellpfade sind vom Refactoring betroffen:

  • bionic/libc/dns
  • system/netd/client
  • system/netd/server/dns
  • system/netd/server/DnsProxyListener
  • system/netd/server/ResolverController
  • system/netd/resolv

Format und Abhängigkeiten

Das DNS-Resolver-Modul (`com.android.resolv`) wird als APEX-Datei bereitgestellt und von netd dynamisch verknüpft. netd ist jedoch keine Abhängigkeit, da das Modul den lokalen Socket /dev/socket/dnsproxyd direkt bedient. Der Binder-Endpunkt für die Resolver-Konfiguration wurde von netd zum Resolver verschoben. Das bedeutet, dass der Systemdienst das Resolver-Modul direkt aufrufen kann, ohne netd zu verwenden.

Das DNS-Resolver-Modul ist von libc (Bionic) abhängig und verknüpft seine Abhängigkeiten statisch. Es sind keine anderen Bibliotheken erforderlich.

mDNS .local-Auflösung

Ab November 2021 unterstützt der Android-Resolver die mDNS-Auflösung von .local-Adressen. Dabei werden „5.1 One-Shot-Multicast-DNS-Abfragen“ gemäß RFC 6762 implementiert, um Standard-DNS-Abfragen blind an 224.0.0.251:5353 oder [FF02::FB]:5353 zu senden. Die mDNS-Auflösung wird transparent unterstützt, indem getaddrinfo() mit einem Hostnamen aufgerufen wird, der auf *.local endet.

Die mDNS-Auflösung von .local erweitert die vorhandenen Funktionen von getaddrinfo(), um die Adressen abzurufen. Wenn ein Gerät die mDNS-Auflösung von .local unterstützt, sendet die getaddrinfo() API mDNS-Abfragen an 224.0.0.251:5353 oder [FF02::FB]:5353 und gibt die lokalen Adressen zurück. Wenn ein Gerät die mDNS-Auflösung von .local nicht unterstützt, sendet die getaddrinfo() API-Methode eine DNS-Abfrage an den DNS-Server.

Der Code befindet sich in AOSP unter packages/modules/DnsResolver. Nutzer können ihr aktuelles mDNS-Design beibehalten, um die Adressen abzurufen, oder stattdessen getaddrinfo() verwenden. Das Verhalten dieser Funktion ähnelt einer regulären DNS-Abfrage, die an die mDNS-Multicast-Adressen gesendet wird. Diese Funktion hat keinen Einfluss auf den Systemzustand.

Nutzer können den Befehl adb shell ping6 HOSTNAME.local verwenden, wobei HOSTNAME der Hostname eines Zielgeräts im LAN ist, z. B. adb shell ping6 ipad.local.

VPN- und mobile Datenverbindungen sind von der Auflösung von .local-Adressen ausgeschlossen.