注:由于「V.P.N.」为敏感词汇,本文中用「虚拟局域网」代称,和 VLAN 技术无关。
1. 背景
和朋友联机玩《博德之门 3》。因为不在同一城市,大家又不都是在 Steam 上购买的,决定用虚拟局域网联机。
我是 Linux,一个朋友是 macOS(ARM 版),另一个朋友是 Windows。
2. 问题
2.1. macOS 引发的惨案
之前我和用 Windows 的朋友组网的方案是 n2n,完全靠国内服务器中转,非常稳定。
但是用 macOS 的朋友来了之后,研究了一番表示:
n2n 官方没有打包 macOS 版,必须自己编译,而且文档里也说「请注意,在最新的 Apple Silicon 上,操作系统中的安全限制可能会越来越多,导致难以安装 TUN/TAP 内核扩展。」[1] 这种调用 UNIX 接口创建路由、而不使用苹果的 API 的虚拟局域网工具,都会把网络弄乱。
同理,ZeroTier、OpenVPN、Tinc、TetherVPN 等一众软件也都是绕过苹果限制创建的虚拟网络,会把这个朋友现有的网络配置弄乱,所以没办法用。
2.2. macOS 原生支持的协议
那么 macOS 具体支持哪些虚拟网络协议呢?官方文档提到三种:
- L2TP over IPSec
- IPSec
- IKEv2
- 另外,App Store 里的 Tailscale 也使用 macOS 接口
- 也可以用 ARM macOS 的功能运行 iOS 版的各虚拟网络 App
2.3. 排除法
然而众所周知,《博德之门 3》之类的游戏只支持用局域网广播搜索局域网房间,而不能输入同伴 IP。然而广播是 Layer 2(链路层)虚拟网络才支持的。
- (4) Tailscale 基于 WireGuard,因此是 Layer 3(网络层)虚拟网络,直接 Pass。(2) IPSec 同理 Pass;
- (5) OpenVPN 和 n2n 的 iOS App 运行起来后创建的也是 Layer 3 虚拟网络,Pass;
这样可行的选项只剩下 L2TP over IPSec 和 IKEv2(又名 IKEv2 over IPSec)了。
但是还没完。 Linux 上唯一的 L2TP 客户端兼服务端 xl2tpd 问题非常非常多,我折腾了三天都落在不同的 issues 上:不仅连接不上,还看不到任何有用的报错,非常让人恼火,另外原仓库作者也失踪两年多了。所以,L2TP over IPSec 也 Pass 了。
3. 目前情况
IKEv2 over IPSec 不可行,见下面的更新
所以唯一剩下的方案就是 IKEv2 over IPSec 了,恰好这也是 Android 目前唯一原生支持的虚拟局域网协议。
但是因为比较新、由商业公司(微软等)开发,网上有用的文档也很少。
另外 IKEv2 over IPSec 本身也不支持广播/组播,还要依靠 StrongSwan 的插件,目前在研究如何搭建服务器中……
折腾了几天,不禁感叹标题的内容:2024 年了,居然还拿不出一个简单易行的跨平台虚拟组网方案啊……
07-14 更新:
- 手动搭建 IKEv2 over IPSec with EAP-MS-CHAPV2 虚拟网络(是的,这玩意名字就是这么长)。看了一整天资料,技术栈实在过于复杂:IKEv2 和 IPSec 是独立的,拨号又依赖另外的 EAP-MS-CHAPV2 协议和 PKI 证书基础设施进行认证。报出的错误千奇百怪,一个一个试错解决花了一下午的时间:
no common hash algorithm
、no trusted ED25519 public key found
、no matching peer config found
、no IKE config found
、no private key found
、TPM 2.0 - could not load
……最新成果是卡在第一个错误提示,真的修不动了。没有高级网络工程师的资历,玩不转这个; - 用自动脚本搭建。尝试了 Star 数量最多的 setup-ipsec-vpn 项目,运行倒是很顺利,就是创建出来的 IKEv2 连接上后依然没有组播功能。尝试修改配置文件,无果,推测是客户端的限制而非服务器问题。
在读文档的过程中,我也意识到 IKEv2 设计时同样没有考虑广播的场景,所以,IKEv2 over IPSec 这条路也 Pass 了。
束手无策了,看看各位的奇思妙想吧。
Note that on the newest MacOS versions and on Apple Silicon, there may be increasing security restrictions in the OS that make installing the TUN/TAP kernel extension difficult. ↩︎