• Welcome to Journal web site.

我是 PHP 程序员

- 开发无止境 -

Next
Prev

内网穿透工具--FRP_风雨兼程--远方的博客_host_header_rewrite

Data: 2015-08-19 02:26:09Form: JournalClick: 7

内网穿透工具--FRP
内网穿透工具--FRP_风雨兼程--远方的博客-CSDN博客_host_header_rewrite
  1. 对于没有公网 IP 的内网用户来说,远程管理或在外网访问内网机器上的服务是一个问题。

  2. 今天给大家介绍一款好用内网穿透工具 FRP,FRP 全名:Fast Reverse Proxy。FRP 是一个使用 Go 语言开发的高性能的反向代理应用,可以帮助您轻松地进行内网穿透,对外网提供服务。FRP 支持 TCP、UDP、HTTP、HTTPS等协议类型,并且支持 Web 服务根据域名进行路由转发。

FRP 项目地址:https://github.com/fatedier/frp

FRP 的作用

  1. 利用处于内网或防火墙后的机器,对外网环境提供 HTTP 或 HTTPS 服务。

  2. 对于 HTTP, HTTPS 服务支持基于域名的虚拟主机,支持自定义域名绑定,使多个域名可以共用一个 80 端口。

  3. 利用处于内网或防火墙后的机器,对外网环境提供 TCP 和 UDP 服务,例如在家里通过 SSH 访问处于公司内网环境内的主机。

FRP 安装

FRP 采用 Go 语言开发,支持 Windows、Linux、MacOS、ARM等多平台部署。FRP 安装非常容易,只需下载对应系统平台的软件包,并解压就可用。

这里以 Linux 为例,为了方便管理我们把解压后的目录重命名为 frp :

 wget https://github.com/fatedier/frp/releases/download/v0.15.1/frp_0.15.1_linux_amd64.tar.gz
 tar xzvf frp_0.15.1_linux_amd64.tar.gz
 mv frp_0.15.1_linux_amd64 frp

更多平台的软件包下载地址:https://github.com/fatedier/frp/releases

FRP 服务端配置

配置 FRP 服务端的前提条件是需要一台具有**公网 IP **的设备,得益于 FRP 是 Go 语言开发的,具有良好的跨平台特性。你可以在 Windows、Linux、MacOS、ARM等几乎任何可联网设备上部署。

这里以 Linux 为例,FRP 默认给出两个服务端配置文件,一个是简版的 frps.ini,另一个是完整版本 frps_full.ini。
我们先来看看简版的 frps.ini,通过这个配置可以快速的搭建起一个 FRP 服务端。

  1. $ cat frps.ini
     
    [common]
    bind_port = 7000
    默认配置中监听的是 7000 端口,可根据自己实际情况修改。
     
    启动 FRP 服务端
    $ ./frps -c ./frps.ini
    2018/01/25 10:52:45 [I] [service.go:96] frps tcp listen on 0.0.0.0:7000
    2018/01/25 10:52:45 [I] [main.go:112] Start frps success
    2018/01/25 10:52:45 [I] [main.go:114] PrivilegeMode is enabled, you should pay more attention to security issues

通过上面简单的两步就可以成功启动一个监听在 7000 端口的 FRP 服务端。

FRP 客户端配置

和 FRP 服务端类似,FRP 默认也给出两个客户端配置文件,一个是简版的 frpc.ini,另一个是完整版本 frpc_full.ini。
这里同样以简版的 frpc.ini 文件为例,假设 FRP 服务端所在服务器的公网 IP 为 4.3.2.1。

  1. $ vim frpc.ini
     
    [common]
    # server_addr 为 FRP 服务端的公网 IP
    server_addr = 4.3.2.1
    # server_port 为 FRP 服务端监听的端口
    server_port = 7000
    启动 FRP 客户端
    $ ./frpc -c ./frpc.ini
    2018/01/25 11:15:49 [I] [proxy_manager.go:284] proxy removed: []
    2018/01/25 11:15:49 [I] [proxy_manager.go:294] proxy added: []
    2018/01/25 11:15:49 [I] [proxy_manager.go:317] visitor removed: []
    2018/01/25 11:15:49 [I] [proxy_manager.go:326] visitor added: []
    2018/01/25 11:15:49 [I] [control.go:240] [83775d7388b8e7d9] login to server success
    , get run id [83775d7388b8e7d9], server udp port [0]

 

这样就可以成功在 FRP 服务端上成功建立一个客户端连接,当然现在还并不能对外提供任何内网机器上的服务,因为我们并还没有在 FRP 服务端注册任何内网服务的端口。

FRP 使用实例

下面我们就来看几个常用的例子,通过这些例子来了解下 FRP 是如何实现内网服务穿透的。

通过 TCP 访问内网机器

这里以访问 SSH 服务为例, 修改 FRP 客户端配置文件 frpc.ini 文件并增加如下内容:

  1. $ cat frpc.ini
     
    [ssh]
    type = tcp
    local_ip = 127.0.0.1
    local_port = 22
    remote_port = 6000
    启动 FRP 客户端
    $ ./frpc -c ./frpc.ini
    2018/01/25 12:21:23 [I] [proxy_manager.go:284] proxy removed: []
    2018/01/25 12:21:23 [I] [proxy_manager.go:294] proxy added: [ssh]
    2018/01/25 12:21:23 [I] [proxy_manager.go:317] visitor removed: []
    2018/01/25 12:21:23 [I] [proxy_manager.go:326] visitor added: []
    2018/01/25 12:21:23 [I] [control.go:240] [3b468a55191341cb] login to server success
    , get run id [3b468a55191341cb], server udp port [0]
    2018/01/25 12:21:23 [I] [control.go:165] [3b468a55191341cb] [ssh] start proxy success

 

这样就在 FRP 服务端上成功注册了一个端口为 6000 的服务,接下来我们就可以通过这个端口访问内网机器上 SSH 服务,假设用户名为 mike:
$ ssh -oPort=6000 mike@4.3.2.1

通过自定义域名访问部署于内网的 Web 服务

有时需要在公有网络通过域名访问我们在本地环境搭建的 Web 服务,但是由于本地环境机器并没有公网 IP,无法将域名直接解析到本地的机器。
现在通过 FRP 就可以很容易实现这一功能,这里以 HTTP 服务为例:首先修改 FRP 服务端配置文件,通过 vhost_http_port 参数来设置 HTTP 访问端口,这里将 HTTP 访问端口设为 8080。

  1. $ vim frps.ini
    [common]
    bind_port = 7000
    vhost_http_port = 8080
    启动 FRP 服务端
    $ ./frps -c ./frps.ini
    2018/01/25 13:33:26 [I] [service.go:96] frps tcp listen on 0.0.0.0:7000
    2018/01/25 13:33:26 [I] [service.go:125] http service listen on 0.0.0.0:8080
    2018/01/25 13:33:26 [I] [main.go:112] Start frps success
    2018/01/25 13:33:26 [I] [main.go:114] PrivilegeMode is enabled, you should pay more attention to security issues
    其次我们在修改 FRP 客户端配置文件并增加如下内容:
    $ vim frpc.ini
     
    [web]
    type = http
    local_port = 80
    custom_domains = **.***.com
    这里通过 local_port 和 custom_domains 参数来设置本地机器上 Web 服务对应的端口和自定义的域名,这里我们分别设置端口为 80,对应域名为 **.***.com。
    启动 FRP 客户端
    $ ./frpc -c ./frpc.ini
    2018/01/25 13:56:11 [I] [proxy_manager.go:284] proxy removed: []
    2018/01/25 13:56:11 [I] [proxy_manager.go:294] proxy added: [web ssh]
    2018/01/25 13:56:11 [I] [proxy_manager.go:317] visitor removed: []
    2018/01/25 13:56:11 [I] [proxy_manager.go:326] visitor added: []
    2018/01/25 13:56:11 [I] [control.go:240] [296fe9e31a551e07] login to server success, get run id [296fe9e31a551e07], server udp port [0]
    2018/01/25 13:56:11 [I] [control.go:165] [296fe9e31a551e07] [web] start proxy success
    2018/01/25 13:56:11 [I] [control.go:165] [296fe9e31a551e07] [ssh] start proxy success

 

最后将 ..com 的域名 A 记录解析到 FRP 服务器的公网 IP 上,现在便可以通过 http://.*.com:8080 这个 URL 访问到处于内网机器上对应的 Web 服务。

HTTPS 服务配置方法类似,只需将 vhost_http_port 替换为 vhost_https_port, type 设置为 https 即可。

通过密码保护你的 Web 服务

由于所有客户端共用一个 FRP 服务端的 HTTP 服务端口,任何知道你的域名和 URL 的人都能访问到你部署在内网的 Web 服务,但是在某些场景下需要确保只有限定的用户才能访问。
FRP 支持通过 HTTP Basic Auth 来保护你的 Web 服务,使用户需要通过用户名和密码才能访问到你的服务。需要实现此功能主要需要在 FRP 客户端的配置文件中添加用户名和密码的设置。

  1. $ vim frpc.ini
     
    [web]
    type = http
    local_port = 80
    custom_domains = **.***.com
     
     
    ## 设置认证的用户名
     
     
    http_user = abc
     
     
    ## 设置认证的密码
     
     
    http_pwd = abc

这时访问 http://.*.com:8080 这个 URL 时就需要输入配置的用户名和密码才能访问。
该功能目前仅限于 HTTP 类型的代理。

给 Web 服务增加自定义二级域名

在多人同时使用一个 FRP 服务端实现 Web 服务时,通过自定义二级域名的方式来使用会更加方便。
通过在 FRP 服务端的配置文件中配置 subdomain_host参数就可以启用该特性。之后在 FRP 客户端的 http、https 类型的代理中可以不配置 custom_domains,而是配置一个 subdomain 参数。
然后只需要将 *.{subdomain_host} 解析到 FRP 服务端所在服务器。之后用户可以通过 subdomain 自行指定自己的 Web 服务所需要使用的二级域名,并通过 {subdomain}.{subdomain_host} 来访问自己的 Web 服务。
首先我们在 FRP 服务端配置 subdomain_host 参数:

$ vim frps.ini
[common]
subdomain_host = ***.com
其次在 FRP 客户端配置文件配置 subdomain 参数:
$ vim frpc.ini
[web]
type = http
local_port = 80
subdomain = test
  1. 然后将泛域名 .com 解析到 FRP 服务端所在服务器的公网 IP 地址。FRP 服务端 和 FRP 客户端都启动成功后,通过 test.**.com 就可以访问到内网的 Web 服务。

同一个 HTTP 或 HTTPS 类型的代理中 custom_domains 和 subdomain 可以同时配置。

需要注意的是如果 FPR 服务端配置了 subdomain_host,则 custom_domains 中不能是属于 subdomain_host 的子域名或者泛域名。

修改 Host Header

通常情况下 FRP 不会修改转发的任何数据。但有一些后端服务会根据 HTTP 请求 header 中的 host 字段来展现不同的网站,例如 Nginx 的虚拟主机服务,启用 host-header 的修改功能可以动态修改 HTTP 请求中的 host 字段。
实现此功能只需要在 FRP 客户端配置文件中定义 host_header_rewrite 参数。

  1. $ vim frpc.ini
    [web]
    type = http
    local_port = 80
    custom_domains = test.***.com
    host_header_rewrite = dev.***.com
    原来 HTTP 请求中的 host 字段 test.***.com 转发到后端服务时会被替换为 dev.***.com。

该功能仅限于 HTTP 类型的代理。

URL 路由

FRP 支持根据请求的 URL 路径路由转发到不同的后端服务。要实现这个功能可通过 FRP 客户端配置文件中的 locations 字段来指定。

  1. $ vim frpc.ini
     
    [web01]
    type = http
    local_port = 80
    custom_domains = web.***.com
    locations = /
     
    [web02]
    type = http
    local_port = 81
    custom_domains = web.***.com
    locations = /news,/about

按照上述的示例配置后,web.***.com 这个域名下所有以 /news 以及 /about 作为前缀的 URL 请求都会被转发到后端 web02 所在的后端服务,其余的请求会被转发到 web01 所在的后端服务。
目前仅支持最大前缀匹配,之后会考虑支持正则匹配。

通过 UDP 访问内网机器

DNS 查询请求通常使用 UDP 协议,FRP 支持对内网 UDP 服务的穿透,配置方式和 TCP 基本一致。这里以转发到 Google 的 DNS 查询服务器 8.8.8.8 的 UDP 端口为例。
首先修改 FRP 客户端配置文件,并增加如下内容:

$ vim frpc.ini
[dns]
type = udp
local_ip = 8.8.8.8
local_port = 53
remote_port = 6001

要转发到内网 DNS 服务器只需把 local_ip 改成对应 IP 即可。

其次重新启动 FRP 客户端:

  1. $ ./frpc -c ./frpc.ini
    2018/01/25 14:54:17 [I] [proxy_manager.go:284] proxy removed: []
    2018/01/25 14:54:17 [I] [proxy_manager.go:294] proxy added: [ssh web dns]
    2018/01/25 14:54:17 [I] [proxy_manager.go:317] visitor removed: []
    2018/01/25 14:54:17 [I] [proxy_manager.go:326] visitor added: []
    2018/01/25 14:54:17 [I] [control.go:240] [33e1de8a771112a6] login to server success, get run id [33e1de8a771112a6], server udp port [0]
    2018/01/25 14:54:17 [I] [control.go:165] [33e1de8a771112a6] [ssh] start proxy success
    2018/01/25 14:54:17 [I] [control.go:165] [33e1de8a771112a6] [web] start proxy success
    2018/01/25 14:54:17 [I] [control.go:165] [33e1de8a771112a6] [dns] start proxy success

最后通过 dig 命令测试 UDP 包转发是否成功,预期会返回 www.google.com 域名的解析结果:

  1. $ dig @4.3.2.1 -p 6001 www.google.com
    ...
     
    ;; QUESTION SECTION:
    ;www.google.com. IN A
     
    ;; ANSWER SECTION:
    www.google.com. 79 IN A 69.63.184.30
     

转发 Unix 域套接字

通过 TCP 端口访问内网的 Unix 域套接字,这里以和本地机器上的 Docker Daemon 通信为例。
首先修改 FRP 客户端配置文件,并增加如下内容:

  1. $ vim frpc.ini
    [unix_domain_socket]
    type = tcp
    remote_port = 6002
    plugin = unix_domain_socket
    plugin_unix_path = /var/run/docker.sock
    这里主要是使用 plugin 和 plugin_unix_path 两个参数启用了 unix_domain_socket 插件和
    配置对应的套接字路径。

其次重新启动 FRP 客户端:

  1. $ ./frpc -c ./frpc.ini
     
    2018/01/25 15:09:33 [I] [proxy_manager.go:284] proxy removed: []
    2018/01/25 15:09:33 [I] [proxy_manager.go:294] proxy added: [ssh web dns unix_domain_socket]
    2018/01/25 15:09:33 [I] [proxy_manager.go:317] visitor removed: []
    2018/01/25 15:09:33 [I] [proxy_manager.go:326] visitor added: []
    2018/01/25 15:09:33 [I] [control.go:240] [f6424f0deb8b6ff7] login to server success, get run id [f6424f0deb8b6ff7], server udp port [0]
    2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [ssh] start proxy success
    2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [web] start proxy success
    2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [dns] start proxy success
    2018/01/25 15:09:33 [I] [control.go:165] [f6424f0deb8b6ff7] [unix_domain_socket] start proxy success

最后通过 curl 命令查看 Docker 版本信息进行测试:

  1. $ curl http://4.3.2.1:6002/version
     
    {"Platform":{"Name":""},"Components":[{"Name":"Engine","Version":"17.12.0-ce",
    "Details":{"ApiVersion":"1.35","Arch":"amd64",
    "BuildTime":"2017-12-27T20:12:29.000000000+00:00","Experimental":"true",
    "GitCommit":"c97c6d6","GoVersion":"go1.9.2","KernelVersion":"4.9.60-linuxkit-aufs",
    "MinAPIVersion":"1.12","Os":"linux"}}],"Version":"17.12.0-ce","ApiVersion":"1.35",
    "MinAPIVersion":"1.12","GitCommit":"c97c6d6","GoVersion":"go1.9.2","Os":"linux",
    "Arch":"amd64","KernelVersion":"4.9.60-linuxkit-aufs","Experimental":true,
    "BuildTime":"2017-12-27T20:12:29.000000000+00:00"}

FRP 从 1.5 版本开始支持客户端热加载配置文件,并不用每次都重启客户端程序。具体方法在后文 FRP 客户端热加载配置文件部分讲解。

FRP 高级进阶

给 FRP 服务端增加一个 Dashboard

通过 Dashboard 可以方便的查看 FRP 的状态以及代理统计信息展示,要使用这个功能首先需要在 FRP 服务端配置文件中指定 Dashboard 服务使用的端口:

  1. $ vim frps.ini
     
    [common]
     
    # 指定 Dashboard 的监听的 IP 地址
    dashboard_addr = 0.0.0.0
     
    # 指定 Dashboard 的监听的端口
    dashboard_port = 7500
     
    # 指定访问 Dashboard 的用户名
    dashboard_user = admin
     
    # 指定访问 Dashboard 的端口
    dashboard_pwd = admin
    其次重新启动 FRP 服务端:
    $ ./frps -c ./frps.ini
     
    2018/01/25 16:39:29 [I] [service.go:96] frps tcp listen on 0.0.0.0:7000
    2018/01/25 16:39:29 [I] [service.go:125] http service listen on 0.0.0.0:8080
    2018/01/25 16:39:29 [I] [service.go:164] Dashboard listen on 0.0.0.0:7500
    2018/01/25 16:39:29 [I] [main.go:112] Start frps success
    2018/01/25 16:39:29 [I] [main.go:114] PrivilegeMode is enabled, you should pay more attention to security issues

最后通过 http://[server_addr]:7500 访问 Dashboard 界面,用户名密码默认都为 admin。

给 FRP 服务端加上身份验证

默认情况下只要知道 FRP 服务端开放的端口,任意 FRP 客户端都可以随意在服务端上注册端口映射,这样对于在公网上的 FRP 服务来说显然不太安全。FRP 提供了身份验证机制来提高 FRP 服务端的安全性。要启用这一特性也很简单,只需在 FRP 服务端和 FRP 客户端的 common 配置中启用 privilege_token 参数就行。

  1. [common]
    privilege_token = 12345678

启用这一特性后,只有 FRP 服务端和 FRP 客户端的 common 配置中的 privilege_token 参数一致身份验证才会通过,FRP 客户端才能成功在 FRP 服务端注册端口映射。否则就会注册失败,出现类似下面的错误:

  1. 2018/01/25 17:29:27 [I] [proxy_manager.go:284] proxy removed: []
    2018/01/25 17:29:27 [I] [proxy_manager.go:294] proxy added: [ssh web dns unix_domain_socket]
    2018/01/25 17:29:27 [I] [proxy_manager.go:317] visitor removed: []
    2018/01/25 17:29:27 [I] [proxy_manager.go:326] visitor added: []
    2018/01/25 17:29:27 [E] [control.go:230] authorization failed
    2018/01/25 17:29:27 [W] [control.go:109] login to server failed: authorization failed
    authorization failed

需要注意的是 FRP 客户端所在机器和 FRP 服务端所在机器的时间相差不能超过 15 分钟,因为时间戳会被用于加密验证中,防止报文被劫持后被其他人利用。这个超时时间可以在配置文件中通过 authentication_timeout 这个参数来修改,单位为秒,默认值为 900,即 15 分钟。如果修改为 0,则 FRP 服务端将不对身份验证报文的时间戳进行超时校验。

FRP 客户端热加载配置文件

当修改了 FRP 客户端中的配置文件,从 0.15 版本开始可以通过 frpc reload 命令来动态加载配置文件,通常会在 10 秒内完成代理的更新。
启用此功能需要在 FRP 客户端配置文件中启用 admin 端口,用于提供 API 服务。配置如下:
$ vim frpc.ini

[common]
admin_addr = 127.0.0.1
admin_port = 7400
重启 FRP 客户端,以后就可通过热加载方式进行 FRP 客户端配置变更了。

  1. $ ./frpc -c ./frpc.ini
    2018/01/25 18:04:25 [I] [proxy_manager.go:326] visitor added: []
    2018/01/25 18:04:25 [I] [control.go:240] [3653b9a878f8acc7] login to server success, get run id [3653b9a878f8acc7], server udp port [0]
    2018/01/25 18:04:25 [I] [service.go:49] admin server listen on 127.0.0.1:7400
    2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [ssh] start proxy success
    2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [web] start proxy success
    2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [dns] start proxy success
    2018/01/25 18:04:25 [I] [control.go:165] [3653b9a878f8acc7] [unix_domain_socket] start proxy success
     
    $ ./frpc reload -c ./frpc.ini
    reload success

等待一段时间后客户端会根据新的配置文件创建、更新、删除代理。
需要注意的是 [common] 中的参数除了 start 外目前无法被修改。

启用 admin_addr 后,还可以通过 frpc status -c ./frpc.ini 命令在 FRP 客户端很方便的查看当前代理状态信息。

  1. $ ./frpc status -c ./frpc.ini
     
    Proxy Status...
    TCP
    Name Status LocalAddr Plugin RemoteAddr Error
    ssh running 127.0.0.1:22 4.3.2.1:6000
    unix_domain_socket running unix_domain_socket 4.3.2.1:6002
     
    UDP
    Name Status LocalAddr Plugin RemoteAddr Error
    dns running 8.8.8.8:53 4.3.2.1:6001
     
    HTTP
    Name Status LocalAddr Plugin RemoteAddr Error

web running 127.0.0.1:80 .*.com:8080

给 FRP 服务端增加端口白名单

为了防止 FRP 端口被滥用,FRP 提供了指定允许哪些端口被分配的功能。可通过 FRP 服务端的配置文件中 privilege_allow_ports 参数来指定:

  1. $ vim frps.ini
     
    [common]
    privilege_allow_ports = 2000-3000,3001,3003,4000-5000

privilege_allow_ports 可以配置允许使用的某个指定端口或者是一个范围内的所有端口,以 , 分隔,指定的范围以 - 分隔。
当使用不允许的端口注册时,就会注册失败。出现类似以下错误:

  1. $ ./frpc status -c ./frpc.ini
    Proxy Status...
    TCP
    Name Status LocalAddr Plugin RemoteAddr Error
    ssh start error 127.0.0.1:22 4.3.2.1:60000 port not allowed
    unix_domain_socket start error unix_domain_socket 4.3.2.1:60002 port not allowed

启用 TCP 多路复用

从 v0.10.0 版本开始,客户端和服务器端之间的连接支持多路复用,不再需要为每一个用户请求创建一个连接,使连接建立的延迟降低,并且避免了大量文件描述符的占用,使 FRP 可以承载更高的并发数。
该功能默认启用,如需关闭可以在 FRP 服务端配置文件和 FRP 客户端配置文件中配置,该配置项在服务端和客户端必须一致:

# frps.ini 和 frpc.ini 中
[common]
tcp_mux = falseFRP

底层通信启用 KCP 协议

FRP 从 v0.12.0 版本开始,底层通信协议支持选择 KCP 协议,在弱网络环境下传输效率会提升明显,但是会有一些额外的流量消耗。
要开启 KCP 协议支持,首先要在 FRP 服务端配置文件中启用 KCP 协议支持:

$ vim frps.ini
[common]
bind_port = 7000
# 指定一个 UDP 端口用于接收客户端请求 KCP 绑定的是 UDP 端口,可以和 bind_port 一样
kcp_bind_port = 7000
其次是在 FRP 客户端配置文件指定需要使用的协议类型,目前只支持 TCP 和 KCP。其它代理配置不需要变更:
$ vim frpc.ini
[common]
server_addr = 4.3.2.1
# server_port 指定为 FRP 服务端里 kcp_bind_port 指定的端口
server_port = 7000
# 指定需要使用的协议类型,默认类型为 TCP
protocol = kcp
  1. 其次是在 FRP 客户端配置文件指定需要使用的协议类型,目前只支持 TCP 和 KCP。其它代理配置不需要变更:

需要注意开放相关机器上的 UDP 端口的访问权限。

给 FRP 服务端配置连接池

默认情况下,当用户请求建立连接后,FRP 服务端才会请求 FRP 客户端主动与后端服务建立一个连接。
当为指定的 FRP 服务端启用连接池功能后,FRP 会预先和后端服务建立起指定数量的连接,每次接收到用户请求后,会从连接池中取出一个连接和用户连接关联起来,避免了等待与后端服务建立连接以及 FRP 客户端 和 FRP 服务端之间传递控制信息的时间。
首先需要在 FRP 服务端配置文件中设置每个代理可以创建的连接池上限,避免大量资源占用,客户端设置超过此配置后会被调整到当前值:

$ vim frps.ini
[common]
max_pool_count = 5
其次在 FRP 客户端配置文件中为客户端启用连接池,指定预创建连接的数量:
$ vim frpc.ini
[common]
pool_count = 1
    *
  1. 其次在 FRP 客户端配置文件中为客户端启用连接池,指定预创建连接的数量:

此功能比较适合有大量短连接请求时开启。

加密与压缩

如果公司内网防火墙对外网访问进行了流量识别与屏蔽,例如禁止了 SSH 协议等,可通过设置 use_encryption = true,将 FRP 客户端 与 FRP 服务端之间的通信内容加密传输,将会有效防止流量被拦截。
如果传输的报文长度较长,通过设置 use_compression = true 对传输内容进行压缩,可以有效减小 FRP 客户端 与 FRP 服务端之间的网络流量,来加快流量转发速度,但是会额外消耗一些 CPU 资源。
这两个功能默认是不开启的,需要在 FRP 客户端配置文件中通过配置来为指定的代理启用加密与压缩的功能,压缩算法使用的是 snappy。

$ vim frpc.ini
 
[ssh]
type = tcp
local_port = 22
remote_port = 6000
use_encryption = true
use_compression = true

通过 FRP 客户端代理其它内网机器访问外网

FRP 客户端内置了 http_proxy 和 socks5 插件,通过这两个插件可以使其它内网机器通过 FPR 客户端的的网络访问互联网。
要启用此功能,首先需要在 FRP 客户端配置文件中启用相关插件,这里以 http_proxy 插件为例:

$ vim frpc.ini
 
[common]
server_addr = 4.3.2.1
server_port = 7000
 
[http_proxy]
type = tcp
remote_port = 6000
plugin = http_proxy

其次将需要通过这个代理访问外网的内部机器的代理地址设置为 4.3.2.1:6000,这样就可以通过 FRP 客户端机器的网络访问互联网了。
http_proxy 插件也支持认证机制,如果需要启用认证可通过配置参数 plugin_http_user 和 plugin_http_passwd 启用。
如需启用 Socks5 代理,只需将 plugin 的值更换为 socks5 即可。

通过代理连接 FRP 服务端

在只能通过代理访问外网的环境内,FRP 客户端支持通过 HTTP_PROXY 参数来配置代理和 FRP 服务端进行通信。要使用此功能可以通过设置系统环境变量 HTTP_PROXY 或者通过在 FRP 客户端的配置文件中设置 http_proxy 参数来使用此功能。

  1. $ vim frpc.ini
     
    [common]
    server_addr = 4.3.2.1
    server_port = 7000
    protocol = tcp
    http_proxy = http://user:pwd@4.3.2.2:8080

仅在 protocol = tcp 时生效,暂时不支持 kcp 协议。

安全地暴露内网服务

对于一些比较敏感的服务如果直接暴露于公网上将会存在安全隐患,FRP 也提供了一种安全的转发方式 STCP。使用 STCP (secret tcp) 类型的代理可以避免让任何人都能访问到穿透到公网的内网服务,要使用 STCP 模式访问者需要单独运行另外一个 FRP 客户端。
下面就以创建一个只有自己能访问到的 SSH 服务代理为例,FRP 服务端和其它的部署步骤相同,主要区别是在 FRP 客户端上。
首先配置 FRP 客户端,和常规 TCP 转发不同的是这里不需要指定远程端口。

 
$ vim frpc.ini
[common]
server_addr = 4.3.2.1
server_port = 7000
 
[secret_ssh]
type = stcp
 
# 只有 sk 一致的用户才能访问到此服务
sk = abcdefg
local_ip = 127.0.0.1
local_port = 22

其次在要访问这个服务的机器上启动另外一个 FRP 客户端,配置如下:

Name:
<提交>