VPN no Android sem root: quem controla o consentimento, as rotas e o bloqueio
O consentimento, a interface TUN e a política de bloqueio do sistema são três permissões distintas. Identifique que componente controla cada uma antes de avaliar um aplicativo VPN para Android.
O root não é o que permite a um aplicativo VPN para Android transportar tráfego, bloquear fugas ou sobreviver a uma reinicialização. As pessoas resumem tudo isso como «o aplicativo tem permissão de VPN», o que esconde três mecanismos separados: um consentimento dado pelo usuário, uma interface de pacotes que o sistema estabelece e uma política de bloqueio da plataforma que não cabe ao aplicativo definir. Avaliar um projeto de VPN para Android significa perguntar em qual dos três uma alegação realmente se apoia, porque cada um tem um dono e um modo de falha diferentes.
O consentimento chega por uma atividade do sistema
VpnService.prepare() não concede nada. Ele devolve um intent à atividade de consentimento do sistema quando o consentimento falta, e o aplicativo abre esse diálogo para que o usuário aprove o serviço. Iniciar o próprio processo do aplicativo, acrescentar uma permissão ao manifesto ou exibir uma tela personalizada de «ativar VPN» não cria a concessão.
A concessão também tem escopo. Ela pertence a um pacote dentro de um perfil de usuário, então a cópia pessoal e a cópia de trabalho são decisões separadas, e o proprietário do dispositivo pode preparar um perfil gerenciado de forma diferente de um pessoal. Se o diálogo nunca aparece e prepare() devolve null, o consentimento já existe para esse pacote naquele perfil; não é prova de que o aplicativo seja confiável, apenas de que a concessão está no lugar.
A interface é um pedido que o sistema cumpre
Após o consentimento, o aplicativo descreve o que quer com VpnService.Builder: endereços, rotas, servidores DNS, MTU e, onde houver suporte, os aplicativos a incluir ou excluir. establish() pede ao sistema que crie a interface de túnel e encaminhe para ela o tráfego correspondente. O sistema detém a decisão de roteamento; o aplicativo recebe o descritor de arquivo e então precisa fazer algo útil com os pacotes.
| What you observe | Who actually owns it |
|---|---|
| VPN consent dialog | The system, triggered by prepare() |
| Routes, DNS and app lists | The app requests them; the system applies them |
| One active VPN per profile | The platform; a new service replaces the old one |
| Always-on and block-without-VPN | Device policy enforced by the platform |
Essa tabela é a arquitetura em um só lugar. O aplicativo participa do tratamento de pacotes; ele não é dono da interface, da tabela de roteamento nem do número de serviços que podem rodar.
O socket do túnel tem de escapar do próprio túnel
A conexão que transporta o tráfego cifrado é ela mesma um socket. Se for encaminhada de volta para a interface que o aplicativo acabou de criar, o túnel depende do túnel e trava. VpnService.protect() liga esse socket à rede subjacente para que ele contorne a captura, e por isso um cliente correto protege seu socket externo antes do primeiro aperto de mão.
adb shell dumpsys connectivity | grep -i -A5 vpn
adb shell settings get global always_on_vpn_app
adb shell settings get global always_on_vpn_lockdown
Esses comandos mostram a rede VPN instalada, o pacote de ativação permanente e se o bloqueio está definido. São observações apenas de leitura: se os valores não correspondem ao que o projeto alega, a alegação é sobre a interface do aplicativo e não sobre o estado do sistema.
O bloqueio pode pertencer à plataforma
O Android documenta uma política que bloqueia conexões que não usam a VPN. Essa aplicação é um contrato da plataforma, não um aplicativo que repete tentativas de conexão em laço. O interruptor fica nas configurações de VPN do dispositivo como Bloquear conexões sem VPN, e em um dispositivo gerenciado o proprietário pode ativá-lo para o perfil inteiro. A distinção importa ao avaliar uma alegação de marketing: um cliente pode mostrar um ícone de cadeado e reconectar agressivamente enquanto o tráfego direto ainda é possível, ou os aplicativos cobertos podem ficar offline porque o sistema aplica o bloqueio.
O ícone de cadeado é desenhado pelo aplicativo, então ele só prova que o aplicativo acredita estar conectado. Se outro aplicativo perde o acesso à rede é decidido pela plataforma, então a verificação útil é ver esse aplicativo falhar com o túnel ativo.
O rótulo «sempre ativo» da loja de aplicativos também não substitui esse contrato. A ativação permanente e o bloqueio são configurações do dispositivo, muitas vezes aplicadas pelo proprietário, e o comportamento delas para aplicativos excluídos é definido pela plataforma. Leia a configuração, não o selo.
Quatro perguntas para uma revisão de projeto
Primeiro, quem consentiu: qual pacote, qual perfil, e se foi o usuário ou uma política de dispositivo gerenciado. Segundo, o que o aplicativo pediu: quais rotas, quais famílias de endereços, quais aplicativos incluídos ou excluídos. Terceiro, o que acontece quando o túnel não está disponível: o sistema bloqueia ou o tráfego recai na rede subjacente? Quarto, o que o aplicativo faz com os pacotes que recebe.
A quarta pergunta é a que o modelo de permissões não consegue responder. O consentimento e uma interface TUN provam que o aplicativo pode receber tráfego, não que o cifre, autentique um par ou se recupere de forma limpa. São propriedades de implementação, e é aí que uma revisão honesta gasta seu tempo.
Um pedido de root desnecessário não se torna legítimo por chamar o resultado de interruptor de segurança, e um diálogo de consentimento não é uma auditoria de segurança. Mantenha as três concessões separadas e cada alegação se torna verificável.