0%

使用frp进行内网穿透

一、背景

内网服务所在设备(比如你家里的电脑)没有外网IP,只能主动访问外网,但外网无法直接找到并连接该内网服务。
frp的本质是:借助有外网IP的服务器和内网某台设备,搭建一个“中转桥梁”,让外网流量通过这个桥梁到达内网服务

二、frp核心工作原理

frp分为服务端(frps,部署在具有外网IP的服务器)和客户端(frpc,部署在内网某台设备):

  1. frpc主动连接frps,建立TCP长连接
  2. 当外网用户要访问内网服务时,先把请求发给frps
  3. frps通过已建立的TCP长连接,把请求转发给frpc
  4. frpc收到请求后,转发给内网的目标服务,再把响应按原路返回给外网用户

三、使用frp进行内网穿透最简实践

3.1、frps服务端

  1. 一台具有外网IP的服务器
  2. 安装frps
  3. 防火墙/安全策略配置放行监听端口(此例中是7000和8080)
  4. 新建/修改frps.ini如下
  5. Linux下执行./frps -c ./frps.ini命令启动frps服务端

frps.ini

1
2
3
4
5
[common]
# frps服务端监听端口(frpc客户端须连接此端口)
bind_port = 7000
# 可选:设置令牌,防止他人滥用(frpc客户端须一致)
token = 12345678

3.2、frpc客户端

  1. 内网某台设备
  2. 安装frpc(最好跟frps版本一致)
  3. 新建/修改frpc.ini如下
  4. Linux下执行./frpc -c ./frpc.ini命令启动frpc客户端

frpc.ini

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[common]
# 外网服务器IP
server_addr = <外网服务器IP>
# frps服务端监听的端口(和frps.ini的bind_port一致)
server_port = 7000
# 令牌(和frps服务端一致)
token = 12345678

# 自定义名称(如web),标识这个映射规则
[web]
# 映射类型(http/tcp/udp,这里用tcp适配大部分服务)
type = tcp
# 内网服务的IP(本地服务填127.0.0.1)
local_ip = 127.0.0.1
# 内网服务的端口(本地Web服务跑在80端口)
local_port = 80
# 外网服务器暴露的实际业务监听端口(访问外网此端口即可映射到以上内网服务)
remote_port = 8080

四、详细工作流程

以以上最简实践为例进行说明。

详细工作流程图示如下:

对关键步骤进行拆解:

  1. 初始化建立TCP长连接,核心步骤
    • frpc启动后,主动向frps发起TCP连接,frps的监听端口为bind_port = 7000,一直保持这个连接不中断(TCP长连接)
  2. 外网请求转发(核心转发)
    • 外网用户(ClientIP:ClientPort)访问外网IP:8080(remote_port = 8080),这个请求先到达外网服务器的frps
    • frps完成以下动作:
      1. 根据外网端口识别相应映射规则(type = tcplocal_ip = 127.0.0.1local_port = 80
      2. 根据映射规则,构造实际业务报文,报文类型为type = tcp,源端点为ClientIP:ClientPort,目的端点为127.0.0.1:80(local_ip:local_port)
      3. 将实际业务报文作为内容嵌入外围TCP报文,通过frps和frpc间TCP长连接,把请求数据转发给内网设备的frpc
  3. 内网响应回传
    • 内网设备的frpc收到请求
    • frpc完成以下动作
      1. 提取实际业务报文,报文类型为type = tcp,源端点为ClientIP:ClientPort,目的端点为127.0.0.1:80(local_ip:local_port)
      2. 实际业务报文的目的端点为127.0.0.1:80(local_ip:local_port),把请求转发给内网的目标服务(这里是本地的80端口对应的Web服务)
    • 内网服务返回响应给frpc
    • frpc完成以下动作:
      1. 根据映射规则,构造实际业务报文,报文类型为type = tcp,源端点为127.0.0.1:80(local_ip:local_port),目的端点为ClientIP:ClientPort
      2. 将实际业务报文作为内容嵌入外围TCP报文,通过frps和frpc间TCP长连接,把请求数据转发给外网服务器的frps
    • 外网服务器的frps收到请求
    • frps完成以下动作:
      1. 提取实际业务报文,报文类型为type = tcp,源端点为127.0.0.1:80(local_ip:local_port),目的端点为ClientIP:ClientPort
      2. 实际业务报文的目的端点为ClientIP:ClientPort,把请求转发给外网用户

参考文献

[1]https://gofrp.org/zh-cn/

您的支持将鼓励我继续分享!