Aplicativo Android se recusa a funcionar na VPN: qual camada decide
Um aplicativo pode recusar a VPN por uma verificação local de transporte, por uma regra de endereço no servidor ou pela própria política. Distinga os três casos antes de mudar a saída.
Quando um aplicativo Android para de funcionar no instante em que o túnel sobe, três coisas diferentes podem ser responsáveis, e elas produzem falhas de aparência semelhante. O aplicativo pode ler o estado de rede do próprio telefone e recusar localmente. O servidor pode classificar o endereço de onde você chega e rejeitá-lo. Ou a recusa pode não ter nada a ver com a VPN. A ordem abaixo reúne evidências antes de mudar qualquer coisa, porque trocar a saída é o passo mais caro e o que menos provavelmente ajuda se a verificação for local.
Passo 1: descubra quando o aplicativo recusa
O momento é o primeiro discriminador. Limpe o buffer de log, reproduza a falha e veja o que o aplicativo fez antes de reclamar:
adb logcat -c
# reproduce the failure in the app
adb logcat -d | grep -iE 'vpn|network|connect|http' | tail -60
Se o aplicativo recusa antes de qualquer tentativa de requisição de saída, você está diante de uma decisão local. Se ele conecta, envia algo e só então mostra um erro, a rejeição veio do outro lado. Se o aplicativo falha de forma idêntica com o túnel desligado, a VPN nunca foi a variável.
Trate esse momento como evidência, não como prova. Um aplicativo pode reproduzir uma resposta em cache, e requisições em segundo plano podem ter dado certo ou falhado antes de você olhar. Anote os horários da última requisição bem-sucedida e do erro, não apenas o instante em que a mensagem apareceu.
Passo 2: leia a visão do próprio telefone sobre a rede
O Android expõe o estado da VPN como uma capacidade de rede, então um aplicativo não precisa de uma lista de provedores comerciais para notar que um túnel está ativo. Ele pergunta ao serviço de conectividade qual é a rede atual, e a resposta inclui um bit de transporte VPN:
val cm = context.getSystemService(ConnectivityManager::class.java)
val caps = cm.getNetworkCapabilities(cm.activeNetwork)
val onVpn = caps?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true
Essa verificação é local e barata, e explica toda uma classe de relatos de "este aplicativo não funciona na VPN" sem qualquer classificação remota. O que o aplicativo consegue ver ainda depende do próprio contexto de rede, então não presuma que todo aplicativo inspeciona todo perfil do aparelho.
De uma estação de trabalho você vê o mesmo estado em um aparelho de teste com adb shell dumpsys connectivity e procurando a entrada de rede VPN. Compare uma execução com o túnel ligado com outra com ele desligado, e guarde as duas saídas.
Passo 3: leia o que o servidor realmente vê
O outro observador é o serviço. Ele vê o endereço de origem que chega e pode agir sobre o endereço, a rede de hospedagem por trás dele, a região, a operadora ou sinais ligados à conta e ao dispositivo. Nenhum deles é uma identidade única, e o endereçamento compartilhado torna bloqueios colaterais normais: um endereço restrito pode derrubar usuários sem relação por trás da mesma tradução.
Obtenha o endereço pelo mesmo caminho que o aplicativo usa, não de um navegador no notebook. No telefone, uma requisição simples a um serviço de eco de endereço mostra o que o lado remoto recebe, e comparar isso com uma requisição pela rede móvel diz se o endereço mudou.
Se o aplicativo funciona pela rede móvel e falha pelo túnel com a mesma conta, a rejeição está no lado remoto ou na política do próprio aplicativo. Se falha nos dois, a VPN não é o diferencial e você deve parar de testar pontos de extremidade.
Passo 4: encaixe as evidências em um dos três veredictos
Três combinações cobrem quase todos os relatos. Uma recusa sem tentativa de saída enquanto um túnel está ativo aponta para uma verificação local de transporte. Uma requisição que sai e volta com erro, um tempo esgotado em um host específico ou uma mensagem de região apontam para o lado remoto. Uma falha que se repete na rede móvel sem túnel aponta para a conta, a versão do aplicativo ou a política do serviço, e nenhuma mudança de VPN vai movê-la.
Escreva o veredicto junto com as evidências que o produziram. O valor deste passo é interromper o ciclo em que alguém troca nós de saída quatro vezes para corrigir uma verificação que roda no aparelho.
Isso também mantém as afirmações honestas. Hospedar o próprio servidor muda o ponto de extremidade e a saída dele para a internet; não faz o Android esquecer que uma rede VPN está ativa e não garante aceitação por um serviço que classifica endereços. Um filtro local pode disparar em uma rede VPN sua tão facilmente quanto em uma comercial.
Passo 5: siga o caminho suportado e verifique
Comece pela política documentada do produto e pelo responsável de suporte. Envie a versão do cliente, a mensagem exata e uma janela estreita de falha; não envie capturas completas de tráfego ou credenciais só para provar que um erro existe.
Se o serviço permite acesso direto e a política do dispositivo permite, a exclusão por aplicativo é o mecanismo suportado, e ela retira deliberadamente esse aplicativo do túnel em vez de esconder o túnel. O tráfego do aplicativo então sai pelo próprio caminho, o que é uma decisão de política que alguém precisa assumir. Numa configuração de bloqueio sem VPN, um aplicativo excluído pode simplesmente perder a conectividade, então teste essa combinação antes de prometer que funciona.
Depois de qualquer mudança, repita o teste de tempo do passo um, confirme que o aplicativo funciona e confirme que todos os outros aplicativos continuam usando o túnel. Em seguida, restaure a configuração anterior e verifique se a falha volta, porque uma correção que você não consegue reproduzir é uma coincidência que você vai encontrar de novo.