跳过正文

v2rayN 和校园 VPN 一起开,我的流量到底走哪条路?

·3557 字·8 分钟
作者
你的名字
这里是我的个人博客。

前言
#

最近不在学校里,但是想要调用学校的模型,就需要开 VPN 才可以访问学校的资源,但是我又开着一个美国的节点,我不知道会不会产生冲突,所以便问了一下 GPT。

他的回答是:

但如果学校代理和国外代理都是“VPN”,那就比较麻烦了。

我才意识到,我之前一直把代理和 VPN 理解成了同一种机制。

我以前的理解是:VPN 就是一个客户端,主要是给用户用的。但今天我才意识到,VPN 首先是一种网络技术,而不是某个客户端软件的名字。

下面就是我的理解纠正之路。

我在用的到底是什么
#

为了更好地讲清楚这两者的区别,下面我会用自己正在使用的两个东西来举例。

我的代理
#

为了访问 GitHub 这些网站,我买了一台 VPS,通过 3x-ui 面板配置代理协议。

访问 GitHub 的时候,Chrome 会根据 Windows 的系统代理配置,把需要代理的请求交给 127.0.0.1:10809

v2rayN 使用的代理核心在这里接住请求,判断这个请求是否需要走代理。如果需要,它会另外发起一个到 VPS 的连接;VPS 再代我去访问 GitHub。

大致可以理解成:

Chrome
Windows 系统代理
127.0.0.1:10809
v2rayN 代理核心
VPS
GitHub

GitHub 那边看到的网络连接来源就是 VPS 的 IP,而不是我家里的公网 IP。

我的 VPN
#

我有调用学校大模型的需求,但只有通过校园网才能访问。

学校提供了一个叫 iWAN 的 VPN。电脑上打开它之后,它会在我的电脑和校园网络之间建立一条网络隧道。

而且电脑里还真的“多出来”了一块网络接口。

开 iWAN 之后跑一下 ipconfig

我在 iWAN 连接状态下看到的是:

未知适配器 Panabit:

   IPv4 地址 . . . . . . . . . . . . : 10.10.x.x
   子网掩码 . . . . . . . . . . . . : 255.255.255.255

而把 iWAN 断开后,再运行一次 ipconfig

未知适配器 Panabit:

   媒体状态 . . . . . . . . . . . . : 媒体已断开连接

也就是说,Panabit 这个虚拟网络适配器本身还在,但连接状态发生了变化:

状态PanabitIPv4 地址
iWAN 已连接正常连接10.10.x.x
iWAN 已断开媒体已断开连接

iWAN 连接成功后,Windows 里出现了一个正在工作的虚拟网络接口,并且这个接口获得了 10.10.x.x 这个地址。

这里需要说明一下,并不是所有 VPN 都一定会以“多出一块虚拟网卡”的形式出现。这是 iWAN 在 Windows 上的一种具体实现方式。

对我来说,它带来的一个非常直观的变化就是:

人在校外,但电脑被“接回”了学校的网络里。


代理和 VPN 的区别
#

一个单向,一个双向
#

代理是单向的。

它更像是:我把一个网络请求交给中间人,由中间人替我去访问目标。

我能通过这个中间人“出去”,但这个代理节点本身并没有把我接入它所在的网络。

VPN 是双向的。

它建立的是一条网络隧道,把我的设备连接到另一个网络中。学校的 iWAN 就属于这种情况:它不只是帮我访问某个网站,而是让我的电脑获得了一个可以用于访问校园网络资源的网络连接。

这也是为什么:

开着 iWAN,我可以直接 SSH 到实验室服务器,而挂着代理节点却不行。

这里的“单向”和“双向”主要是为了帮助理解两种机制的区别,并不是说代理协议在技术上只能进行单向通信。

例如 HTTP、SOCKS5 等代理本身也可以承载双向的数据传输。真正的区别在于:

代理主要是在帮某个网络请求寻找一个中转站,而 VPN 则是在设备与远程网络之间建立一条网络连接。


出口 IP 不等于本机 IP
#

这里有个我一度想岔的地方。

我本来想用“有没有 IP”来区分两者,但发现说不通——用代理的时候,我明明也“有”了一个美国 IP。

后来才想明白,这是两个不同的概念:

  • 出口 IP——目标网站看到的网络连接来源地址。代理确实可以改变它。
  • 本机 IP——配置在我电脑网络接口上的地址。

比如我连接美国代理节点之后:

我的电脑
美国代理服务器
GitHub

GitHub 看到的:
美国代理服务器的 IP

这个美国 IP 属于代理服务器,我只是借它转发流量,并没有把这个 IP “装”到自己的电脑上。

而连接 iWAN 后:

我的电脑
Panabit 虚拟网络接口
校园网络

操作系统里确实出现了一个正在工作的虚拟网络接口,并且这个接口拥有一个地址:

10.10.x.x

那我之前的误解是从哪来的
#

前言里我说“以为 VPN 就是个客户端”,这个误解其实是有来源的。

像 NordVPN 这类商业 VPN 服务,用户通常最直接感受到的功能就是:

连接一个服务器,然后自己的互联网出口 IP 发生变化。

它们同样可以使用 VPN 技术建立加密隧道,但并不一定像学校 VPN 一样,让你真正接入某个组织的内部网络。

例如学校 VPN:

我的电脑
VPN 隧道
学校网络
学校内部资源

而商业 VPN 更常见的是:

我的电脑
VPN 隧道
VPN 服务器
Internet

所以我以前接触到的 VPN,主要都是后者。

这也解释了为什么我以前会觉得:

VPN 和代理好像就是一回事。

它们确实可以实现一些相似的效果,比如改变访问目标看到的出口 IP,但它们的网络机制和使用场景并不完全相同。


那到底是谁在决定走哪条路
#

对于我现在这套网络环境,可以把一个请求的处理过程粗略地理解成三层:

第一层:这个程序要不要走代理?
第二层:代理客户端内部怎么分流?
第三层:操作系统最终从哪条网络路径出去?

第一层:这个程序要不要走代理
#

网络请求流程图

程序的代理配置决定,跟路由表不是一回事。

我用的是 v2rayN 的“自动配置系统代理”,它会把 Windows 的系统代理指向本地端口。

例如:

代理服务器:127.0.0.1
代理端口:10809

它表达的意思其实很简单:

“如果程序要使用代理,就把请求交给我电脑上的 127.0.0.1:10809。”

Chrome 这类通常遵循系统代理设置的程序,就会把请求交给 v2rayN。

而 SSH 通常不会读取 Windows 的系统代理设置,因此它会直接跳过这一层。

这也解释了一个很常见的现象:

有些软件明明开着代理,却照样连不上。

原因可能很简单:

这个软件根本没有使用你的代理。


第二层:v2rayN 内部的分流
#

如果请求进入了 v2rayN,那么还要再判断一次:

direct   → 直连
proxy    → 走代理节点
block    → 拦截

具体怎么判断,取决于你的代理客户端和配置规则。

常见的判断依据包括:

  • geosite:根据域名分类
  • geoip:根据 IP 地址所属区域分类

这一层顺便解释了一个我一直好奇的问题:

为什么开着代理访问百度也没有明显变慢?

因为百度的流量可能命中了 geoip:cn 等直连规则,于是 v2rayN 判断:

百度
direct
不走美国节点

所以虽然 v2rayN 开着,但这个请求实际上没有经过我的美国 VPS。


第三层:操作系统路由表
#

如果一个连接最终需要直接从我的电脑发出去,那么操作系统还需要决定:

这个数据包应该从哪块网络接口出去?

这就是路由表负责的事情。

可以通过:

route print -4

查看 Windows 当前的 IPv4 路由表。

我这台机器上,跟这件事相关的是这几行:

网络目标           网络掩码          网关            接口            跃点数
0.0.0.0           0.0.0.0          192.168.x.x    192.168.x.x     45
xxx.xxx.192.0     255.255.192.0    100.100.x.x    10.10.x.x        2
xxx.xxx.64.0      255.255.224.0    100.100.x.x    10.10.x.x        2

第一行是默认路由:

0.0.0.0/0

它指向:

192.168.x.x

也就是我家里的路由器。

后面几行则是 iWAN 插进来的校内网段:

xxx.xxx.192.0/18
xxx.xxx.64.0/19

它们的网关都是:

100.100.x.x

接口则是刚才那块虚拟网络接口:

10.10.x.x

这里还有一个容易混淆的地方
#

前面三层看起来像是:

程序
v2rayN
路由表

但实际上,如果请求走了代理,路由表处理的就不是“Chrome → GitHub”这条原始连接,而是代理客户端自己建立的连接。

例如 Chrome 访问 GitHub:

Chrome
Windows 系统代理
v2rayN
代理客户端判断:proxy
建立到 VPS 的连接
操作系统路由表决定:
这个“到 VPS 的连接”从哪块网卡出去
家里的物理网卡
VPS
GitHub

而如果 v2rayN 判断:

direct

那么就没有中间的代理服务器:

Chrome
操作系统网络栈
路由表
物理网卡 / Panabit 虚拟网卡
目标服务器

所以我后来发现:

路由表并不是决定“这个网站走不走代理”的地方。

它更像是负责最后的网络路径选择。


走一遍具体例子
#

把三层串起来看:

场景第一层第二层第三层
Chrome 访问校内网站进 v2rayNdirect命中 xxx.xxx.192.0/18 → iWAN
SSH 连实验室服务器跳过跳过命中 xxx.xxx.192.0/18 → iWAN
Chrome 访问 GitHub进 v2rayNproxy代理客户端连接 VPS 时 → 默认路由 → 物理网卡
Chrome 访问百度进 v2rayNdirect命中默认路由 → 物理网卡

前两行放在一起其实很有意思:

同一个目标、同样的最终结果,但走过的层数不一样。

浏览器访问校内网站时,假设 Chrome 使用系统代理,而且没有提前把这个地址排除在代理之外,那么它可能会先把请求交给 v2rayN。

但 v2rayN 判断这个请求应该:

direct

于是它不会通过美国节点,而是让这个请求直接连接目标地址。

之后,Windows 的路由表发现:

xxx.xxx.240.204

属于:

xxx.xxx.192.0/18

于是最终把它送进 iWAN。

而 SSH 则完全不同。

SSH 通常不会读取 Chrome 使用的系统代理设置,所以它从一开始就没有进入 v2rayN:

SSH
Windows 网络栈
路由表
xxx.xxx.192.0/18
iWAN
实验室服务器

这也是为什么:

同样是访问学校服务器,Chrome 和 SSH 可能走了不同的路径,但最后都进入了学校网络。


总结
#

搞明白之后最大的感受,不是学会了两个定义,而是以后网络出问题,我知道该从哪一层开始查了:

先看程序走不走代理,再看代理分流规则判了什么,最后看实际建立的连接由哪条路由出去。

以前是稀里糊涂地开着两个东西,居然一直没出问题,还以为是自己运气好。

现在至少知道:

代理负责“中转”,VPN 负责“接入网络”,分流规则负责“选择”,路由表负责“找路”。

而我这次之所以能同时开着学校的 iWAN 和美国代理,并不是因为它们“互不干扰”,而是因为:

不同的流量最终被分配到了不同的网络路径。

参考
#

感谢这些帮我理清思路的资料:

  • USTC iWAN 官方使用说明
  • v2ray / Xray 官方文档 · 路由配置
  • 和 GPT 掰扯了半天的那次对话