Android 的 VPN 图标亮着,流量为什么没走隧道?
钥匙图标只说明某个应用占用了虚拟接口,并不代表流量已经离开手机。请检查配置类型、按应用范围和拦截策略。
VPN 钥匙出现在状态栏,浏览器能打开网页,而网站看到的地址仍是你的家庭宽带。这种组合在 Android 上是正常的,因为图标只说明某个应用占用了虚拟网络接口,并不代表流量已经从远程服务器出去。本地过滤类应用用的是同一套机制。先弄清楚服务到底在做什么,再去找服务商的麻烦。
图标只表示某个 VPN 服务占用了接口
Android 的 VPN 服务允许应用创建虚拟接口,并接收被路由进该接口的数据包。接下来做什么完全由这个应用决定:可以转发到远程服务器,可以过滤,也可以直接丢弃。钥匙图标只报告有服务持有该接口,不报告数据包的去向。所以过滤应用和完整隧道在状态栏里长得一模一样。
adb shell dumpsys connectivity | grep -i vpn
adb shell settings get global always_on_vpn_app
同一用户或同一配置文件在同一时间只能有一个 VPN 服务处于活动状态,这是有文档说明的行为,不是缺陷。第二个应用尝试连接时,要么抢占,要么失败,第一个应用的流量就不再被处理。如果你一连接隧道过滤应用就退出,那多半就是这个竞争造成的。
系统原生配置与应用自带 VPN 不能互换
平台提供的 IKEv2 配置和自行实现 OpenVPN 或 WireGuard 的应用是两套产品,菜单也不一样。面向 IKEv2 的平台 API 从某个 Android 版本才开始提供,各厂商的定制系统也未必把同样的选项放在同一个位置。拿另一台手机的截图当兼容性依据并不可靠。
adb shell getprop ro.build.version.sdk
adb shell dumpsys package com.example.vpn | head -40
让协议与支持它的客户端配对,并通过服务商验证过的渠道获取配置,而不是把它粘贴到无关的表单里。端点地址只说明连到哪里,不说明哪个应用会说这个协议。导出的配置和二维码都应当作凭据对待,因为二维码图片可能包含完整密钥。如果配置是给另一个客户端签发的,应重新签发,而不是转换格式。
按应用规则和工作配置文件会改变作用范围
Android 支持按应用划分 VPN,因此浏览器可以在隧道之外,而邮件应用在隧道之内。个人配置文件和工作配置文件是两个独立环境,各自有处于活动状态的服务。从错误的应用去查地址,是这一领域最常见的误判之一。
先看包含列表和排除列表,再用你真正关心的应用去测试。工作配置文件的隧道不覆盖个人应用,个人隧道也不覆盖工作应用。同样的隔离也解释了为什么某个公司资源在一个配置文件里能用、在另一个里却失败,而两者看不出任何配置差异。把配置文件环境写进工单,因为它甚至会改变哪些设置生效。
如果被测应用不在隧道作用范围内,就到此为止。这是策略选择,不是故障。
测试真正离开手机的东西
测试公网和私网目标、两种地址族、两种接入网络。然后把结果与应用自身的作用范围对照,因为一个应用能打开网页,说明不了另一个应用。在从 Wi-Fi 切换到移动数据之后要重测,因为重新连接可能落到另一条路径上。
adb shell ip rule
adb shell dumpsys netpolicy | grep -i vpn
Always-on VPN 与「无 VPN 时阻止连接」是相关但不同的两项,严格拦截可能让强制门户登录失效,直到你按文档步骤处理。Private DNS 设置也可能与配置里的解析器相互作用,所以盲目替换组织的 DNS 只会制造新故障。如果锁屏后隧道就断,先读 VPN 开发者指南中关于后台运行和电池优化的部分,再考虑重装任何东西。
需要盯住的症状是图标与路径之间的落差。钥匙只说明某个服务占用了接口;只有在目标应用、目标网络上做测试,才能知道流量去了哪里。两者都查,下一次「VPN 坏了」的报告就会好定位得多。