什么是frp?
frp 是一个高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务,支持 tcp, http, https 等协议类型,并且 web 服务支持根据域名进行路由转发。frp 是一款跨平台的内网穿透工具,支持 Windows、macOS 与 Linux,它需要你有一台拥有固定公网 IP 的电脑,VPS 最好,然后就能愉快的进行内网穿透了。还支持 https,甚至可以用它进行小程序开发。
众所周知,frp 支持多种代理类型来适配不同的使用场景。
类型 | 描述 |
---|---|
tcp | 单纯的 TCP 端口映射,服务端会根据不同的端口路由到不同的内网服务。 |
udp | 单纯的 UDP 端口映射,服务端会根据不同的端口路由到不同的内网服务。 |
http | 针对 HTTP 应用定制了一些额外的功能,例如修改 Host Header,增加鉴权。 |
https | 针对 HTTPS 应用定制了一些额外的功能。 |
stcp | 安全的 TCP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。 |
sudp | 安全的 UDP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。 |
xtcp | 点对点内网穿透代理,功能同 stcp,但是流量不需要经过服务器中转。 |
tcpmux | 支持服务端 TCP 端口的多路复用,通过同一个端口访问不同的内网服务。 |
教程
为什么选择XTCP
有人要问了,为什么要选择xtcp呢。我前面tcp。stcp链接都很好用啊,为什么要选择XTCP这种类型呢。
从前面的表格里不难看出,除了XTCP这种类型。其他的所有代理类型,“服务端”和客户端之间的传输流量,都需要经过Frps服务器的中转。同样的,有购买过服务器的朋友就会有印象,国内服务器的带宽资源可以说是寸土寸金, 每m的带宽都能追上金价了 。如果需要传输一些什么大的文件,慢不说,想增加带宽,也是不小的开支。
比如友商的最低配置服务器,使用 100m 的带宽
一个月8000,想想就离谱。
所以,就有了Frp的XTCP模式,xtcp模式本质上是类似p2p的一种点对点传输方法,frps服务器负责沟通两个客户端间建立点对点的链接
案例
通过服务端的辅助后,两个客户端如果成功建立了nat链接,那么,其传输的流量,将直接在两个客户端之间传输,无需经过服务端转发。这对于使用家庭宽带的用户来说是一个好消息。有些人的内网设备,例如:NAS。在传输文件的时候,需要非常大的带宽,使用普通的tcp模式,服务器无法承载这么大的网络流量,传输效率极低。而使用XTCP模式后,限制将只受限于客户端宽带的速度和点对点nat的复杂性,相较普通tcp模式,能够有很大的改善。
以下是站长和一位好友使用XTCP跨地区跨内网的情况下,点对点链接测试的速度
链接方向:浙江杭州←福建福州
网络环境:均使用移动网络,配置了两层的路由。福州方向使用300m带宽,实际出150m入400m,杭州方向未知,但电脑仅链接一根100m的网线进行测试。
测试入上图,延迟较低,轻轻松松就达到了50m的速度,峰值速度甚至逼近这位好友的端口极限。
PS:如果双方使用 电信 或 联通 网络,速度可能会更快,更稳定。 这里没有黑移动的意思
注意事项
因为点对点打洞NAT(XTCP)比较在意网络环境,这里科普一下各种napt类型:
NAPT分类
本小段参考CSDN https://blog.csdn.net/deng_xj/article/details/89187944
根据Stun协议(RFC3489),NAPT大致分为下面四类:
1.Full Cone(完全圆锥型)
从同一私网地址端口192.168.8.100:5000发至公网的所有请求都映射成同一个公网地址端口1.2.3.4:8000 ,192.168.8.100可以收到任意外部主机发到1.2.3.4:8000的数据报。
这种NAPT内部的机器A连接过外网机器C后,NAT会打开一个端口.然后外网的任何发到这个打开的端口的UDP数据报都可以到达A,不管是不是C发过来的。
例如:
A:192.168.8.100 ——NAT:1.2.3.4 ——C:292.88.88.88
[ok] C(292.88.88.88:2000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
[ok] C(292.88.88.88:3000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
[ok] D(292.99.99.99:3000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
任何发送到 NAT(202.100.100.100:8000) 的数据都可以到达 A(192.168.8.100:5000)
2.Address Restricted Cone(地址限制圆锥型)
从同一私网地址端口192.168.8.100:5000发至公网的所有请求都映射成同一个公网地址端口1.2.3.4:8000,只有当内部主机192.168.8.100先给服务器C 292.88.88.88发送一个数据报后,192.168.8.100才能收到292.88.88.88发送到1.2.3.4 : 8000的数据报。
这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口,然后C可以用任何端口和A通信,其他的外网机器不行。
例如:
A:192.168.8.100 ——NAT:1.2.3.4 ——C:292.88.88.88
[ok] C(292.88.88.88:2000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
[ok] C(292.88.88.88:3000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
任何从C发送到 NAT(1.2.3.4:8000)的数据都可以到达A(192.168.8.100:5000)
3.Port Restricted Cone(端口限制圆锥型)
从同一私网地址端口192.168.8.100:5000发至公网的所有请求都映射成同一个公网地址端口1.2.3.4:8000,只有当内部主机192.168.8.100先向外部主机地址端口292.88.88.88:2000 发送一个数据报后,192.168.8.100才能收到292.88.88.88:2000 发送到1.2.3.4:8000的数据报。
这种NAT内部的机器A连接过外网的机器C后,NAT打开一个端口,然后C可以用原来的端口和A通信,其他的外网机器不行。
例如:
A:192.168.8.100 ——NAT:1.2.3.4 ——C:292.88.88.88
[ok] C(292.88.88.88:2000) ——> NAT(1.2.3.4 : 8000) ——> A(192.168.8.100:5000)
C(202.88.88.88:2000)发送到 NAT(1.2.3.4:8000)的数据都可以到达A(192.168.8.100:5000)
以上三种NAT通称Cone NAT,我们只能用这种NAT进行UDP打洞。
4.Symmetic
内网主机建立一个UDP socket(LocalIP,LocalPort),当用这个socket第一次发数据给外部主机1时,NAT为其映射一个(PublicIP-1,Port-1),以后内网主机发送给外部主机1的所有数据都是用这个(PublicIP-1,Port-1),如果内网主机同时用这个socket给外部主机2发送数据,第一次发送时,NAT会为其分配一个(PublicIP-2,Port-2), 以后内网主机发送给外部主机2的所有数据都是用这个(PublicIP-2,Port-2)。如果NAT有多于一个公网IP,则PublicIP-1和PublicIP-2可能不同,如果NAT只有一个公网IP,PublicIP-1和PublicIP-2只能相同,Port-1和Port-2就肯定不同,也就是说一定不能是PublicIP-1等于 PublicIP-2且Port-1等于Port-2。
如果任何外部主机想要发送数据给这个内网主机,那么它首先应该收到内网主机发给他的数据,然后才能往回发送,但对于这种NAT,不同于Cone NAT,在连接不同的外部目标,原来NAT打开的端口(Port)会变化,虽然可以用端口猜测,但是成功的概率很小,这种NAT无法实现UDP-P2P通信。
即在Symmetic环境下,无法适用点对点穿透,只能选择服务器中转穿透。
结论
只要NAT类型不是 Symmetic ,就可以尝试使用 点对点穿透,以减缓服务器端带宽压力。
具体网络类型可以使用NatTypeTester来测试。
下载地址: NatTypeTester
检测服务端
首先我们要先检查Frps端的配置状态
打开frps服务端的配置文件
检查里面 bind_udp_port 是否配置监听。如果没有,请加上。
然后,检查您的防火墙,是否对您监听的UDP端口放行了。如果没有,请放行您的端口。
如果您使用的是阿里云,腾讯云等服务商的服务器,请检查安全组是否也放行了您的端口,并且允许了相关协议。
我这里演示的是宝塔的防火墙
配置客户端
因为点对点的打洞需要使用到两个客户端,我们这里分服务客户端A和客户客户端B来说明。
服务客户端
配置文件如下
[common]
server_addr =YOUR_SERVER_IP #您Frps服务端的IP地址
server_port =YOUR_SERVER_PORT #您Frps服务端的TCP监听端口,默认是7000
token=YOUR_SERVER_TOKEN #您Frps服务端的链接秘钥
[p2p]
type = xtcp #使用XTCP代理协议
sk=123456 #您自行设定的安全秘钥,用于客户客户端B认证使用
local_ip = 127.0.0.1 #本地需要打洞的服务地址
local_port = 3389 #本地需要打洞的服务端口
#这里显示的是Windows的Mstsc功能演示
更具注释修改之后,使用
frpc -c frpc.ini
或
frpc.exe -c frpc.ini
来运行服务客户端的Frp
不出意外的话,日志会出现类似如下的信息
客户客户端
现在来到另外一台机器上,来配置客户客户端
配置文件如下
[common]
server_addr =YOUR_SERVER_IP #您Frps服务端的IP地址
server_port =YOUR_SERVER_PORT #您Frps服务端的TCP监听端口,默认是7000
token=YOUR_SERVER_TOKEN #您Frps服务端的链接秘钥
[p2p_visitor]
type = xtcp #使用XTCP代理协议
role = visitor #非常重要,这表明frpc将吧这个客户端视为访问的访客客户端
server_name = p2p #您在服务客户端设定的代理名称,如前面的p2p
sk = 123456 服务客户端设定的安全秘钥
bind_addr = 127.0.0.1 #打洞后,客户端在本地建立的镜像接口地址,通常为127.0.0.1或0.0.0.0
bind_port = 2323 #打洞后,客户端在本地建立的镜像接口的端口
更具注释修改之后,使用
frpc -c frpc.ini
或
frpc.exe -c frpc.ini
来运行服务客户端的Frp
不出意外的话,日志会出现类似如下的信息
ps:站长这里使用的是站长自己编写的WindowsGUI版Frps客户端,显示的颜色可能并不一样
测试
完成以上的操作之后,启动两个客户端的frpc服务。
因为我们使用的是Windows的RDP作为演示,我们在运行客户客户端的电脑上运行mstsc打开远程桌面
例程里面使用的是127.0.0.1的2323端口
我们填入
点击链接
如果打洞成功,运行服务客户端的frpc会回显类似下图的消息,这意味着打洞成功,nat链接成功
同时,运行客户客户端的frpc也会出现如下消息,表示打洞成功
同样的,RDP也链接上了相关服务
错误说明
如果出现类似:
get sid from client error: read udp 192.168.10.2:58681->106.15.*.*5:62218: i/o timeout
这样的错误,那么说明您的frps服务器可能存在问题,或者您的网络环境不适合打洞nat。
站长在实际测试中大概率怀疑是frps服务器的问题。
博主太厉害了!