分享VPN连接
朋友喜欢打中国网游,由于操作对延迟比较敏感,遂购买“网游加速器”包月VIP,用他们的跨洋专线来降低延迟。他们想把家里变成网吧、聚众打网游,却不想重复买好多份VIP,于是我便接受挑战,研究怎么让所有电脑的流量都走“网游加速器”建立的VPN连接。
这一挑战看似简单,难点在于这款“网游加速器”只支持Windows,且在建立了PPTP或L2TP连接之后,把自己创建的网卡从“网络适配器设置”里隐藏起来了。我只熟悉在Linux下捣鼓路由表,在Windows上无从下手,但他们提供了一个突破口:虚拟机里的流量会被加速。我可以看到“网游加速器”给中国IP段添加了路由规则,随便搜索一番之后,打开了系统服务处理路由。这时,局域网里其他人可以访问这台电脑里的虚拟机了。
把问题reduce到“让虚拟机转发流量”之后,我提出了第一个方案:把虚拟机IP作为其他机器的默认网关。我立刻看到中国IP流量被分流了,但是似乎丢包率非常高;几经推理,我几乎肯定是这里运营商附送的家用路由器十分多管闲事,认为有人劫持其他人的流量;仔细排查后看到路由器上果然在汇报“DoS攻击”,但不论怎么尝试关掉多余的安全功能都失败了,这条路只得作罢。
我于是尝试第二个方案,从虚拟机中新建无线网络接入点。这台机器有450Mbps的PCIe无线网卡,VMware表示不支持分享PCIe设备给虚拟机,请氪金。我们只好找出一个USB无线网卡,分享USB设备给虚拟机。奈何USB网卡的信号质量很差,丢包率仍然不低,体验不好。我本来想直接找台有两个有线网口的电脑;结果翻箱倒柜之后,却只找到了USB-C接口的网卡,而这里所有Windows系统的电脑都没有USB-C。也罢,还是继续考验网络工程师能力吧。
Windows是可以作为VPN服务器的,按道理来说,让其他机器连入VPN之后,流量走系统默认的路由表即可。然而Windows一定要先选择一个网络连接作为出口,然后选择“分享”给连入的VPN或Wi-Fi;如前所述,“网游加速器”隐藏了自己创建的连接,如果“分享”了本地连接,所有流量都会不走加速器。我们不服,开始疯狂调整各种Windows设置,试图改掉默认行为,结果身陷囹圄,出师未捷身先死——Windows 7的网络栈被我们彻底搞砸了,虚拟机完全上不了网了。我们只得把系统打掉重装,我索性提议直接装了Windows 10,顺便打开WSL 2。
WSL 2里的Linux用了Hyper-V维护的NAT网卡,国内流量可以被分流,然而Windows却拒绝让局域网里其他的电脑的流量被直接路由给Linux。我于是提出了第三个方案,在Virtualbox里开了一台Linux虚拟机,添加了一块NAT网卡和一块桥接网卡。其他局域网机器通过桥接网卡直接连入虚拟机,然后虚拟机里用Linux iptables进行NAT,最后流量通过NAT网卡发往宿主机之后自动分留给网游加速器的VPN。我轻车熟路的在Linux里删掉了桥接网卡的默认路由,确定了流量全部从NAT网卡走,然后开始筹备其他电脑流量往虚拟机转发。为了避免路由器再捣鬼,我又搭了一下Wireguard隧道,然后开着scapy再三检查数据包确实往来正常。我发现,在有多个设备同时连虚拟机里的“出口”Wireguard节点时,必须让每个设备peer条目里配置不同的IP段,否则一个配置会把另一个配置“挤掉”,似乎这个IP段同时扮演了ACL和路由表两个角色。终于,网络部分的问题算解决了,其他电脑都共享了“网游加速器”的低延迟跨洋VPN,只是一个数据包要被来回NAT四层(Wireguard网段、Virtualbox NAT网卡、网游加速器VPN网段、中国公网IP)。
这时还有最后一个小问题,网游的反作弊系统在进入游戏之后报告“有其他异常程序正在运行”。把Wireguard.exe改成了aaa.exe、先等登录界面加载完成再打开aaa.exe就解决了问题;有人猜想前者是多余的,只是开了隧道之后网速太慢导致反作弊系统没有加载成功/过于敏感。
这次也算是遇上了“专业对口”的挑战,每天花几个小时捣鼓,最后花了四天解决。我们一直开玩笑说,以后面试/考试其他网络方向的学生时,可以把这个问题作为一道开放式应用题,给一周时间。当然,主要还是我只熟悉在Linux下手动配置网络底层,换做和Windows摸爬滚打多年的人,或许能找出简单得多的方案。
太酷了