首先解释一下NAT服务器,与普通服务器不同的是,NAT服务器是多个用户共用 IP 的,仅能使用十个至几十个端口,有的是直接划分好端口段( OLVPS ),服务器上用防火墙打开对应端口即可使用,有的可以自行设定端口映射( CloudIPLC ),但是在公网上只能打开 1 万以上的端口号,且可能已经被占用
FRP 和 NPS 的原理都相近,一个主(Server)多个从(Client),通过一个端口(TCP复用)使多个从服务器的端口映射到主服务器上,使得访问主服务器端口时,能获得访问从服务器对应端口的目的。以本文的需求为例,假如我在树莓派的 5000 端口上挂载了一个网页服务,想通过公网访问,则可以将树莓派的 5000 端口映射到公网服务器的 6000 端口,然后访问公网服务器的6000端口即可访问网页,其他的可以一一映射,如5100到6001,5200到6002,如下图所示
NAT 服务器稍有不同,即多了一层映射,需要将 NAT 服务器的内网端口映射到公网端口上,假设需求和上图相同,则需要将树莓派的 5000 、 5100 和 5200 端口映射到 NAT 服务器的 6000 、 6001 、 6002 端口上,数据沟通端口则填写 37000 而不是 7000 ,然后用户通过访问 36000 、 36001 和 36002 可获得相同效果,如下图所示
那么下面进入部署阶段
FRP
一个由 go 语言实现的内网穿透工具,优点是下载即用,不需要安装,可以在不同服务器间拷贝,直接运行即可,缺点是官方提供的 WebUI 非常鸡肋,可以直接忽略,本文使用的是 0.34.1 版本
https://github.com/fatedier/frp
普通服务器
Server端
笔者一般先部署 Server 端,因为调试逻辑会更加简单,首先去官网下载 Release 包,注意区别服务器系统版本,解压压缩包之后给予 frps 文件执行的权限,当然最简单的方式就是整个目录递归赋予 777 权限(笔者通过 WinSCP 操作的),然后修改 frps.ini ,笔者使用的设置为
[common]
bind_port = 7000
kcp_bind_port = 7000
token = 服务器间通信密码
dashboard_port = 7001
dashboard_user = 用户名
dashboard_pwd = WebUI密码
log_file = /root/log/frps.log
log_level = info
log_max_days = 7
其中含有 dashboard 的几个变量都是和 WebUI 相关的,不使用该功能的话可以直接删掉,然后切换到目录下运行看是否报错(记得先创建 log 文件夹,不知道为什么这些软件连创建文件夹都不会),如果未正常开启可以在 log 文件中查看日志并修正
./frps -c ./frps.ini
Client端
解压后修改配置文件 frpc.ini,注意和上面的区别,别修改或运行错了
[common]
server_addr = 服务器ip
server_port = 7000
token = 服务器间通信密码
protocol = kcp
log_file = /root/log/frpc.log
log_level = info
log_max_days = 7
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
[web]
type = tcp
local_ip = 127.0.0.1
local_port = 80
remote_port = 6001
将服务器 ip 和密码设置好后就可以运行了,如果使用的是 kcp 协议,需要放行通信端口(如上文中的 7000 端口)的 udp 协议,也可以使用默认的 tcp 协议,下方模块的 type 中的协议不需要更改,更多协议可以参考官方文档
./frpc -c ./frpc.ini
这时建议先两边都用 ssh 客户端直接运行命令开启服务并验证是否可以连通,如果一切正常再使用其他方式后台运行,如果无法连接,下面列出了几个常见的解决思路
1、查看 log 日志的报错信息,其中 log 日志所在的目录需要提前创建,然后根据错误信息来排查问题
2、查看是否端口已经被占用 netstat -lnp|grep 端口号
3、查看两侧防火墙是否均放行所有相应的端口的 tcp 协议,其中 kcp 需要放行沟通端口(如上文中的7000)的 tcp + udp 协议
4、从外部查看端口是否开放(测服务器的),需要开启服务后即有程序监听端口后查看, http://coolaf.com/tool/port
5、frpc.ini 配置文件里面的模块是否重名,可能因为复制粘贴忘记修改而重名以至无法开启服务
NAT服务器
Server端
和上面完全相同,如果是手动开启映射的服务器,记得在使用 kcp 协议的时候,增加一条 udp 的映射
Client端
稍有不同的是需要将 server_port 改为映射后的端口,如上图中的 37000 ,server_addr 实测支持填写域名
NPS
一个同样由 go 实现的内网穿透工具,但官方提供了更好的 WebUI ,并且可以直接操作 Server 端就能完成映射,在增减映射的时候不用重启服务,避免了想重启服务但关闭服务导致 ssh 掉线然后服务无法开启因此失联的尴尬局面,当然,为了更保险起见,笔者同时开了 FRP 和 NPS 服务,防止掉线后无法重连的尴尬,当然,后面加入了 ZeroTier 实现了三重保险,本文使用的是 0.26.9 版本
https://github.com/ehang-io/nps
普通服务器
Server端
下载Release包,解压然后进入目录,安装
./nps install
默认情况下,服务会安装到 /etc/nps 文件夹中,编辑配置文件 /etc/nps/conf/nps.conf
一般情况下修改这四行内容即可
http_proxy_port=未被占用的端口
https_proxy_port=未被占用的端口
web_username=用户名
web_password=密码
因为很可能服务器的80和443端口已经用来开启其他服务比如被 Nginx 监听了,所以直接运行会报错,因此需要修改成未被占用的端口,并填写后台管理用的用户名和密码,在放行 8080 端口后开启服务就可以访问到后台了
nps start
点击 客户端 - 新增 - 新增 使用默认配置新增一个服务器,可以自行选择是否加密和压缩,然后点击 隧道 - 新增 新增一个映射,以上图为例,则 服务器端口 填写 6000 , 目标 (IP:端口) 填写 路由器下内网:5000 或者 127.0.0.1:5000
然后返回 客户端列表 点击服务器左侧加号,可以得到一条如下所示的 客户端命令 ,复制后配置客户端时使用,记得放行防火墙端口
./npc -server=服务器IP:端口(默认8024) -vkey=自动生成的密钥 -type=tcp
如果需要修改默认端口 8024 ,可以修改 bridge_port 后重启生效(理论上,笔者未测试),卸载可以执行 nps uninstall 后通过 whereis nps 找到残留文件删除即可
Client端
首先防火墙放行相应端口,然后解压压缩包然后进入目录并执行上面复制的 客户端命令 ,理论上,刷新后台即可看到客户端状态均变为绿色,因为是直接用 ssh 执行的命令,因此如果未正常连接,可以通过日志来查错和修正,基本的排查错误的思路和 FRP 相同
NAT服务器
Server端
和上面完全相同
Client端
稍有不同的是需要将 客户端命令 改为映射后的端口,如上图中的 37000 , 服务器IP 实测支持填写域名
ZeroTier
如果阅读了上面两个工具的 Github 页面或者官方文档,就会发现,里面都提到了一个 P2P 的连接方式,但是笔者尝试后会发现存在诸多问题且很多时候无法连接,官方也表名并不稳定,那么,有没有一个专门做 P2P 连接的工具呢,这个就是了,一个使用 CPP 和 C 实现的内网穿透工具,并且组建的是局域网,本文使用的是 1.4.6 版本
https://github.com/zerotier/ZeroTierOne
Leaf 节点(叶子节点)
这里面的概念发生了一些变化,因为这个的目的是将所有用户连接起来形成一个局域网,因此所有用户都是平等的,也就没有服务端和客户端的区别了,增加一个用户相当于增加了一个 Leaf 节点,可以使用一键安装包, Windows 用户去下载 exe 文件安装即可,如果 debian 系统下提示没有 sudo 同时已经在 root 用户下,去掉 sudo 即可
curl -s https://install.zerotier.com | sudo bash
如果安装时提示 NO_PUBKEY 1657198823E52A61 ,则需要添加公钥,这种情况一般是使用了第三方的镜像导致的,比如清华源、阿里源
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1657198823E52A61
安装完后就可以通过 zerotier-cli 配置服务器了,首先,开启服务并设置开机自启
systemctl start zerotier-one
systemctl enable zerotier-one
打开官网创建账号然后新增网络
https://my.zerotier.com/network
然后获得一个 Network ID ,所有节点加入网络都使用相同的命令,Windows 下就使用管理员权限的 CMD 来执行
zerotier-cli join ID
如果成功则会返回
200 join success
然后打开防火墙 9993 的 udp 协议,Windows 下自动打开了,无需手动操作
然后在官网中打开该网络的设置页面,在 Members 中就会多出一个成员,即 Leaf 节点,左侧打钩即可同意加入网络,同时会显示版本号和公网 IP 并分配一个内网 IP ,当有超过两个节点之后,就可以通过内网IP Managed IPs 相互连通了,这个页面似乎是会进行 ajax 刷新的,所以不需要手动刷新
Moon节点(月亮节点)
但如果连接国外 Planet 节点(行星节点)的效果不够好怎么办,可以自行搭建 Moon 节点当中转站,首先,将 Moon 节点按上面方法加入网络并授权,然后新增 Moon 配置
cd /var/lib/zerotier-one
zerotier-idtool initmoon identity.public > moon.json
修改配置文件 moon.json ,在括号内填入服务器的公网 IP 和端口,注意需要双引号,同时复制ID,位于 ["id": "18fasd2319"] 内 ,后面让其他 Leaf 节点加入时使用
"stableEndpoints": ["公网IP/9993"]
在该目录下生成 Moon 文件,文件名类似于 00000018fasd2319.moon
zerotier-idtool genmoon moon.json
新增 moons.d 文件夹,即 /var/lib/zerotier-one/moons.d/ ,将 00000018fasd2319.moon 文件移入,然后重启服务
systemctl restart zerotier-one
其他节点绑定 moon 节点的方式都是输入以下命令, ID 需要改为上面复制的 ID
zerotier-cli orbit 18fasd2319 18fasd2319
重启服务后查看是否添加成功
zerotier-cli listpeers
zerotier-cli listmoons
listpeers 列出了局域网内所有的节点,包括官方的行星中转节点 Planet 、所有用户的叶子节点 Leaf 以及自建的月亮中转节点 Moon ,一行为一个节点,如果没有看到 Moon 节点则添加失败, listmoons 如果返回为空则失败
当然 Linux 下可以新建目录 /var/lib/zerotier-one/moons.d/ ,然后复制生成的 moon 文件到文件夹下,重启服务后查看是否生效
Windows下的默认目录在 C:\ProgramData\ZeroTier\One\moons.d\ ,新建该文件夹然后复制进去,重启(停止然后启动)服务(打开开始菜单然后搜索服务即可找到)即可,如果执行 zerotier-cli 的命令时出现 missing authentication token ,则需要用管理员身份启动 CMD ,如果出现了服务不正常的情况,比如右键状态栏中图标发现没有节点,可以尝试手动重启服务或重启电脑
两个 Leaf 节点如果打通则通过 9993 端口的 UDP 协议连接,速度取决于两端的带宽和延时,与中转节点无关,如果两个 Leaf 节点之间未能成功打通,则会走服务器中转
NAT服务器对比
无论如何都要选择 KVM 架构的服务器,一般都有标明的,这个可玩性才高,一般情况下价格也不会高很多
CloudIPLC
https://www.cloudiplc.com/
需要实名认证,仅能开启一个服务器,电信移动联通均有,最便宜的 1C+384M+4G+600G ,价格为30元一个月,这个大小的内存如果重装纯净版,仅能安装 Debian9 , CentOS 和 Debian10 都是装不上的,512M 的内存可以装 Debian10 ,具体的重装教程请阅读下一篇文章
需要手动映射内网端口到公网端口上,TCP和UDP分开映射,考虑 ssh 端口占用一条,则可以配置额外十条映射规则
如果使用 FRP 的 KCP 模式,通信端口占用 TCP + UDP 两条映射规则,则可以映射 8 个额外的端口
如果使用 NPS ,通信和 WebUI 占用两个端口,同样有额外 8 个端口可用,如果使用纯文本配置,则多一个,但是会麻烦很多,用 NPS 就是看上了他的 WebUI
如果使用 ZeroTier,emmmmmm,为什么要为一个中转功能开一个 NAT 服务器啊淦,随便开个普通的服务器就好了,或者直接用官方的节点
不过不太能够理解的是,因为不明原因,在穿透可道云的时候,加载含大文件的文件夹时百分百会出现 Ajax Error ,且无法打开 AriaNG ,在重装清华源 Debian9 、开启 BBR 、检查 MTU 、手动部署 Nginx-1.14.2 、手动部署 PHP7.3-FPM 、提高所有超时和大小限制、开启 UDP 之后问题依旧,服务器提供商表示问题你们自己解决,可道云开发者表示不关我事,遂放弃。不过在下载时,速度比较稳定,能长期维持 5MB/s 的速度,因为百兆是进出口带宽,在中转的时候同时进出,所以满速就是 5MB/s 左右,如果有 dalao 能解决上述问题,欢迎评论区留言和讨论
OLVPS
https://olvps.com/
不需要实名认证,能开启多个服务器,电信移动联通均有,最便宜的仅有 256M 内存,考虑到上面的经历,尝试了下 512M 内存的服务器,价格稍贵,读者可以尝试更便宜的那一款,进去后成功重装清华源的 Debian10
固定开启一个端口段,需要在使用的时候将端口改到相应的端口段内,不过好处是 TCP 和 UDP 可以同时开启,直接在防火墙上放行即可,因此最多有 10 个端口(相当于20 条映射规则)
测试可道云穿透和 AriaNG 穿透均正常,不过速度不是很稳定,经常会掉到几百 K ,在开启 BBR 之后情况依旧,那么,有什么理由让我不使用 ZeroTier 呢
BBR
NAT 服务器的内存普遍偏小,不适合直接安装 CentOS 系统,当然服务商提供的系统是没问题的,经过了一定的精简,可以顺利装上,如果用户直接从清华源安装会报内存不足的错误,不过,无论使用哪个系统,都可以开启 BBR 加速
Debian 在内核版本大于 4.9 时可以直接通过以下命令开启并应用设置,现在的系统基本都符合要求
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
然后检测是否开启成功,返回值中含有 bbr 或者 fq 即开启成功
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control
sysctl net.core.default_qdisc
lsmod | grep bbr
也可以安装 BBR - PLUS ,readme 里面有安装说明
https://github.com/Xaster/bbrplus-debian
CentOS 则需要安装相应的编译好的内核,有一键脚本可以使用,会下载一个内核,如果速度太慢可以下载好传上服务器,不过需要自己修改一下脚本,难度很低
wget "https://github.com/cx9208/bbrplus/raw/master/ok_bbrplus_centos.sh" && chmod +x ok_bbrplus_centos.sh && ./ok_bbrplus_centos.sh
然后可以通过与上面相同的命令查看是否安装成功
Supervisor守护进程
因为要开机启动和后台挂载,于是使用 supervisor 服务,配置教程可以参考 基于CentOS7+supervisor+logrotate部署nginx+uwsgi ,debian下安装supervisor命令稍有改变
apt-get install supervisor
启动服务并设置开机启动
systemctl start supervisor
systemctl enable supervisor
修改配置文件 /etc/supervisor/supervisord.conf ,新增 web 页面
[inet_http_server] ; inet (TCP) server disabled by default
port=0.0.0.0:端口 ; (ip_address:port specifier, *:port for all iface)
username=用户名 ; (default is no username (open server))
password=密码 ; (default is no password (open server))
端口、用户名、密码需自行修改,同时记得放行端口,然后更新配置
supervisorctl reload
Debian 下的任务后缀是 conf 而不是 ini ,在 /etc/supervisor/conf.d 文件夹下新增 frp.conf ,nps 则只用挂载客户端, zerotier 不需要
[program:frp_supervisor]
stdout_logfile=/root/log/frp_supervisor.out.log
stderr_logfile=/root/log/frp_supervisor.out.err
directory=/root/frp
command=/root/frp/frpc -c /root/frp/frpc.ini
user=root
autostart=true
autorestart=true
redirect_stderr=true
其中log路径需要手动创建,否则无法运行,Server 端为 frps ,不要写错,然后更新列表并在 web 上查看是否正常运行
supervisorctl update
发表评论