通 途

首页 / 翻墙 app 接住哪些流量

系统层与浏览器层 · 分界

翻墙 app 接住哪些流量:
分界线画在哪一层

同样是「装上就能用」,一个浏览器扩展和一个系统层的 app 接住的东西差了整整一台设备。 分界线不在功能表上,在它跟操作系统要的是哪一个接口。

同一台设备上,谁的流量会被接住
这一类流量浏览器扩展 系统层 app为什么
浏览器里打开的网页 接住接住 请求由浏览器自己发出,两种方案都在它的作用域里
手机上的独立应用 接不住接住 它们不经过浏览器,扩展看不到这些请求
桌面软件 接不住接住 同上;桌面软件自己开连接,不借浏览器的手
命令行工具 接不住接住 由系统网络栈发出,只有接在这一层才拿得到
客户端自己的请求 不适用刻意排除 否则它会把自己的流量绕回自己,连不出去

一个 app 是怎么「接住」流量的

它要的是系统接口,不是浏览器接口

扩展装在浏览器里,能力边界就是浏览器给它的那一圈:它能看见并改写浏览器自己发出的请求, 其余一概看不见。系统层的 app 走的是另一条路 —— 向操作系统申请建立一条虚拟网络接口, 让系统把出网的数据先交到这条接口上。这就是安装时那一次「是否允许建立 VPN 连接」的提示, 它不是形式,它就是这个能力本身。

这一次授权之后,谁的流量会被交过来,就不再由应用决定,而由系统决定。 所以命令行工具不需要单独设代理,桌面软件也不需要,因为它们都在同一个系统里出网。 反过来,一个方案如果要你去每个工具里填一遍代理地址,那它接的就不是这一层。

接住之后,交给谁

虚拟接口拿到的是原始数据包,而加密隧道说的是另一种语言,中间需要一次转译。 通常的做法是在本机开一个只有本机能连的中转端口,把包整理成标准的代理请求再送出去。 这里用的是 SOCKS 协议第 5 版,它把流程写得很直白:据 RFC 1928 第 3 节与第 4 节, 客户端要先与代理完成一次协商,之后才带着目标地址发起转发请求。 协议里没有任何一处需要说明发起方是哪个程序 —— 到了这一步,来源已经不重要了。

这也解释了一个常见的疑问:为什么同一条隧道能同时给十几个不同的程序用。 因为它们在更早的一层就被合并成了同一种请求,隧道看到的是请求,不是程序。

为什么这件事值得你分清

因为它决定了「能不能用」这个判断该怎么下。只在浏览器里试一次就下结论, 是这一类工具最常见的误判:浏览器通不代表其他程序也通,而如果你真正要用的是 命令行工具或某个桌面软件,浏览器那次成功没有告到你要的那件事。

挑工具的时候,这一层比宣传页上任何一项都更值得先确认。它不需要看评测, 装好之后用你真正要用的那个程序试一次就知道了。

一个花两分钟、不用信任何人的验法。 用你真正要用的那个程序(不是浏览器)去取一次自己的出口地址, 记下连接前后的两个结果。变了,说明这个程序的流量确实进了隧道;没变,说明它绕过去了。 这个方法的好处是它测的是你自己的用法,而不是别人替你测过的场景。

接住之后,还有两个分岔

  1. 分流:不是所有流量都值得进隧道

    本来就通的站点,绕一趟境外只会更慢。安卓端因此可以按应用划分, 把这部分留在隧道外面;桌面端没有等价的系统能力,境内境外一律经过境外出口。 这一条写在这里,是因为它是实现层面的差距,而不是某个开关忘了打开。

  2. 排除名单:谁必须留在外面

    客户端自己的请求必须绕开隧道,否则它会把自己的流量送回自己,结果是谁都出不去。 除此之外,安卓端还允许你手动把指定应用排除掉 —— 有些应用会因为出口地址与 它记录的常用位置不一致而要求你重新验证,把这类放在隧道外面通常更省事。

  3. 断掉的时候会怎样,两端不一样

    安卓端的隧道由这个进程持有:进程被系统回收,隧道就跟着断,之后流量按普通网络发出。 通知栏那条常驻提示因此是个有用的信号 —— 它在,说明进程还在。

    桌面端相反,这一点值得单独记住。负责转发的子进程不随主程序一起结束, 它可能继续持有虚拟网卡和默认路由,于是流量既出不去、也不会退回普通网络, 表现为整台机器都不通。这种时候重新启动一次客户端就好,它在启动时会清掉上一轮的残余进程。 换句话说,桌面端主程序没了并不等于「没在保护」,而是「谁都走不了」。

    还有一种情况与上面两种都不同:提示还在、网页却打不开,那说明进程活着而链路不通。 客户端在连上之后会做一次真实探测,探测不通就不显示已连接。

取用

安卓 安卓安装包约 30 MB,直接安装。首次连接时授权一次,之后不再询问。 下载 APK
Windows 桌面端安装包。桌面端全部流量走隧道,不提供分流。 下载安装包
其他 安卓与 Windows 客户端已上线,macOS 与 Linux 开发中。iPhone 暂无原生客户端。 备用线路

问答

本机那个中转端口,别的程序能连上吗?

能,而且这正是它服务所有程序的方式。那个端口只监听本机回环地址,机器之外连不进来;同一台机器上的程序则都可以把请求交给它,所以浏览器、桌面软件和命令行工具最终用的是同一条隧道。换句话说,隧道并不按程序分配,它只处理请求,不区分请求是谁发出的。

为什么装好之后,还是有某个软件连不上?

先看它是不是被排除在隧道外面了。客户端自身的请求必须绕开隧道,否则会绕回自己;安卓端还允许你把指定应用排除掉,排掉的那个自然不走隧道。其次是有些程序把服务器地址写死在自己内部、或者自带一套连接逻辑,这类要看它有没有提供网络相关的选项。最后一种是目标站点在拦,这跟流量接在哪一层没有关系。

为什么安卓端可以让国内流量不进隧道,桌面端不行?

这其实是两件事,先分开说。让国内网站不进隧道靠的是按域名分流,规则写在配置里;把某个应用整个留在外面靠的是按应用划分,那是系统提供的能力。安卓端两样都做得到。桌面端缺的不是操作系统的能力,而是我们这一侧的实现:虚拟网卡持有默认路由,而客户端自己的进程在桌面端没有被排除出去,所以一旦放行一部分流量,它会绕回自己。这是实现层面的差距,不是设置里少了一个开关。

app 被系统杀掉之后,隧道还在吗?

分平台,而且两边方向相反,值得说清楚。安卓端隧道由这个进程持有,进程没了隧道就跟着断,之后流量按普通网络发出。桌面端不是这样:负责转发的子进程不随主程序一起结束,它可能继续持有虚拟网卡与默认路由,于是流量既出不去、也不会回到普通网络,表现为整机都不通。遇到这种情况重新启动一次客户端就好,它在启动时会清掉上一轮留下的残余进程。

安卓上把某个应用排除在隧道外,会影响别的应用吗?

不会,排除是按应用生效的,其他应用照常走隧道。这个开关最常见的用途是把对出口位置敏感的应用放在外面 —— 有些服务会因为你的出口位置与它记录的常用位置不一致而要求重新验证,留在隧道外通常比反复验证省事。要提醒的是,被排除的应用也就不再经过隧道了,这是一个取舍,不是一个纯粹的优化。

怎么自己确认某个软件的流量真的被接住了?

用那个软件本身去访问一个会回显来源地址的页面,比较连接前后拿到的地址。地址变了,说明这个软件的流量确实走了隧道;地址没变,说明它绕过去了。不要只在浏览器里测一次就下结论,浏览器通不代表其他程序也通,这正是本页要讲的分界。

它要一个 VPN 权限,能看到我什么?

那个权限的作用是允许建立一条虚拟网络接口,流量要出境必须经过它,没有别的办法。至于我们这一侧留下什么:出口服务器的访问日志是关闭状态;会话记录表里没有目标地址、域名或 URL 字段。判断任何一家服务时都可以问这两句,比问「你们记不记日志」有用。