第零章:导言
导言部分主要介绍 frp 项目的背景知识以及基本信息。
背景
什么是内网穿透?
在日常工作中,我们经常会遇到将内网服务暴露到公网的需求,例如:
- 搭建个人网站
- 远程代码开发调试
Minecraft 游戏联机- ...
由于ipv4 地址资源有限,绝大多数内网环境并没有公网 IP。而且ipv6 普及进程缓慢, 导致了很多地方依然存在内网服务无法直接暴露到公网的情况。
因此,需要一种技术手段,将内网服务通过具有公网 IP 的节点中转,来解决没有公网 IP 的难题, 这就是内网穿透技术。
什么是反向代理?
反向代理是一种位于服务器和客户端之间的代理服务器。 客户端将请求发送给反向代理,然后由代理服务器根据一定的规则将请求转发给后端服务器。 后端服务器将响应返回给代理服务器,再由代理服务器将响应转发给客户端。
反向代理的优势在于:
- 负载均衡,提高系统的整体性能和稳定性。
- 隐藏真实服务器的信息,提高安全性。
- 缓存静态资源,减少后端服务器的负载,提高响应速度。
工具介绍
frp 是一个用于内网穿透的反向代理应用, 可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。
通过在具有公网 IP 的节点上部署 frp 服务端,可以将内网服务穿透到公网。此外还提供诸多专业功能特性:
- 客户端服务端通信支持 TCP、QUIC、KCP 以及 Websocket 等多种协议。
- 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间,降低请求延迟。
- 代理组间的负载均衡。
- 端口复用,多个服务通过同一个服务端端口暴露。
- 支持 P2P 通信,流量不经过服务器中转,充分利用带宽资源。
- 多个原生支持的客户端插件(静态文件查看,HTTPS/HTTP 协议转换,HTTP、SOCK5 代理等), 便于独立使用 frp 客户端完成某些工作。
- 高度扩展性的服务端插件系统,易于结合自身需求进行功能扩展。
- 服务端和客户端 UI 页面。
整体架构
frp 工具由以下两个部分组成:
frps
:服务端,部署在具有公网 IP 的节点上,用于接收客户端请求并转发到内网服务。frpc
:客户端,部署在内网环境中,用于将内网服务请求发送到服务端。
通过frpc
和frps
的紧密配合,就能最终实现内网穿透的功能。在内网穿透服务搭建完成后,
任何能访问互联网的用户都可以通过公网 IP 向内网服务发起请求。以下架构图展示了成功建立 frp 服务后的工作状态:
可以看到,该模型中包含了三个主体,由上至下分别是:
User
:用户(可以有多个),任何能访问互联网的用户。Server
:服务端(一个),部署了frps
并且具有公网 IP ,用于接收用户请求并转发到内网服务。Client
:客户端(可以有多个),在局域网环境中并且可以访问互联网,部署了frpc
,用于将 内网服务请求发送到服务端。
Note
关于客户端(Client)和服务端(Server)的概念,可能会造成一定的混淆。
1. 在内网主机与公网服务器通信的过程中,内网主机是客户端(frpc
),公网主机是服务端(frps
);
2. 内网主机反代的最终目的,也是为了通过公网服务器间接向外部用户提供服务,从这个角度看,内网主机似乎又成为了服务端。
因为在之后的章节中我们将重点关注 frp 的实现过程,所以在这里提前约定统一的术语:将内网主机称为客户端,公网服务器称为服务端。
仓库信息
项目的仓库地址为:https://github.com/fatedier/frp。
这是一个国人开发的开源项目,目前已经在 GitHub 上获得了 86.9k+ 的 star 数以及 13.4k+ 的 fork 数。
本地使用cloc
工具,可以统计出 frp 项目的代码行数:
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Go 223 4483 3425 25157
Markdown 9 542 7 1351
Vuejs Component 16 98 4 1058
TypeScript 11 44 18 600
INI 2 98 0 459
YAML 11 36 53 395
TOML 4 84 223 258
Bourne Shell 3 25 4 142
JavaScript 4 8 37 141
JSON 5 2 0 111
make 2 22 1 61
HTML 4 12 0 46
CSS 4 4 0 25
-------------------------------------------------------------------------------
SUM: 298 5458 3772 29804
-------------------------------------------------------------------------------
可以看到,frp 项目主要用Go 语言编写,代码行数约为25k行。