Un’app Android rifiuta di funzionare su VPN: quale livello decide
Un’app può rifiutare una VPN per un controllo locale del trasporto, una regola sugli indirizzi lato server o una sua politica. Distingui i tre casi prima di cambiare uscite.
Quando un’app Android smette di funzionare nel momento in cui sale il tunnel, possono esserne responsabili tre cose diverse, e producono guasti dall’aspetto simile. L’app può leggere lo stato di rete del telefono stesso e rifiutare localmente. Il server può classificare l’indirizzo da cui arrivi e respingerlo. Oppure il rifiuto può non avere nulla a che fare con la VPN. L’ordine qui sotto raccoglie prove prima di cambiare qualcosa, perché cambiare l’uscita è il passo più costoso e quello meno probabilmente utile se il controllo è locale.
Passo 1: scoprire quando l’app rifiuta
Il momento è il primo discriminante. Svuota il buffer del registro, riproduci il guasto e guarda cosa ha fatto l’app prima di lamentarsi:
adb logcat -c
# reproduce the failure in the app
adb logcat -d | grep -iE 'vpn|network|connect|http' | tail -60
Se l’app rifiuta prima che venga tentata una qualsiasi richiesta in uscita, stai guardando una decisione locale. Se si connette, invia qualcosa e poi mostra un errore, il rifiuto è arrivato dall’altro lato. Se fallisce allo stesso modo con il tunnel spento, la VPN non è mai stata la variabile.
Tratta quel momento come prova e non come conferma. Un’app può riprodurre una risposta in cache, e le richieste in background possono essere riuscite o fallite prima che guardassi. Annota i timestamp dell’ultima richiesta riuscita e dell’errore, non solo l’istante in cui è comparso il messaggio.
Passo 2: leggere la visione del telefono sulla rete
Android espone lo stato della VPN come capacità di rete, quindi un’app non ha bisogno di un elenco di fornitori commerciali per accorgersi che un tunnel è attivo. Chiede al servizio di connettività qual è la rete corrente, e la risposta include un bit di trasporto VPN:
val cm = context.getSystemService(ConnectivityManager::class.java)
val caps = cm.getNetworkCapabilities(cm.activeNetwork)
val onVpn = caps?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true
Quel controllo è locale ed economico, e spiega un’intera classe di segnalazioni del tipo «questa app non funziona su VPN» senza alcuna classificazione remota. Ciò che l’app può vedere dipende ancora dal suo contesto di rete, quindi non dare per scontato che ogni app ispezioni ogni profilo del dispositivo.
Da una postazione di lavoro puoi vedere lo stesso stato su un dispositivo di prova con adb shell dumpsys connectivity e cercando la voce di rete VPN. Confronta un’esecuzione con il tunnel alzato con una con il tunnel abbassato, e conserva entrambi gli output.
Passo 3: leggere ciò che il server vede davvero
L’altro osservatore è il servizio. Vede l’indirizzo sorgente che arriva, e può agire sull’indirizzo, sulla rete di hosting dietro di esso, sulla regione, sull’operatore o su segnali legati all’account e al dispositivo. Nessuno di questi è un’identità unica, e l’indirizzamento condiviso rende normali i blocchi collaterali: un indirizzo limitato può mettere fuori gioco utenti non correlati dietro la stessa traduzione.
Ottieni l’indirizzo dallo stesso percorso che usa l’app, non da un browser su un portatile. Sul telefono, una richiesta semplice a un servizio di eco degli indirizzi mostra cosa riceve il lato remoto, e confrontarla con una richiesta sulla rete mobile ti dice se l’indirizzo è cambiato del tutto.
Se l’app funziona sulla rete mobile e fallisce sul tunnel con lo stesso account, il rifiuto è all’estremità remota o nella politica dell’app stessa. Se fallisce in entrambi i casi, la VPN non è il fattore discriminante e dovresti smettere di testare gli endpoint.
Passo 4: abbinare le prove a uno dei tre verdetti
Tre combinazioni coprono quasi ogni segnalazione. Un rifiuto senza alcun tentativo in uscita mentre un tunnel è attivo punta a un controllo locale del trasporto. Una richiesta che esce e torna con un errore, un timeout su un host specifico o un messaggio di regione punta al lato remoto. Un guasto che si ripete sulla rete mobile senza tunnel punta all’account, alla versione dell’app o alla politica del servizio stesso, e nessun cambio di VPN lo sposterà.
Scrivi il verdetto insieme alla prova che lo ha prodotto. Il valore di questo passo è che ferma il ciclo in cui qualcuno cambia quattro volte i nodi di uscita per correggere un controllo che gira sul telefono stesso.
Tiene anche oneste le affermazioni. Ospitare da sé cambia l’endpoint e la sua uscita internet; non fa dimenticare ad Android che una rete VPN è attiva, e non garantisce l’accettazione da parte di un servizio che classifica indirizzi. Un filtro locale può scattare sulla tua rete VPN tanto facilmente quanto su una commerciale.
Passo 5: seguire la via supportata e verificarla
Parti dalla politica documentata del prodotto e dal suo responsabile del supporto. Invia la versione del client, il messaggio esatto e una finestra di guasto stretta; non inviare catture di traffico complete o credenziali solo per dimostrare che esiste un errore.
Se il servizio consente l’accesso diretto e la politica del dispositivo lo permette, l’esclusione per app è il meccanismo supportato, e toglie deliberatamente quell’app dal tunnel invece di nascondere il tunnel. Il traffico dell’app esce allora per la propria strada, che è una decisione di politica che qualcuno deve assumersi. In una configurazione che blocca senza VPN, un’app esclusa può semplicemente perdere la connettività, quindi prova quella combinazione prima di promettere che funziona.
Dopo ogni modifica, ripeti il test del momento del primo passo, conferma che l’app funziona e conferma che tutte le altre app usano ancora il tunnel. Poi ripristina la configurazione precedente e verifica se il guasto ritorna, perché una correzione che non riesci a riprodurre è una coincidenza che incontrerai di nuovo.