手机应用和远端服务器从不同的事实出发,谁也无法借用对方的事实。应用可以向操作系统询问自己所使用的网络,而服务器只知道连接上到达了什么。运行自己的出口会改写后者,前者则原封不动。究竟哪一个能回答你的问题,取决于问题本身。

两个观察点,两类证据

本地证据描述设备。它包括承载流量的接口、平台报告的传输方式,以及调用方应用被允许查询的内容。远端证据描述连接:源地址、协议、时序,以及应用选择发送的任何内容。没有任何一个观察点是另一个的超集。

把两者混在一起,会得到听起来精确却无法核实的说法。标记证明的是设备上某个网络对象的情况,而不是远端服务如何归类这个请求。

在争论检测之前,先写下问题针对哪一个观察点。问题究竟是某个应用能否知道隧道处于活动状态,还是某项服务能否推断请求来自哪里?这是两项彼此独立的调查,回答其中一个并不能说明另一个。

本地平台接口能报告什么

Android 提供了一个具体的标记。NetworkCapabilities 对象可以报告 TRANSPORT_VPN,而 hasTransport 用来检验该对象上是否存在这种传输方式。应用从连接服务取得该对象并读取它,前提是拥有网络状态权限。

结果是本地平台信息,而不是去查询服务商的地址段。它描述的是调用方应用正在使用的网络。

有两点限制值得注意。排除某个应用的分流隧道规则,可能让同一部手机上的答案与同事看到的不同,因为该应用可能被绑定到别处。标记之所以存在,是因为操作系统对 VPN 接口做了建模,而不是因为某个特定应用在采集它。应用是否读取该字段、是否转发、是否忽略,都是该应用自身的属性。它的清单文件和文档才是这个问题唯一可靠的来源。

adb shell dumpsys connectivity | grep -i -m5 vpn

远端服务能看到什么

服务器能看到连接的源地址、传输方式和时序,还可以用注册信息或路由数据来补充地址。它也能收到应用发送的一切,包括应用请求且用户同意时的位置。这些通道彼此独立,只有一项像地址查询。

注册在主机商名下的地址暗示隧道,而注册在住宅网络下的地址暗示家庭宽带。两者都只是统计线索,不是关于设备的事实。

住宅地址并不能把某人定位在该地址,主机地址也不会点明运营方或国家。把推断当成确定的服务,有时会出错却无法察觉。如果要求的是可靠性而不是经验法则,地址数据给不了,而承认这一点的设计比掩盖猜测的设计更诚实。

证据它回答什么它无法显示什么
本地传输标记该网络对象是否为 VPN谁在运营出口,或设备身处何地
远端源地址哪个地址到达了服务设备是否同时携带隧道
应用负载应用选择发送了什么应用没有发送的一切

自建出口为何只改变一侧

运行自己的出口会改变远端服务看到的源地址,这可能把它移出该服务与商业服务商关联的地址段。本地网络模型没有任何变化,因为隧道仍然是隧道,操作系统依然会报告它。

证据的一侧在动,另一侧不动。两者之间的落差正是预期破裂之处。

浏览器是第三种情况,有自己的接口和限制。网页内容无法读取原生的能力对象,把移动操作系统的特性当作网页可用的东西是范畴错误。如果问题涉及网站,就去研究网站实际能获得什么,而不是照搬平台 API。

用你提出的问题来决定

如果问题是某个应用能否观察隧道状态,那么平台接口才是该看的地方,答案就在该应用的代码与权限里。如果问题是服务能推断什么,连接元数据就是证据。法律或合同问题,两者都无法了断。

在收集任何东西之前,先用一句话把问题命名。那句话决定了哪个观察点重要,也能防止调查滑向另一场争论。

报告时给每项观察标上来源,因为没有标注的说法无法复核。本地标记与地址推断都有用,也都不是决定性的,所以把它们合并成一个结论是错误的。

当服务拒绝已授权的连接时,走它支持的复核渠道,而不是改动本地设置去掩盖某个信号。移除一项观察,永远不能证明其余观察已经消失。

相关文章