Skip to content

第零章:导言

导言部分主要介绍 frp 项目的背景知识以及基本信息。

背景

什么是内网穿透?

在日常工作中,我们经常会遇到将内网服务暴露到公网的需求,例如:

  • 搭建个人网站
  • 远程代码开发调试
  • Minecraft 游戏联机
  • ...

由于ipv4 地址资源有限,绝大多数内网环境并没有公网 IP。而且ipv6 普及进程缓慢, 导致了很多地方依然存在内网服务无法直接暴露到公网的情况。

因此,需要一种技术手段,将内网服务通过具有公网 IP 的节点中转,来解决没有公网 IP 的难题, 这就是内网穿透技术。

什么是反向代理?

反向代理是一种位于服务器和客户端之间的代理服务器。 客户端将请求发送给反向代理,然后由代理服务器根据一定的规则将请求转发给后端服务器。 后端服务器将响应返回给代理服务器,再由代理服务器将响应转发给客户端。

reverse_proxy

反向代理的优势在于:

  • 负载均衡,提高系统的整体性能和稳定性。
  • 隐藏真实服务器的信息,提高安全性
  • 缓存静态资源,减少后端服务器的负载,提高响应速度

工具介绍

frp 是一个用于内网穿透的反向代理应用, 可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

通过在具有公网 IP 的节点上部署 frp 服务端,可以将内网服务穿透到公网。此外还提供诸多专业功能特性:

  • 客户端服务端通信支持 TCP、QUIC、KCP 以及 Websocket 等多种协议。
  • 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间,降低请求延迟。
  • 代理组间的负载均衡。
  • 端口复用,多个服务通过同一个服务端端口暴露。
  • 支持 P2P 通信,流量不经过服务器中转,充分利用带宽资源。
  • 多个原生支持的客户端插件(静态文件查看,HTTPS/HTTP 协议转换,HTTP、SOCK5 代理等), 便于独立使用 frp 客户端完成某些工作。
  • 高度扩展性的服务端插件系统,易于结合自身需求进行功能扩展。
  • 服务端和客户端 UI 页面。

整体架构

frp 工具由以下两个部分组成:

  • frps服务端,部署在具有公网 IP 的节点上,用于接收客户端请求并转发到内网服务。
  • frpc客户端,部署在内网环境中,用于将内网服务请求发送到服务端。

通过frpcfrps的紧密配合,就能最终实现内网穿透的功能。在内网穿透服务搭建完成后, 任何能访问互联网的用户都可以通过公网 IP 向内网服务发起请求。以下架构图展示了成功建立 frp 服务后的工作状态:

architecture

可以看到,该模型中包含了三个主体,由上至下分别是:

  • 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行。