一、背景
内网服务所在设备(比如你家里的电脑)没有外网IP,只能主动访问外网,但外网无法直接找到并连接该内网服务。
frp的本质是:借助有外网IP的服务器和内网某台设备,搭建一个“中转桥梁”,让外网流量通过这个桥梁到达内网服务。
二、frp核心工作原理
frp分为服务端(frps,部署在具有外网IP的服务器)和客户端(frpc,部署在内网某台设备):
- frpc主动连接frps,建立TCP长连接
- 当外网用户要访问内网服务时,先把请求发给frps
- frps通过已建立的TCP长连接,把请求转发给frpc
- frpc收到请求后,转发给内网的目标服务,再把响应按原路返回给外网用户
三、使用frp进行内网穿透最简实践
3.1、frps服务端
- 一台具有外网IP的服务器
- 安装frps
- 防火墙/安全策略配置放行监听端口(此例中是7000和8080)
- 新建/修改
frps.ini如下 - Linux下执行
./frps -c ./frps.ini命令启动frps服务端
frps.ini
1 | [common] |
3.2、frpc客户端
- 内网某台设备
- 安装frpc(最好跟frps版本一致)
- 新建/修改
frpc.ini如下 - Linux下执行
./frpc -c ./frpc.ini命令启动frpc客户端
frpc.ini
1 | [common] |
四、详细工作流程
以以上最简实践为例进行说明。
详细工作流程图示如下:
对关键步骤进行拆解:
- 初始化建立TCP长连接,核心步骤
- frpc启动后,主动向frps发起TCP连接,frps的监听端口为
bind_port = 7000,一直保持这个连接不中断(TCP长连接)
- frpc启动后,主动向frps发起TCP连接,frps的监听端口为
- 外网请求转发(核心转发)
- 外网用户(
ClientIP:ClientPort)访问外网IP:8080(remote_port = 8080),这个请求先到达外网服务器的frps - frps完成以下动作:
- 根据外网端口识别相应映射规则(
type = tcp,local_ip = 127.0.0.1,local_port = 80) - 根据映射规则,构造实际业务报文,报文类型为
type = tcp,源端点为ClientIP:ClientPort,目的端点为127.0.0.1:80(local_ip:local_port) - 将实际业务报文作为内容嵌入外围TCP报文,通过frps和frpc间TCP长连接,把请求数据转发给内网设备的frpc
- 根据外网端口识别相应映射规则(
- 外网用户(
- 内网响应回传
- 内网设备的frpc收到请求
- frpc完成以下动作
- 提取实际业务报文,报文类型为
type = tcp,源端点为ClientIP:ClientPort,目的端点为127.0.0.1:80(local_ip:local_port) - 实际业务报文的目的端点为
127.0.0.1:80(local_ip:local_port),把请求转发给内网的目标服务(这里是本地的80端口对应的Web服务)
- 提取实际业务报文,报文类型为
- 内网服务返回响应给frpc
- frpc完成以下动作:
- 根据映射规则,构造实际业务报文,报文类型为
type = tcp,源端点为127.0.0.1:80(local_ip:local_port),目的端点为ClientIP:ClientPort - 将实际业务报文作为内容嵌入外围TCP报文,通过frps和frpc间TCP长连接,把请求数据转发给外网服务器的frps
- 根据映射规则,构造实际业务报文,报文类型为
- 外网服务器的frps收到请求
- frps完成以下动作:
- 提取实际业务报文,报文类型为
type = tcp,源端点为127.0.0.1:80(local_ip:local_port),目的端点为ClientIP:ClientPort - 实际业务报文的目的端点为
ClientIP:ClientPort,把请求转发给外网用户
- 提取实际业务报文,报文类型为