代理模式分为:
- 系统代理:将数据交给本地 http/socks5 服务
- TUN/TAP 代理:使用虚拟网卡接管全局流量
- 真 VPN 代理:封装网络层数据包
其中 TUN/TAP 代理是目前用的最多的代理模式。
无代理下的访问流程
先创建常见的家庭网络场景:
路由器通过PPPoE拨号获取运营商分配的公网IP,假设为
2.2.2.2
,同时路由器作为局域网网关也会有自己的内网IP,假设为192.168.0.1
,家里的所有网络设备都会连接这台路由器,路由器通过DHCP为每一台局域网设备分配一个内网IP以及默认网关、DNS等信息,一般情况下默认网关、DNS服务器都是路由器,这是最常见的家庭网络拓扑。为了了解不同代理模式的行为,我们需要再细化到操作系统的网络协议栈。
以TCP/IP的四层模型为例,假设浏览器发送了访问百度的请求,数据包会经由操作系统的网络协议栈一层层的进行封装:
首先 应用层会将其封装成http数据包
再由传输层以tcp的方式封装数据,其中包含了源端口(忽略)和目标端口(
80
)接着网络层会加上源IP(内网IP)和目标IP(百度IP,假设为
3.3.3.3
)接口层会封装MAC地址
并将数据从物理网口通过网线发送到了默认网关(路由器),路由器会对数据包进行NAT处理,将数据包的内网IP替换为运营商分配的公网IP(
2.2.2.2
),再将数据包发送到互联网经过互联网路由器的路由,最终百度的服务器会从网口收到我们发给他的数据包,发数据的过程是封装,而收数据的过程就是解封装,这里不再赘述,它会一层层的将我们的数据包解开,最终得到我们的意图是访问百度,于是乎他会将百度首页的内容通过协议栈像上面一样一层层的封装,从网口发出,并通过互联网的路由,最终我们的路由器会收到百度返回的数据包,路由器会进行NAT处理,将公网IP恢复成内网IP,并将数据发送给我们的电脑,电脑将数据包一层层解封装后返回给浏览器,百度首页的内容也就呈现在我们的面前。
系统代理模式
接下来我们引入代理,第一种最常见的是通过socks或者http代理的方式
我们平时使用基于clash、v2ray、xray等内核的代理客户端都支持这种方式,也是必须要能支持的,大部分电脑用户用这种方式比较多。
以clash为例,开启系统代理后,遵循系统代理配置的软件就会将访问网络的请求交给clash处理。
由于clash接管了系统代理,浏览器访问谷歌的请求会交给clash,clash收到数据后会根据分流规则判断是否需要走代理,确定访问谷歌需要走代理:
clash会将数据进行加密封装,具体怎么加密取决于clash当前使用的节点是什么协议,这里假设clash当前选中的节点是服务器IP为5.5.5.5的ss节点,所以会使用ss协议进行加密封装:
//TODO 节点搭建系列加密封装
加密封装后的数据会通过操作系统的网络协议栈一层层的进行封装,传输层会加上节点服务器的端口(
8388
),网络层会加上节点服务器的IP地址(5.5.5.5
)最后交给路由器,路由器进行NAT转换后将数据发送到了节点服务器,节点服务器收到数据后,解封装,解密,然后帮我们访问谷歌,最后将谷歌的数据进行加密,封装,再返回给我们,收到节点服务器的数据后,通过网络协议栈一层层的解封装,加密数据会交给clash,clash对数据进行解密后再转交给浏览器,这样我们就成功的访问了谷歌(中间图示自行脑补)。
这就是系统代理的执行流程,使用非常方便,但是存在比较棘手的问题:并不是所有软件都遵循系统代理,除去浏览器绝大部分软件都不会走系统代理,甚至连设置代理的地方都没有,行为完全取决于软件开发者,并且系统代理一般都是http代理而非socks5,http代理不支持udp,游戏也是没法玩的,并且游戏一般都不会添加代理功能,所以使用系统代理模式一般都是看看网页聊聊天,如果说系统代理能满足你的需求,那就是最方便省事的模式了。
TUN/TAP 虚拟网卡模式
如果设置好系统代理后软件还是无法使用,可能是软件并没有走代理,这个时候就可以使用TUN/TAP模式。
这种模式的原理是创建一张虚拟网卡,从网络层接管系统所有流量,因为所有发往互联网的流量都必须经过网络层的封装,在这层进行拦截就能够获取所有应用产生的网络数据,这是目前主流的模式,我们的手机默认就是这种模式,所以才能实现所有app科学上网,软路由接管全家的科学上网也是同样的原理,正因为有了TUN,才能让科学上网达到近乎完美的状态。
还是以clash为例,假设浏览器无视clash接管的系统代理,数据不会交给clash处理,但是clash开启了TUN模式,开启之后会创建一张虚拟网卡,此时 浏览器访问谷歌:
数据会直接来到网络协议栈,应用层会封装http头部,http请求会使用tcp进行封装,接着来到网络层,目标IP是谷歌的IP,假设我们已经知道了是8.8.8.8,那源IP是什么?
由于clash的TUN模式开启了一张虚拟网卡,也就是说数据会有两个出口:要么发给clash的虚拟网卡,要么发给物理网卡,具体发给哪张网卡是通过电脑的路由表来决定的。
windows可以通过
route print
命令来查看路由表,默认路由是这条通过本机IP192.168.0.2
发给网关,也就是路由器的192.168.0.1
,只有当下面所有路由条目都不匹配的时候 才会走默认路由:clash在开启TUN模式的时候会自动帮我们添加路由,可以看到这两条路由条目:
通过网络号和子网掩码我们可以算出,clash添加的这两条路由涵盖了所有IPv4的地址,也就是说,访问任何ip的时候都会从
198.18.0.1
这个接口,将数据交给198.18.0.2
这个网关。也就是说,数据会发给clash开启的虚拟网卡,所以源IP为198.18.0.1
。这里实现了拦截。如果你使用TAP模式则还会向下封装MAC地址,但对我们来说MAC并没什么作用,没必要向下封装,所以更推荐使用TUN模式。
此时数据已经来到了clash的虚拟网卡。clash可以直接读取该网卡接口中的数据,并对其进行解析
根据分流规则决定数据是否需要走代理。
如果需要走代理,就使用当前选中的节点对数据进行加密,发给相应的节点服务器,封装过程都是一样的。
为避免流量环回,clash会帮我们设置好出口为物理网卡,从物理网口将数据发送出去。
当收到节点服务器返回的数据时,通过网络协议栈一层层的解封装,数据会来到clash:
clash对数据进行解密,然后通过虚拟网卡将数据封装成网络层的数据包再发回给浏览器,这样我们就成功的访问了谷歌。
这就是在网络层进行代理的TUN模式。
在系统代理模式下,软件可以不走系统代理,那么TUN模式做的就是无视软件走法,通过配置路由表接管系统所有流量。
透明代理
不过非常严格的程序或者游戏可能会检测电脑是否开启了虚拟网卡代理。
为了让代理过程对电脑完全透明,可以将clash的虚拟网卡转移到路由器里,这样局域网内的设备无需运行任何代理工具,所有设备上网流量必将经过网关路由器,路由器的物理网卡接收到数据后会转交给clash,接下来的流程就和电脑上是一样的了,加密封装 然后转发到互联网即可,电脑没开代理,程序和游戏当然也就检测不出来,这种称之为透明代理。
前提是你家的路由器能够安装clash,这也是软路由的由来
可以试试用虚拟机或者闲置的安卓手机充当软路由,也是一样的原理:
真正的VPN模式
这种虚拟网卡模式和真正的VPN已经非常接近了,但是也只能说非常接近,还不是真正的VPN,因为我们用的ss、vmess、trojan等主流的协议,都无法封装网络层的数据包。
最直观的感受就是
ping
命令这个网络层的工具:当我们使用clash的TUN模式ping谷歌的话,会返回一个假的延迟:这个一毫秒的延迟是直接从虚拟网卡返回的,并且如果使用fakeIP模式的话还会直接返回一个假的IP,因为ss、vmess等协议无法代理网络层的icmp协议,而ping就是icmp协议的工具。
真正的VPN可以代理网络层,所以使用真正的VPN WireGuard是可以ping通谷歌的,可以看到延迟是真实的。
要了解什么是真正的VPN,就需要先来了解一下VPN的全称:Virtual Private Network,译为虚拟专用网络或者虚拟私有网络。
什么网络是私有网络?家里的局域网就是私有网络,我们无法直接和没有公网ip的电脑进行通信,除非连上同一路由器,在同一个私有网络里。什么是虚拟?顾名思义,就是物理不存在。
虚拟私有网络的意思就是不需要物理的连接上你的路由器就可以实现与你没有公网IP的电脑进行通信。
要实现这个功能的话就必须要能够封装网络层的数据包:
只有能够封装网络层的数据包,才能实现异地组网,才能实现内网穿透,才能实现虚拟的同一内网里,才能称之为VPN。
VPN是一种技术而不是某个具体的协议,VPN有很多技术实现:PPTPVPN、IPSECVPN、OPENVPN、WIREGUARD等等,具体实现细节都不太一样,但有一个是必须要支持的,就是封装网络层,如果ss协议也能够封装网络层实现异地组网,那也能称之为VPN。
然而VPN并不高级,VPN并不是为科学上网而生的,只是因为它能对数据进行加密顺便实现了这个需求,相较于ss这种专门为科学上网而生,将流量特征隐藏的协议,VPN的流量清晰明了的写着它就是VPN的流量。而且VPN分流很不方便,所以用来科学上网并不合适。目前来讲,TUN模式是比较完美的客户端代理方式,既能实现在网络层接管系统所有流量,又能在此基础上实现分流,美中不足的地方就是使用ping命令来测试网络延迟的时候就不太方便了。
至于真VPN的话 并不推荐用来科学上网,更适合有内网穿透需求的用户。