Ottieni una shell sul dispositivo, leggi /etc/resolv.conf o scovi un vecchio valore net.dns1, e ottieni un indirizzo. L’app che hai davanti risolve attraverso qualcosa di completamente diverso. Su una versione attuale di Android il resolver è per rete: il sistema mantiene una policy per ogni Network e la applica al socket che ha effettuato la richiesta. Il file e la vecchia proprietà sono residui, e nessuno dei due descrive il percorso che la tua query ha davvero seguito.

Questo divario emerge durante i rollout di split tunnel e DNS privato, dove due app sullo stesso telefono possono legittimamente vedere risposte diverse. Questa analisi parte dalla risoluzione errata o mancante e risale alla configurazione che la possiede.

Il resolver appartiene a una rete, non al dispositivo

La risoluzione dei nomi su Android 9 e successivi passa per un resolver di sistema che si basa sulla Network a cui è associato un socket. Ogni rete porta con sé le proprie LinkProperties, e quelle proprietà contengono l’elenco dei server DNS, i domini di ricerca e lo stato del DNS privato solo per quella rete. Nulla in quel modello corrisponde a un elenco unico per dispositivo che puoi leggere da un file.

Una VPN rende evidente la separazione. Quando il tunnel sale, l’app VPN fornisce server DNS registrati sulla rete propria della VPN, così le app instradate attraverso di essa risolvono su quei server mentre le app escluse continuano a usare la rete sottostante. Un dispositivo, due percorsi di risposta, nessuna contraddizione.

Leggere lo snapshot dall’interno dell’app interessata

Chiedi all’app stessa. Un metodo che dispone di un Context e del normale permesso android.permission.ACCESS_NETWORK_STATE può leggere lo snapshot senza toccare le proprietà di sistema:

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?.privateDnsServerName

activeNetwork è la rete predefinita del tuo processo, non l’unica rete del dispositivo, e può essere null quando il chiamante non ha un predefinito utilizzabile. Una VPN predefinita bloccata è il motivo abituale. isPrivateDnsActive ti dice se le query su quella rete passano su TLS verso un resolver con nome, il che cambia ciò che una semplice sonda UDP 53 ti mostrerà. La superficie API è documentata in LinkProperties, e ogni valore che contiene è uno snapshot della configurazione, non la prova che una particolare query abbia raggiunto un particolare server.

Quando la rete predefinita non è quella che lavora

Lo snapshot risponde solo per la predefinita. Un’app può associare il proprio processo o un singolo socket a un’altra rete, e allora la risoluzione segue quella scelta mentre la tua diagnostica continua a riportare la predefinita. Un browser che porta il proprio resolver DNS-over-HTTPS non consulta mai l’elenco di sistema, quindi le sue risposte non dicono nulla del resto del dispositivo. Un’app del profilo di lavoro gira sotto un utente separato con una propria policy. Controlla il binding prima di dare la colpa ai server.

L’integrazione VPN è l’altra metà. Ricevere una riga dhcp-option DNS in un profilo OpenVPN e registrare quell’indirizzo sulla rete VPN di Android sono due passaggi distinti, e una route mancante verso il server fallisce in modo silenzioso quanto un indirizzo sbagliato. Da una macchina di sviluppo, adb shell dumpsys connectivity stampa le stesse proprietà di link per rete quando la build lo consente, il che conferma l’elenco senza scrivere codice.

Confrontare la configurazione con una risoluzione che sei autorizzato a fare

Scegli un nome che deve risolvere nello spazio privato e un nome pubblico, poi annota entrambi i risultati accanto allo snapshot: rete, server configurati, stato del DNS privato e testo esatto dell’errore. Una query diretta a un server con nome dimostra che quel server ti risponde; non dimostra che la normale risoluzione applicativa lo abbia scelto. Una risposta in cache non è un test fresco, quindi svuota la cache o usa un nome che nessuno ha interrogato oggi.

Se il resolver serve solo client da una particolare rete di accesso, ciò che vede dopo l’uscita VPN può decidere l’esito, e questa è una questione di policy per chi lo gestisce, non la prova che gli operatori blocchino l’UDP 53. Dove il DNS privato è attivo, un nome host non qualificato può essere rifiutato per progettazione mentre lo stesso server risponde normalmente ai nomi pubblici. Leggere le proprietà ti dice quale modalità è in vigore, così smetti di indovinare i filtri di pacchetti.

Correggere il livello a cui appartiene la discrepanza

Lavora verso l’alto invece di modificare lo stato globale. Se l’app è associata alla rete sbagliata, correggi il binding. Se il profilo fornisce l’opzione DNS sbagliata, correggi il profilo. Se il DNS privato è rigoroso su una rete il cui resolver non può servire la tua zona privata, è una decisione di gestione del dispositivo, non un motivo per disattivare la funzione ovunque.

Forzare resolver pubblici in un hook DHCP o in una proprietà di sistema è la riparazione che continua a causare incidenti: i nomi privati smettono di risolversi, la modifica sopravvive alla sessione VPN e la persona successiva sul dispositivo trova un indirizzo obsoleto senza proprietario. Mantieni la modifica dentro la VPN, l’app o il livello di gestione a cui appartiene la discrepanza, poi rileggi lo snapshot per confermare che l’elenco dei server è davvero cambiato.

Quello che vuoi alla fine è una richiesta di app legata a una rete, a un elenco di resolver e a uno stato del DNS privato. Una volta che sai mostrare questa catena, un indirizzo familiare in un file smette di essere prova di qualcosa.

Articoli correlati