Lees Android-DNS korrek: per netwerk, nie in resolv.conf nie
Jou Android-app los op via ’n resolver per netwerk, nie via die resolv.conf wat jy pas gelees het nie. Ondersoek eers LinkProperties, socket-bindings en Private DNS.
Jy kry ’n shell op die toestel, lees /etc/resolv.conf of grawe ’n ou net.dns1-waarde uit, en kry een adres. Die app voor jou los op via iets heeltemal anders. Op ’n huidige Android-weergawe is die resolver per netwerk: die stelsel hou ’n beleid vir elke Network en pas dit toe op die socket wat die versoek gedoen het. Die lêer en die ou eienskap is oorblyfsels, en nie een van hulle beskryf die pad wat jou navraag werklik gevolg het nie.
Daardie gaping wys tydens split-tunnel- en Private DNS-uitrol, waar twee apps op dieselfde foon wettig verskillende antwoorde kan sien. Hierdie deurloop begin by die verkeerde of ontbrekende opsoeking en werk terug na die konfigurasie wat dit besit.
Die resolver behoort aan ’n netwerk, nie aan die toestel nie
Naamoplossing op Android 9 en later gaan deur ’n stelselresolver wat op die Network staatmaak waaraan ’n socket gebind is. Elke netwerk dra sy eie LinkProperties, en daardie eienskappe hou die DNS-bedienerlys, die soekdomeine en die Private DNS-toestand net vir daardie netwerk. Niks in daardie model stem ooreen met een toestelwye lys wat jy uit ’n lêer kan lees nie.
’n VPN maak die splitsing duidelik. Wanneer die tonnel opkom, voorsien die VPN-app DNS-bedieners wat op die VPN se eie netwerk geregistreer is, sodat apps wat daardeur gerouteer word teen daardie bedieners oplos terwyl uitgeslote apps die onderliggende netwerk bly gebruik. Een toestel, twee antwoordpaaie, geen teenstrydigheid nie.
Lees die momentopname van binne die betrokke app
Vra die app self. ’n Metode met ’n Context en die normale toestemming android.permission.ACCESS_NETWORK_STATE kan die momentopname lees sonder om stelseleienskappe aan te raak:
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 is die standaard vir jou proses, nie die enigste netwerk op die toestel nie, en dit kan null wees wanneer die oproeper geen bruikbare standaard het nie. ’n Geblokkeerde VPN-standaard is die gewone rede. isPrivateDnsActive vertel jou of navrae op daardie netwerk oor TLS na ’n genoemde resolver gaan, wat verander wat ’n gewone UDP 53-probe jou wys. Die API-oppervlak is gedokumenteer onder LinkProperties, en elke waarde daarin is ’n momentopname van konfigurasie en nie ’n bewys dat ’n bepaalde navraag ’n bepaalde bediener bereik het nie.
Wanneer die standaardnetwerk nie die een is wat die werk doen nie
Die momentopname antwoord net vir die standaard. ’n App kan sy proses of ’n enkele socket aan ’n ander netwerk bind, en dan volg die opsoeking daardie keuse terwyl jou diagnostiek steeds die standaard rapporteer. ’n Blaaier wat sy eie DNS-over-HTTPS-resolver lewer, raadpleeg nooit die stelsellys nie, so sy antwoorde sê niks oor die res van die toestel nie. ’n Werkprofiel-app loop onder ’n aparte gebruiker met sy eie beleid. Kontroleer die binding voordat jy die bedieners blameer.
VPN-integrasie is die ander helfte. Om ’n dhcp-option DNS-reël in ’n OpenVPN-profiel te ontvang en daardie adres op die Android VPN-netwerk te registreer, is twee afsonderlike stappe, en ’n ontbrekende roete na die bediener misluk net so stil soos ’n verkeerde adres. Vanaf ’n ontwikkelmasjien druk adb shell dumpsys connectivity dieselfde skakel-eienskappe per netwerk as die bou dit toelaat, wat die lys bevestig sonder om kode te skryf.
Vergelyk konfigurasie met een opsoeking wat jy mag doen
Kies ’n naam wat binne die private naamruimte moet oplos en een openbare naam, en teken albei resultate langs die momentopname aan: netwerk, gekonfigureerde bedieners, Private DNS-toestand en die presiese foutteks. ’n Direkte navraag aan ’n genoemde bediener bewys dat daardie bediener jou antwoord; dit bewys nie dat gewone toepassingoplossing hom gekies het nie. ’n Gekasde antwoord is nie ’n vars toets nie, so leeg die kas of gebruik ’n naam wat niemand vandag navraag gedoen het nie.
As die resolver net kliënte van ’n bepaalde toegangsnetwerk bedien, kan dit wat hy ná VPN-uitgang sien die uitkoms bepaal, en dit is ’n beleidsvraag vir wie hom bestuur, nie ’n bewys dat operateurs UDP 53 blokkeer nie. Waar Private DNS aktief is, kan ’n ongekwalifiseerde gasheernaam ontwerpmatig geweier word terwyl dieselfde bediener openbare name normaal antwoord. Om die eienskappe te lees sê vir jou watter modus geld, sodat jy ophou raai oor pakkefilters.
Herstel die laag wat die wanverhouding besit
Werk opwaarts in plaas van om globale toestand te wysig. As die app aan die verkeerde netwerk gebind is, herstel die binding. As die profiel die verkeerde DNS-opsie lewer, herstel die profiel. As Private DNS streng is op ’n netwerk wie se resolver nie jou private sone kan bedien nie, is dit ’n toestelbestuurbesluit en nie ’n rede om die funksie oral af te skakel nie.
Om openbare resolvers in ’n DHCP-haak of ’n stelseleienskap te forseer, is die herstel wat aanhoudend voorvalle veroorsaak: private name hou op oplos, die verandering oorleef die VPN-sessie, en die volgende persoon op die toestel vind ’n verouderde adres sonder eienaar. Hou die verandering binne die VPN, die app of die bestuurslaag wat die wanverhouding besit, en lees dan die momentopname weer om te bevestig dat die bedienerlys werklik verander het.
Wat jy uiteindelik wil hê, is een app-versoek gekoppel aan een netwerk, resolverlys en Private DNS-toestand. Sodra jy daardie ketting kan wys, is ’n bekende adres in ’n lêer nie meer ’n bewys van enigiets nie.