1. n2n 简介
上文实验分析了 FRP 和 Zerotier 的利弊,本文再介绍另一种内网穿透方案,n2n。
n2n 是 C/S 架构的内网穿透服务,不同于 FRP 的 反向代理,它的原理是类似 Zerotier 的先打孔,打孔失败再尝试转发。关于打孔本文不会展开介绍,只说一点,国内网络打孔成功率不低,成功后两个客户端之间的通信无需经过服务端转发。
与 FRP 相比,n2n 的优势在于它能打孔;因此速度和用户容量全面优于 FRP,延迟大致持平。
与 Zerotier 相比,n2n 的优势在于:
1.Zerotier 是商业产品,以后的收费策略未可知。n2n 是开源的。
2.Zerotier 只有不开源的 moon 服务器能搭建,根服务器在美国;n2n 全开源,根服务器可以自行搭建。
3.n2n 服务端,客户端均轻量,结构比 Zerotier 更简单。实施时只需要配好配置文件和脚本传给客户,客户每次运行脚本即可连接,对小白客户的实施也比 Zerotier 容易。
4.n2n 打孔速度比 Zerotier 快,Zerotier 常常出现第一次连接需要等待的卡顿感。
n2n 的 缺点在于,不提供 Windows 编译版本,没有官方图形界面,本文会提供编译好的 n2n 3.0。
前提还是需要一台云服务器,选用主流云服务器即可。本文仍举例星露谷物语联机为应用场景。
2. 安装 n2n 服务端
下载 n2n,https://github.com/ntop/n2n/releases/tag/3.0
这里简单说一下怎么看安装包的名字,先看扩展名,代表系统类型,.rpm 是 redhat 类系统,如 CentOS,.deb 是 debian 类系统,如 Ubuntu。
再看文件尾,代表 CPU 架构,x86_64 代表 32位/64位 通用,i386 代表 32位,amd64 代表 64位,arm 代表 arm 架构(如树莓派,手机)。
github 上开源项目的 release 一般都会提供针对几个主流 linux 系统编译的可运行文件,其他的系统请用源代码自行编译。(😡难道 windows 不是主流系统?)
可以用这几条命令查看自己的系统架构,linux 发行版 等信息。
uname -m
lsb_release -a
cat /etc/*release*
比如我的是 Ubuntu 20.04.5 LTS x86_64,因此选择 n2n_3.0.0-1038_amd64.deb。
用 apt 来安装 deb 包。
apt install n2n_3.0.0-1038_amd64.deb
等待安装完毕,systemctl 里面就多了 supernode 和 edge 两个服务,也就是 n2n 的服务端和客户端。这条命令可以看到服务端此时并未开启。
systemctl status supernode
3. 安装 n2n 客户端,第一次连接
先对云服务器上的服务端进行配置。
vim /etc/n2n/supernode.conf
-p=7984
-F=FeigeGarden
-p 是端口号,随意填写,这一步做完后还需要在云服务器的防火墙面板放行 7984 端口(UDP)。
-F 是服务器的名字,客户端连接时要核对。
然后用该命令启动 n2n 服务端,并查看其状态。
systemctl start supernode
systemctl status supernode
可以看到 supernode.service 的启动命令是 /usr/sbin/supernode /etc/n2n/supernode.conf -f
。
然后在本地PC上安装 n2n 客户端,如果是 linux 系统,则安装步骤和安装服务端一模一样。
下面介绍的是 windows 系统,n2n 并未提供 windows 系统的编译版本,因此需要用 Visual Studio 编译源码。
本文提供 EasyN2N 作者编译好的 n2n-3.0,n2n-keygen 工具。以及 windows 系统还需要额外安装的虚拟网卡 tap-windows-9.23.3。
https://pan.baidu.com/s/103fC4QAkz4uvjj9mippgxA?pwd=fgtc
在 本地PC 下载后解压,先安装虚拟网卡 tap-windows-9.23.3,不赘述。
然后用 n2n-keygen 生成公钥
.\n2n-keygen.exe -F FeigeGarden
这里的 -F FeigeGarden 就是刚才服务端的配置文件 supernode.conf 中的 -F 服务器名。
可以看到一串加密后的乱码,这就是我们连接服务器的凭证。
在 本地PC 的 edge.exe 同目录下创建一个 edge.conf 文件。
-l 172.7.76.71:7984
-P OjWvhPvHc9Qo5tPthq9vEZfGvq3fn7+498fDDS0Oyqm
-c StardewValley
-l 是云服务器的 IP 和 端口。
-P 是 公钥,刚才 n2n-keygen 生成的密文,用来验证服务器名。
-c 是 community,可以理解为房间名,不同房间网络不互通。
在 本地PC 调出 cmd(管理员权限),运行客户端,尝试第一次连接。
C:\prohos\pro\n2n\edge C:\prohos\pro\n2n\edge.conf
出现如下画面证明连接成功,红圈内为 虚拟局域网IP 10.219.185.106,关闭此窗口则连接断开。
完成第一次连接后,只要给每个小伙伴的 本地PC 都安装上客户端,写好配置文件运行成功,就可以进行联机了,只要星露谷房主记住自己的虚拟局域网IP 10.219.185.106,其他成员填写这个 IP 加入游戏即可。
4. 配置用户权限
虽然已经可以成功联机,但是这样配置的服务器仅有一个验证凭据 -P,太单薄。我们还需要用用户名密码的方式强化下 n2n 服务器的访问权限。
在云服务器上修改配置文件,/etc/n2n/supernode.conf,加入这一行
-c=/etc/n2n/community.list
然后创建 /etc/n2n/community.list,如下所示是仅允许 StardewValley 和 borderlands2 两个房间名,以及各个房间允许的用户,lengyu,sister1,sister2,friend5,friend6。其他所有连接请求全部拒绝。更多 community.list 支持的规则请参阅 n2n 官方文档。 https://github.com/ntop/n2n/blob/dev/doc/Communities.md
StardewValley
* lengyu nZaltWogB+Vv6dAUEiNjGfzrCyD2SBsdH+CDdtPRI4y
* sister1 iqgGLHRzTNbcL6ui6QrTANlfUPQ3jMniTwPSxFQqur8
* sister2 6lhQQhfx9fUHcy10fLDomOoRvHbkG-Q9oPajSErt76C
* friend5 2h-xsXFw0XQol7Ef0H14LSI+rvBlrPLjOVf9s7Ov6aO
* friend6 j9CeNWBnJJ5i0-Hy811rHHJHkkY+8Frv39OEFexv2a0
borderlands2
* lengyu nZaltWogB+Vv6dAUEiNjGfzrCyD2SBsdH+CDdtPRI4y
* sister1 iqgGLHRzTNbcL6ui6QrTANlfUPQ3jMniTwPSxFQqur8
* sister2 6lhQQhfx9fUHcy10fLDomOoRvHbkG-Q9oPajSErt76C
用户名后面那串乱码是密码,是加密过的密文。现在说如何 明文->密文。
首先构思一对 用户名/密码,并且把它记录下来,例如:
lengyu
asTT-=3
然后使用 n2n-keygen 工具,生成密文
n2n-keygen lengyu asTT-=3
即可得到这样的结果
* lengyu nZaltWogB+Vv6dAUEiNjGfzrCyD2SBsdH+CDdtPRI4y
把这个结果贴到 community.list 中去。写完 community.list 之后,重启 n2n 服务端。
systemctl restart supernode
服务端配置完成,接下来修改客户端的 edge.conf。
-l 172.7.76.71:7984
-P OjWvhPvHc9Qo5tPthq9vEZfGvq3fn7+498fDDS0Oyqm
-c StardewValley
-I lengyu
-J asTT-=3
-A5
-k 23!->?gh
前三行没有任何变化。
-I 用户名
-J 明文密码
-A5 加密算法,A5 代表 Speck-CTR
-k 加密密钥,给加密算法使用的,可随意填写
这样调出 cmd(管理员权限),运行客户端 edge 就可以连接上 n2n 服务端了。
C:\prohos\pro\n2n\edge C:\prohos\pro\n2n\edge.conf
5. 编写批处理脚本(windows)
每次都调出 cmd(管理员权限) 输命令未免太过麻烦,对于小白用户来说也很劝退。我们可以写一个批处理脚本来干这个活,还是放在 edge.exe 的同目录下。
%1 start "" mshta vbscript:CreateObject("Shell.Application").ShellExecute("%~s0","::","%~dp0","runas",1)(window.close)&&exit
%~dp0\edge %~dp0\edge.conf
pause
这样,小伙伴们就可以啥都不用知道,每次联机之前双击这个脚本即可加入房间。
6. 杂谈
遗憾的是,本文并未采用实验的方式给出 n2n 和 FRP,Zerotier 的足够直观的性能对比。个人做过一些不太严谨的实验,得出的结论是:如果是以游戏联机为目标,可以首先尝试 n2n。另外,游戏的 主机/房主 还可以在路由器上打开 DMZ主机 功能,能够有效降低延迟;某些游戏会在检测网卡时优先选用物理网卡,导致联不上,这时需要手动修改跃点数来提高虚拟网卡的优先级。
PS:Steam上某些游戏就是采用打孔的方式联机的,官方服务器负担很小,比如枪火重生。
除了联机游戏,n2n 对于个人而言,还有个应用场景,就是遥控家里的智能设备,我家里的树莓派 同时配置了动态域名,n2n 客户端 和 Shadowsocks 服务端,这使得我身在千里之外也可以随时遥控家里的智能设备。一台自己做的电视盒子(CoreELEC),也同样配备了 n2n 客户端。
另外,n2n 有个独特的优势,它还是个分布式软件,服务端可以组成一个集群,这个神奇的优势在某些场景下可能让它脱颖而出。想不到一个服务端+客户端都不超过 2MB 的软件这么有志气。
翻看官方 github 页面还可以找到第三方的 windows GUI,docker 镜像,Android 版 n2n 等。