Server搭建过程-5.Frp穿透介绍和P2P
利用Frp来进行内网穿透的方案已经较为成熟,不过这套方案已经流行了几年。
现在更多的新软件会偏向P2P打洞,虚拟组网之类。
说实话只要是内网穿透,无论是传统的服务器中转,还是P2P
打洞,穿透都需要通过不同的网络环境,所以还是非常吃NAT类型的。
因此尽量使用公网IPV4,没有公网V4用公网V6。内网穿透只是没有公网V4/V6的下位替代。
另外还有一个可以注意的点:
如果大学中办了校园网套餐,你的设备通过校园网连接,而学校内又有校园网wifi覆盖,那么之间大概率是局域网。
可以好好利用这点来局域网串流。
Tailscale
的这篇文章很值得看:
中文译文:[译] NAT 穿透是如何工作的:技术原理及企业级实践(Tailscale, 2020)
原文地址:How NAT traversal works
这篇文章浅显易懂,而又全面的讲解了穿透的整个过程。
简单的说,穿透分为两部分,第一部分是穿透网络上的防火墙:
这部分很简单,因为防火墙的一般策略都是进站有所封锁,而出站全部放行。
也就是说,只要我们内部由外主动发起这个连接要求,防火墙就会放行对应的应答包进来,因为防火墙认为是我们主动需要和外界连接。而对方也这样操作一次,也就构成了这个双向通信链接,打通了防火墙。
总而言之,打通防火墙所需要的,就是两台设备在防火墙后面同时发起对向的通信请求。
我们可以发现,无论在链路上有几堵墙,都可以用这个简单的逻辑来穿透。
但其实这个机制有效的前提是:要提前互相知道对方的公网ip和对应的port,才能发送包给对方,来构成链路。
而这个前提也就引入了穿透的第二部分,NAT。这部分也是穿透中最难的部分。
在IPV4情况下,我们手上的终端设备不会被分配公网ip。都需要NAT转换后,数据包才能以一个公网ip:端口发出去。
这也就是问题所在,我们需要提前互相知道对方的公网IP和端口,但是经过NAT后,我们不知道怎么获取到对方的公网IP和端口。
轮到Stun发挥作用的时候了。Stun服务器可以探测客户端在NAT之后的公网IP和端口。
实际上Stun不仅可以探测公网ip和端口,还可以用来检测NAT类型等信息。
有很多基于此的在线检测工具,手机的NekoBox软件里也自带一个Stun检测,当然,你也可以自建一个Stun服务器用于检测。
Stun服务器我一般白嫖的网址是:stun.miwifi.com
NAT类型分为四类:
完全锥形NAT(Full Cone NAT)(NAT1):
只要内部资源先发起过联系,任何外部地址和端口都可以访问该内部资源。
受限锥形NAT(Restricted Cone NAT)(NAT2):
外部IP地址只有在之前与内部资源有过交互的情况下,才能连接到该内部资源。
端口受限锥形NAT(Port Restricted Cone NAT)(NAT3):
只有当某个外部IP地址和端口,之前通过该端口与内部资源交互过时,它才有权限访问该内部地址和端口。
对称NAT(Symmetric NAT)(NAT4):
当数据包被发送到某个外部IP地址和端口时,回复时会为该外部地址和端口分配不同的映射。也就是说,当两个不同的外部用户尝试使用相同的端口号连接同一个内部地址时,他们会各自得到不同的映射端口号。
这种NAT比较常见于企业级NAT。
普通家庭宽带大多数都是NAT3,而移动数据是NAT4。
这里夸一句,中兴的路由器可以更改NAT类型,算是少见了。
简单地说前三种NAT,Stun都能穿透,而对称NAT,Stun无法奏效。
在这种NAT下,Stun拿到的公网ip和端口,只允许Stun的入向包进入。其他服务无法进入,自然无法穿透。
因此这种情况下只能启用保底的中转服务器,流量全部通过中转服务器转发。这类似于FRP干的事情。Tailscale
的中继服务器Derp默认以TCP流量转发。
总而言之,NAT4基本无法P2P直连,只能通过中转。中转穿透的情况,恐怕只能做一些简单的操作,串流延迟很大建议放弃。Tailscale
的中转服务器都在国外,最近的也在香港。建议是自建中转服务器。
自建中转服务器的好处不仅仅是中转延迟低,也有助于设备之间的p2p建立。
有能力的话还可以自建控制服务器。
有一点和Zerotier不同的是,Tailscale
各个平台下都直接支持更换中转和控制服务器。
而Zerotier的IOS修改moon服务器很麻烦。
我们应该如何提高P2P的成功率呢?我们要做的就是减少NAT的层级(这点对于国内用户来说很迫切)和提高NAT的类型。
少嵌套一层NAT(比如路由器拨号光猫桥接),可以减少转发损耗,提高网络通信效率和连通性。
而NAT类型越高,P2P就越容易成功。
当然最明显的提升,就是从NAT各个类型升级到公网的程度,公网也称为NAT0。
最适合国内的目前就是公网IPV6。下发了公网IPV6也就意味着无NAT,不太需要考虑NAT穿透的问题,P2P成功率高很多。
基本只需要考虑防火墙,而防火墙的情况和之前一样,只需要通过两端同时发包就能解决。
可能有人就会问,都有公网IPV6了,直接直连不就好了吗,还打什么洞?
有几方面的优势:
1.就算有公网IPV6,运营商光猫的防火墙会阻拦直连流量。如果想直连必须关闭光猫防火墙,或者改桥接。而Tailscale较友好。
2.公网IPV6分配的地址是不断变化的,如果需要固定还需要用DDNS。
3.公网IPV6暴露在外的端口安全性不佳,而Tailscale端到端加密流量,只有组网内的设备能互相访问。且Tailscale虚拟组网较无感。
关于搭建Tailscale服务器可以看:
Tailscale 基础教程:部署私有 DERP 中继服务器
Tailscale 基础教程:Headscale 的部署方法和使用教程
Tailscale/Headscale ACL 使用教程
Tailscale玩法之内网穿透、异地组网、全隧道模式、纯IP的双栈DERP搭建、Headscale协调服务器搭建,用一期搞定,看一看不亏吧?
虚拟组网其实就是把众多设备组在一个虚拟的,共同的网络内。
该说不说,和以前用游侠对战平台来组虚拟局域网,联机打游戏这点差不多。
ZeroTier还真的可以用来局域网联机。
现在内网穿透比较常见的软件有:
Frp | Nps | EasyTier | ZeroTier | Tailscale | WireGuard |
---|
Tailscale实际上是基于Stun和WireGuard的工具。
不过,使用Frp通过传统的服务器中转流量方案,穿透效果还是不佳。
在单纯偏向速率需求的任务中,比如搭建网盘穿透到公网,下载/上传文件等操作,速率是能够跑满上传限制。能够正常使用,Frp没有问题。
但在对延迟要求高的任务中,比如sunshine+moonlight串流,只要动作大点,就卡的不行。
并不是带宽上限太低导致的卡顿丢帧,在把分辨率和帧率都降低后,frp穿透本身在带宽还有余的情况下,依旧如此。
经过调查,卡的原因就是码率。可能是我之前一下子对码率太自信了,调的太高。
后面被代码框框住的内容是之前的错误推测,仅供参考
为什么我能确定这是错误推测呢,因为我后来使用Tailscale
p2p打洞成功后,码率和frp一样,调高的话也会出现同样的情况。
一般分辨率720p-1080p,网络不卡的情况可以开60帧,卡顿的话开30帧比较好。
码率10-20mbps之间。
Moonlight
中,除了需要根据情况调整分辨率和帧率外,码率也应设置在实际串流过程中网络最低可用带宽之下。
以避免因“木桶效应”导致的卡顿。
比如串流整个过程中,中转服务器速率为200mbps,主机设备上传带宽30mbps,串流设备下行100mbps:
则以30mbps为准,而且Moonlight
码率设置应比30mbps还要低一些。
1 | 我估计是穿透网络太难。在和主机设备(主机设备即被链接,被控制的设备)同一房间的情况下: |
Frp已支持P2P
打洞,无需中转服务器的XTCP穿透,可以按照官方文档来添加。
但是P2P已经有ZeroTier等软件了。
因此这里只介绍Frp最为基础的的Tcp和Udp端口转发,传统的中转服务器方案。
BTW,网络上很多Frp教程提供的配置文件都是ini的,但后续frp默认的配置文件是toml,这之间的语法有区别。本文以toml为标准。
程序下载下来里有两份,frpc
是Client,客户端的,放在自己需要内网穿透的设备上。frps
是Server,服务端的,放在中转服务器上。
frps.toml的参考配置
1 | bindPort = 5050 #服务器和客户端之间的通信端口 |
后续不添加配置,默认转发所有通过密码认证的流量。
如需自定义,请参考官方文档。
frpc.toml的参考配置
1 | serverAddr = "x.x.x.x" #填写服务器的公网IP地址 |
启动frpc/frps时,默认查找的配置文件是本目录下的ini文件,直接打开会说找不到对应的配置文件。
命令行手动指定配置文件位置:
1 | frps -c ./frps.toml |
1 | frpc -c ./frpc.toml |
后续可以设置成sh和bat脚本自动化执行。
串流需要打开的端口可以看这个视频:
串流游戏IPv4端口映射最全列表 | 包含 PC PS和XBOX一次性搞定
Frp
对应的配置文件参考:
1 | serverAddr = "x.x.x.x" |
新版本的Frp
使用的toml语法不支持端口范围转发。
用老的ini格式设置端口范围转发,frp
可以识别配置文件,但是无法正确转发多个端口,导致moonlight串流连接失败。
因此下面这个配置文件仅供参考:
1 | [common] |