前言
很久没写博客了,最近正好有空可以谈谈我最近更新的家庭网络架构。我所有的网络组件都部署在一台 J1900
的机器上,安装的操作系统是 debian 10
,主板配有四个网口。我将其中三个网口合并为一个 bridge
用来构建我的私有子网,供主机和路由器插线连接,另一个网口连接光猫作为出口。
科学上网
通过在软路由上使用 iptables
+ tproxy
重定向 TCP/UDP
流量到 clash
,可以实现全局翻墙,所有设备无需设置。在讨论我遇到的问题之前,有必要了解一下 clash
在软路由上怎么进行规则判断的,换言之 clash
怎么知道我们当前的连接是否需要走代理。
DNS
软路由上的流量被重定向后,clash
只能获取的目标 ip
,但是根据 ip
地区判断是远远不够的,那么该如何获取 ip
对应的域名呢?clash
自带了一个 DNS server
,在软路由上将所有 DNS
请求转发给它,那么它就能记录域名和 ip
的对应关系。但是由于存在许多问题,这种 redir-host
模式在较新的 clash
中被删除了。它最大的问题就是无法应对 DNS
污染,例如最上游 DNS 被污染时,返回 google
的 ip
是 127.0.0.1
这种,那么该请求直接在主机上请求失败了。
FakeIP
在使用 redir-host
的过程中,我经常遇到网络不正常的情况,迫于无奈只能切换到 fake-ip
模式。它的原理就是 clash
的 DNS server
返回一个虚假的内网 ip
,例如 198.168.0.0/16
,同时记录 ip
与 hostname
的对应关系,这样就可以避免 DNS
污染的问题。当然 fake-ip
也有缺陷,例如 QQ
的某些域名指向就是 127.0.0.1
,因为需要和 QQ
客户端通信,另外 Windows
的网络探测服务也无法在 fake-ip
模式下工作。对于这些特殊的域名,我们可以在 clash
配置中过滤掉,让它们返回真实的查询结果。
1 | dns: |
游戏加速
游戏加速说到底还是代理,只不过是延迟很低的线路,使用小米等路由器同时开启翻墙和游戏加速插件肯定会有冲突,但是在自己配置的 Linux
路由器里,我可以精准地控制每一条规则。
docker
一年前我的方案是将 openwrt
版本的 UU加速器
跑在 docker
里,它其实是一个为主机加速提供的方案,所以我写了个 python
脚本将我的软路由伪装成 PS4
:
1 | #!/usr/bin/env python3 |
想象一下,UU加速器
在容器 172.17.0.3
中广播 UDP
包,然后这个脚本在软路由的 172.17.0.1
上收到了这个包,并成功回复让对方认为自己是一台 PS4
。然后在手机 APP
上就可以开启加速,这个时候我们只需要在软路由上将需要加速的包路由给 172.17.0.3
即可,流量会顺利地从容器的 tun
网卡进入 UU加速器
的专线。
1 | # https://github.com/Hackerl/docker-uuplugin |
启动后添加路由规则:
1 | ip rule add fwmark 0x163 table 0x163 |
这个路由规则的意思是如果流量带有 0x163 标志,那么就路由给 172.17.0.3
,接着我们可以在 iptables
里给特定流量打上标志:
1 | iptables -t mangle -N UUPLUGIN |
例如我们给 UDP
高端口号的包打上标志,这其实是大多数网络游戏的通讯方式,例如英雄联盟。
虚拟机
使用 docker
运行 UU加速器
进行游戏加速也存在问题,一就是可选择的节点并不多,毕竟这是主机加速方案,二就是它的 iptables
限制了只代理某些源 ip
。由于第二个限制,我们没有办法直接在它的容器中部署 socks5
代理,以集成到 clash
规则中,当然我可以修改它的规则,但是每次启动加速都要修改的话太麻烦了。此时我有了一个大胆的想法,我可不可以在软路由上跑一个 windows
虚拟机,然后将流量转发到虚拟机中去加速,一想到 J1900
廉价的性能我心里就充满了问号。
我首先安装了一个 windows 7
虚拟机,连上 VNC
后果然很卡,然后部署了一个简单的 socks5
代理,接着将英雄联盟台服的域名全部抠出来,写好 clash
规则:
1 | script: |
尝试了一下确实可以工作,所有英雄联盟相关的流量都由虚拟机代理。那么接下来要做的就是怎么把这台虚拟机压缩一下,J1900
的确有点带不动,而且为了一个游戏加速我也并不是很乐意耗费这么多 CPU
和内存。我在网上找到了一个 Windows 7 Super-Nano Lite
,镜像居然只有 316MB
,确定这可以跑起来吗?我安装了一下确实跑起来了,但是包括网络驱动之类的东西全部被删除了。
磁盘占用只有 600MB
,内存也只用了 200MB
,为了进一步优化性能,我使用 virt-install
安装虚拟机时设置的网络和磁盘驱动都是 virtio
:
1 | wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.173-4/virtio-win-0.1.173_x86.vfd |
在使用 VNC
安装的时候会提示找不到驱动器,因为 windows 7
无法识别 virtio
设备,所有在界面上点击加载驱动,加载 virtio-win-0.1.173_x86.vfd
软盘中的磁盘和网络驱动。安装后的系统是无法显示中文的,因为中文包也被删除了。找一台完整的 windows 7
机器,拷贝 C:\Windows\System32\C_936.NLS
以及 C:\Windows\Fonts\msyh.ttf
到虚拟机中,中文就不会乱码了。安装完加速器后,需要部署一个支持 TCP/UDP
的 socks5
代理,我找了一圈发现没几个支持 UDP
的,最后选择了 3proxy
,配置文件如下:
1 | #!/usr/local/bin/3proxy |
搞完这个之后在英雄联盟台服开了把大乱斗,延迟居然才 30 比国服还低,看了下软路由的资源占用,虚拟机低负载时 qemu
进程稳定占用 45% 左右的单核 CPU
,算是可以接受的范围,毕竟它只是 J1900
啊!有了这个比较稳定的虚拟方案后,其实可以将一些 windows
独占的软件放到里面,通过软路由上的 smb
共享文件,但是我现在使用的百度云、迅雷都是使用的 docker
+ noVNC
方案,暂时没有其余想折腾的东西了。