Je vais essayer d'expliquer ma compréhension du DNS sur Android. Cela vous aidera à résoudre des problèmes connexes et me servira de notes futures.
DNS
Le résolveur de noms de domaine fait traditionnellement partie de la bibliothèque C du système d'exploitation (communément appelée libc). GNU libc
(qui est le plus courant sur les distributions Linux) met en œuvre un mécanisme compliqué de résolution de noms appelé NSS qui peut donner la priorité à l'ordre des services de base de données comme LDAP / NIS, les services locaux de gestion des noms de domaine et les services de gestion des noms de domaine. files
( /etc/hosts
) et DNS
doivent être utilisés afin de résoudre les noms d'hôtes / de domaines. Le résolveur DNS lit alors /etc/resolv.conf
pour obtenir l'adresse du serveur de noms qui doit être interrogé.
Contrairement à GNU libc
, Android Bionic libc
(qui dépend de en netd
pour le DNS) ne considère pas /etc/resolv.conf
sauf si ANDROID_CHANGES est définie (uniquement lorsque libc++ est construit en tant que bibliothèque statique ?). Cependant, /etc/hosts Les entrées sont valorisé par le résolveur d'Android lors de la résolution des noms.
Mais si vous utilisez un binaire compilé/lié de manière statique avec un autre - tel que musl
o uC
o diet
- libc, qui doit être en train de lire /etc/resolv.conf
pour obtenir l'adresse IP du serveur de nom de domaine. Busybox ping est un exemple courant.
Le DNS d'Android
Au sein de l'environnement d'exécution Java d'Android, un DHCP fourni ou une configuration manuelle de l'adresse de l'utilisateur est nécessaire. codé en dur Le serveur DNS est utilisé. Propriétés net.dns1
et net.dns2
sont définis avec les valeurs des serveurs DNS reçues de l'application Serveur DHCP (en Wi-Fi ou en données mobiles) en ConnectivityService
y luego transmis à a netd
. À partir d'Android Oreo, ces propriétés sont les suivantes n'est plus disponible par le biais des API Android, mais seulement lisible comme root
o shell
- une fois supprimé puis Ajouté à nouveau . Donc, changer les propriétés net.dns*
mit setprop
n'affecte que les programmes (fonctionnant avec l'UID 0
o 2000
) qui lisent explicitement ces propriétés. Un tel exemple est La busybox de meefik . Il y avait aussi d'autres Propriétés liées au DNS qui se déroule au bon vieux temps de dhcpcd
qui était le client DHCP jusqu'à Lollipop.
Voir plus de détails dans Comment Android OS fait-il la résolution de nom DNS ? .
Mise en cache
Les requêtes DNS sont mises en cache sur Android par netd
comme NSCD
fait sur les distros Linux pour accélérer la résolution des noms. Android a un outil en ligne de commande ndc
qui pouvait effacer le cache DNS mais la commande était supprimé dans Android 7 . Il est maintenant possible de contourner la mise en cache en définissant une variable d'environnement ANDROID_DNS_MODE
ce qui empêche la libc bionique de renvoyer par proxy vers netd
pour la consultation du cache. Voir Comment modifier les variables d'environnement comme PATH au démarrage ? pour définir la variable de manière globale.
Comment configurer le DNS
Comme mentionné précédemment, les différentes méthodes utilisées pour changer les serveurs de noms de domaine par défaut sur Android ne semblent pas fonctionner maintenant. Configuration des serveurs de noms et/ou recherche du nom de domaine par la ligne de commande :
~$ ndc resolver setnetdns <network_id> <domain> <DNS>
* La syntaxe des commandes est un peu différents sur les anciennes versions
De même, ndc tether dns set
travaille pour dnsmasq
. Pour obtenir l'ID du réseau actuel :
~$ dumpsys netd | grep 'Default network'
Effacer la configuration des serveurs DNS :
~# ndc resolver clearnetdns <network_id>
Cependant, certaines applications peuvent parfois contourner le mécanisme de résolution de noms d'Android en essayant d'atteindre directement un serveur de noms, j'ai observé WhatsApp. Ou la valeur codée en dur est utilisée (peut être lorsque le routeur est annoncer le serveur DNS IPv6 ). La seule option sûre est iptables DNAT
:
~# iptables -t nat -I OUTPUT -p udp --dport 53 -j DNAT --to 1.1.1.1:53
Les serveurs DNS peuvent également être configuré dans Paramètres pour le réseau Wi-Fi. Compatible avec Android 9+. DNS privé / DNS over TLS (DoT) qui envoie des requêtes DNS chiffrées sur port 853 tel que normalisé dans RFC7858 .
La solution non-root qui fonctionne à la fois pour le Wi-Fi et les données mobiles est d'utiliser des applications VPN telles que Hôtes virtuels o Filtre DNS personnel qui interceptent le trafic DNS et effectuent des requêtes auprès du serveur DNS configuré en amont.
Essais
Pour tester quel serveur de nom est utilisé par connectivity
et netd
dans le runtime Java :
~# dumpsys connectivity | grep CONNECTED | grep -o 'DnsAddresses: \[[^ ]*'
~# dumpsys netd | grep -A2 'DNS servers:'
Et ceux utilisés par le serveur DNS de redirection du tethering :
~# ndc tether dns list
~# logcat -d -s TetherController,dnsmasq | grep -E 'update_dns|nameserver'
Pour voir où vont les requêtes DNS, vous pouvez capturer le trafic destiné au port 53 :
~# iptables -I OUTPUT -m udp -p udp --dport 53 -j LOG --log-prefix 'DNS_QUERIES '
~# iptables -I OUTPUT -m tcp -p tcp --dport 53 -j LOG --log-prefix 'DNS_QUERIES '
~# dmesg -w | grep 'DNS_QUERIES'
Ou
~# tcpdump -n -i any port 53
Si les requêtes ne vont pas à la destination souhaitée, il y a un problème avec votre configuration DNS, en particulier si vous utilisez un VPN. Veuillez noter que iptables
et tcpdump
(capture sur le port 53
) ne fonctionnera pas avec le DNS privé (port 853
). Nature dynamique de la RPDB et des tables de routage ( rt_tables ne cesse de changer, principal n'est pas utilisé) accompagné de fwmark ( SO_MARK ) rendent les choses compliquées pour le contrôle manuel.
Si les étapes mentionnées ci-dessus ne fonctionnent pas, il n'y a pas grand-chose que vous puissiez faire pour résoudre les problèmes de DNS sur les appareils Android. Une réinitialisation d'usine ou un re-flash de la ROM peut résoudre le problème.
En outre, si un serveur DNS local est fourni par DHCP (serveur sur le routeur Wi-Fi), vous pouvez vérifier s'il écoute réellement sur le port 53 :
~# nmap -e eth0 -sUT -p53 --script=dns-recursion 192.168.1.245