frp 是什么?
frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议,且支持 P2P 通信。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。
为什么使用 frp?
通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:
- 客户端服务端通信支持 TCP、QUIC、KCP 以及 Websocket 等多种协议。
- 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间,降低请求延迟。
- 代理组间的负载均衡。
- 端口复用,多个服务通过同一个服务端端口暴露。
- 支持 P2P 通信,流量不经过服务器中转,充分利用带宽资源。
- 多个原生支持的客户端插件(静态文件查看,HTTPS/HTTP 协议转换,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。
- 高度扩展性的服务端插件系统,易于结合自身需求进行功能扩展。
- 服务端和客户端 UI 页面。
原理
frp 主要由 客户端(frpc) 和 服务端(frps) 组成,服务端通常部署在具有公网 IP 的机器上,客户端通常部署在需要穿透的内网服务所在的机器上。
内网服务由于没有公网 IP,不能被非局域网内的其他用户访问。
用户通过访问服务端的 frps,由 frp 负责根据请求的端口或其他信息将请求路由到对应的内网机器,从而实现通信。
代理
在 frp 中一个代理对应一个需要暴露的内网服务。一个客户端支持同时配置多个代理。
代理类型
frp 支持多种代理类型来适配不同的使用场景。
类型 | 描述 |
---|---|
tcp | 单纯的 TCP 端口映射,服务端会根据不同的端口路由到不同的内网服务。 |
udp | 单纯的 UDP 端口映射,服务端会根据不同的端口路由到不同的内网服务。 |
http | 针对 HTTP 应用定制了一些额外的功能,例如修改 Host Header,增加鉴权。 |
https | 针对 HTTPS 应用定制了一些额外的功能。 |
stcp | 安全的 TCP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。 |
sudp | 安全的 UDP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。 |
xtcp | 点对点内网穿透代理,功能同 stcp,但是流量不需要经过服务器中转。 |
tcpmux | 支持服务端 TCP 端口的多路复用,通过同一个端口访问不同的内网服务。 |
测试
环境准备
一台公网服务器
一台内网服务器,需要保证能够连接到上面的公网服务器
我的环境是公网服务器为Linux服务器,内网就是我的Windows系统电脑。大致做个测试,需要下载对应版本的包。
需要使用更多功能的可以参考大佬文档https://gofrp.org/docs/examples/ssh/
服务器端配置
服务器作为公网访问唯一的固定地址,即作为 server 端。内网客户端作为 client 端,会主动向 server 端创建连接,此时再从 server 端反向发送数据即可实现内网穿透。
从github下载,地址为https://github.com/fatedier/frp/tags
,选择版本和对应的操作系统进行下载。
[root-4-6-centos ~]# wget https://github.com/fatedier/frp/releases/download/v0.50.0/frp_0.50.0_linux_amd64.tar.gz
[root-4-6-centos ~]# tar -xvf frp_0.50.0_linux_amd64.tar.gz
[root-4-6-centos ~]# cd frp_0.50.0_linux_amd64
[root-4-6-centos ~]# vim frps.ini
[common]
bind_port = 7000
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = admin123
#添加了ui界面的相关配置
[root-4-6-centos ~]# ./frps -c frps.ini &
[root-4-6-centos frp_0.50.0_linux_amd64]# ps aux|grep frps
root 3550 0.0 0.4 727584 17084 pts/2 Sl+ 16:11 0:00 ./frps -c frps.ini
root 9832 0.0 0.0 112812 976 pts/0 S+ 16:33 0:00 grep --color=auto frps
#注意下面的6000端口要客户端启动起来才有
[root-4-6-centos frp_0.50.0_linux_amd64]# netstat -anp|grep frp
tcp6 0 0 :::7500 :::* LISTEN 3550/./frps
tcp6 0 0 :::6000 :::* LISTEN 3550/./frps
tcp6 0 0 :::7000 :::* LISTEN 3550/./frps
tcp6 0 0 10.0.4.6:7000 118.122.92.220:2079 ESTABLISHED 3550/./frps
注意云服务器需要在安全组中打开相应的端口。包括6000/7000/7500 三个端口。
客户端配置
客户端只需要配置所链接的服务器端地址,以及要映射客户端的哪些服务端口。
由于我的客户端是Windows的,需要下载对应的Windows版本。https://github.com/fatedier/frp/releases/tag/v0.50.0
,下载后解压即可。
修改frpc.ini配置文件
[common]
server_addr = *.*.*.* (服务器公网IP)
server_port = 7000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
然后进入命令行界面运行服务
外网服务器连接内网测试
直接Telnet服务器外网IP的6000端口,
或者使用ssh连接
#x.x.x.x为服务器外网IP
[root@VM-4-6-centos ~]# ssh -oPort=6000 test@x.x.x.x
ssh_exchange_identification: Connection closed by remote host
frp 会将请求 x.x.x.x:6000 的流量转发到内网机器的 22 端口。
由于我的Windows服务器没有ssh服务22端口,所以会报以下错误。但是也证明了已经连通。
访问frp控制面板
面板仅供参考,可用可不用。frp的dashboard访问界面为 http://服务器外网IP:7500,使用上面配置的用户名和密码 admin/admin123
更多更详细的使用请参考https://gofrp.org/docs/examples/ssh/
更多关于Linux的知识请前往博客主页查看,编写过程中可能由于能力有限难免出现问题,敬请指出,谢谢。