简单好用的内网穿透代理工具
frp
是一个专注于内网穿透的高性能的反向代理应用,支持 TCP
、UDP
、HTTP
、HTTPS
等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP
节点的中转暴露到公网。
1. frp 的特性介绍
一些概述便于您快速的了解 frp 工具
通过在具有公网 IP
的节点上部署 frp
服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:
- 代理组间的负载均衡
- 服务端和客户端
UI
页面 - 端口复用,多个服务通过同一个服务端端口暴露
- 高度扩展性的服务端插件系统,方便结合自身需求进行功能扩展
- 多个原生支持的客户端插件,便于独立使用
frp
客户端完成某些工作 - 客户端服务端通信支持
TCP
、KCP
以及Websocket
等多种协议 - 采用
TCP
连接流式复用,在单个连接间承载更多请求,节省连接建立时间
2. frp 的原理介绍
理解它们有助于您更好地了解和使用 frp 工具
- [1] 原理
frp
主要由 客户端(frpc
) 和 服务端(frps
) 组成,服务端通常部署在具有公网 IP
的机器上,客户端通常部署在需要穿透的内网服务所在的机器上。内网服务由于没有公网 IP
,不能被非局域网内的其他用户访问。用户通过访问服务端的 frps
,由 frp
负责根据请求的端口或其他信息将请求路由到对应的内网机器,从而实现通信。
- [2] 代理
在 frp
中一个代理对应一个需要暴露的内网服务,一个客户端支持同时配置多个代理。
- [3] 类型
编号 | 类型 | 描述 |
---|---|---|
1 | tcp |
单纯的 TCP 端口映射,服务端会根据不同的端口路由到不同的内网服务 |
2 | udp |
单纯的 UDP 端口映射,服务端会根据不同的端口路由到不同的内网服务 |
3 | http |
针对 HTTP 应用定制了一些额外的功能 |
4 | https |
针对 HTTPS 应用定制了一些额外的功能。 |
5 | stcp |
安全的 TCP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口 |
6 | sudp |
安全的 UDP 内网代理,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口 |
7 | xtcp |
点对点内网穿透代理,功能同 stcp,但是流量不需要经过服务器中转 |
8 | tcpmux |
支持服务端 TCP 端口的多路复用,通过同一个端口访问不同的内网服务 |
3. frp 的安装方式
关于如何安装 frp 的说明
frp
采用 Golang
语言编写,支持跨平台,仅需下载对应平台的二进制文件即可执行,没有额外依赖。目前可以在 Github
的 Release
页面中下载到最新版本的客户端和服务端二进制文件,所有文件被打包在一个压缩包中。
解压缩下载的压缩包,将其中的 frpc
拷贝到内网服务所在的机器上,将 frps
拷贝到具有公网 IP
的机器上,放置在任意目录。
# download
$ wget https://github.com/fatedier/frp/releases/download/v0.37.0/frp_0.37.0_linux_amd64.tar.gz
编写配置文件,先通过下面提供的命令来启动服务端和客户端。如果需要在后台长期运行,建议结合其他工具使用,例如 systemd
和 supervisor
工具。
# 启动服务端
$ ./frps -c ./frps.ini
# 启动客户端
$ ./frpc -c ./frpc.ini
4. Frp 的配置文件
配置文件如何编写可以参考示例中的内容
这里包括多个 常见的使用场景和配置 示例,你可以用来亲自部署和体验这些示例。
编号 | 类型 | 描述 |
---|---|---|
1 | 服务端配置 | frp 服务端详细配置说明 |
2 | 客户端配置 | frp 客户端的详细配置说明 |
3 | 代理配置 | frp 代理的详细配置说明 |
编号 | 类型 | 描述 |
---|---|---|
1 | 通过 SSH 访问内网机器 | 简单配置 TCP 类型的代理让用户访问到内网的服务器 |
2 | 自定义域名访问内网的 Web 服务 | 简单配置 HTTP 类型的代理让用户访问到内网的 Web 服务 |
3 | 转发 DNS 查询请求 | 通过简单配置 UDP 类型的代理转发 DNS 查询请求 |
4 | 转发 Unix 域套接字 | 配置 Unix 域客户端插件来通过 TCP 端口访问内网的 Unix 域服务 |
5 | 对外提供简单的文件访问服务 | 配置 static_file 客户端插件将本地文件暴露在公网上供其他人访问 |
6 | 为本地 HTTP 服务启用 HTTPS | https2http 插件可以让本地 HTTP 转换成 HTTPS 服务对外提供 |
7 | 安全地暴露内网服务 | 将会创建一个只有自己能访问到的 SSH 服务代理 |
8 | 点对点内网穿透 | 将会演示一种不通过服务器中转流量的方式来访问内网服务 |
- [1] 通过 SSH 访问内网机器
- 示例通过简单配置
TCP
类型的代理让用户访问到内网的服务器 - 编辑好如下配置文件之后,就可以分别启动
frps
和frpc
了 - 然后,就可以
SSH
来访问设置的内网机器了
- 示例通过简单配置
# 有公网IP的机器(已部署frps服务)
# 这里使用了最简化的配置,详情配置可参考官方文档
$ vim frps.ini
[common]
bind_port = 7000 # 设置frp服务器用户接收客户端连接的端口
# 在内网IP的机器(部署frpc服务)
# 默认情况下,SSH服务通常监听在22端口
$ vim frpc.ini
[common]
server_addr = x.x.x.x # 公网IP地址
server_port = 7000 # 公网设置frp服务器对应的端口
[ssh]
type = tcp
local_ip = 127.0.0.1 # 本地需要暴露到公网的服务地址
local_port = 22 # 本地需要暴露到公网的服务端口
remote_port = 6000 # 表示在frp服务端监听的端口
# 启动服务端
$ ./frps -c ./frps.ini
# 启动客户端
$ ./frpc -c ./frpc.ini
# 通过SSH访问内网机器
# frp会将请求x.x.x.x:6000的流量转发到内网机器的22端口
$ ssh -oPort=6000 [email protected]
- [2] 通过自定义域名访问内网的 Web 服务
- 通过简单配置
HTTP
类型的代理让用户访问到内网的Web
服务 - 编辑好如下配置文件之后,就可以分别启动
frps
和frpc
了 - 将
www.yourdomain.com
的域名A
记录解析到公网IP
地址上 - 然后,就可以绑定自定义域名和端口来访问内网机器的服务了
- 通过简单配置
HTTP
类型的代理相比于 TCP
类型,不仅在服务端只需要监听一个额外的端口 vhost_http_port
用于接收 HTTP
请求,还额外提供了基于 HTTP
协议的诸多功能。
# 有公网IP的机器(已部署frps服务)
$ vim frps.ini
[common]
bind_port = 7000 # 设置frp服务器用户接收客户端连接的端口
vhost_http_port = 8080 # 设置监听HTTP请求端口为8080
# 在内网IP的机器(部署frpc服务)
$ vim frpc.ini
[common]
server_addr = x.x.x.x # 公网IP地址
server_port = 7000 # 公网设置frp服务器对应的端口
[web]
type = http # 协议类型
local_port = 80 # 本地机器上Web服务监听的端口
custom_domains = www.yourdomain.com # 绑定自定义域名
# 启动服务端
$ ./frps -c ./frps.ini
# 启动客户端
$ ./frpc -c ./frpc.ini
# 通过浏览器访问
$ http://www.yourdomain.com:8080
- [3] 安全地暴露内网服务
- 将会创建一个只有自己能访问到的
SSH
服务代理
- 将会创建一个只有自己能访问到的
对于某些服务来说如果直接暴露于公网上将会存在安全隐患。使用 stcp
(secret tcp
) 类型的代理可以避免让任何人都能访问到要穿透的服务,但是访问者也需要运行另外一个 frpc
客户端。
# 有公网IP的机器(已部署frps服务)
$ vim frps.ini
[common]
bind_port = 7000 # 设置frp服务器用户接收客户端连接的端口
# 在内网IP的机器(部署frpc服务)
$ vim frpc.ini
[common]
server_addr = x.x.x.x # 公网IP地址
server_port = 7000 # 公网设置frp服务器对应的端口
[secret_ssh]
type = stcp # 使用的协议类型
sk = abcdefg # 只有sk一致的用户才能访问到此服务
local_ip = 127.0.0.1 # 本地需要暴露到公网的服务地址
local_port = 22 # 本地机器上Web服务监听的端口
# 想要访问内网服务的机器(部署frpc服务)
[common]
server_addr = x.x.x.x # 公网IP地址
server_port = 7000 # 公网设置frp服务器对应的端口
[secret_ssh_visitor]
type = stcp # 使用的协议类型
role = visitor # stcp的访问者
server_name = secret_ssh # 要访问的stcp代理的名字
sk = abcdefg # 只有sk一致的用户才能访问到此服务
bind_addr = 127.0.0.1 # 绑定本地地址用于访问SSH服务
bind_port = 6000 # 绑定本地端口用于访问SSH服务
# 启动服务端
$ ./frps -c ./frps.ini
# 启动客户端
$ ./frpc -c ./frpc.ini
# 启动客户端
$ ./frpc -c ./frpc.ini
# 通过SSH访问内网机器
$ ssh -oPort=6000 [email protected]
5. Frp 的高级配置
了解 frp 的一些通用功能
编号 | 对应高级特性 |
---|---|
1 | 配置文件 |
2 | 监控 |
3 | 身份认证 |
4 | Web 界面 |
5 | 负载均衡与健康检查 |
6 | 获取用户真实 IP |
7 | 范围端口映射 |
8 | 客户端 |
9 | 服务端管理 |
10 | 客户端插件 |
11 | 服务端插件 |
12 | 通信安全及优化 |
- [1] 身份认证
frp
配置文件,目前仅支持 ini
格式的配置文件,frps
和 frpc
各自支持不同的参数。frps
主要配置服务端的一些通用参数,frpc
则需要额外配置每一个代理的详细配置。目前 frpc
和 frps
之间支持两种身份验证方式,token
和 oidc
,默认为 token
。通过 frpc.ini
和 frps.ini
的 [common]
段落中配置 authentication_method
来指定要使用的身份验证方式。只有通过身份验证的客户端(frpc
)才能成功连接 frps
服务。
# 在frps配置 - Token
bind_port = 7000
authentication_method = token
token = 12345678
# 在frpc配置 - Token
[common]
server_addr = x.x.x.x
server_port = 7000
authentication_method = token
token = 12345678
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
- [2] Web 界面
目前 frpc
和 frps
分别内置了相应的 Web
界面方便用户使用。服务端 Dashboard
使用户可以通过浏览器查看 frp
的状态以及代理统计信息。客户端管理界面,frpc
内置的 Admin UI
可以帮助用户通过浏览器来查询和管理客户端的 proxy
状态和配置。
# 在frps配置
# http://[server_addr]:7500
[common]
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = admin
# 在frpc配置
# http://127.0.0.1:7400
[common]
admin_addr = 127.0.0.1
admin_port = 7400
admin_user = admin
admin_pwd = admin
- [3] 范围端口映射
在 frpc
的配置文件中可以指定映射多个端口,目前只支持 TCP
和 UDP
的代理类型。这一功能通过 range:
段落标记来实现,客户端会解析这个标记中的配置,将其拆分成多个 proxy
,每一个 proxy
以数字为后缀命名。实际连接成功后会创建 7
个 proxy
,命名为 test_tcp_0
, test_tcp_1
到 test_tcp_6
。
# 在frpc配置
# 映射本地6000-6005/6007这7个端口
[range:test_tcp]
type = tcp
local_ip = 127.0.0.1
local_port = 6000-6005,6007
remote_port = 6000-6005,6007
- [4] 服务端管理
# 在frps配置 - 端口白名单
[common]
allow_ports = 2000-3000,3001,3003,4000-50000
# 在frps配置 - 端口复用
bind_port = 443
vhost_https_port = 443
# 在frps配置 - 代理限速
[ssh]
type = tcp
local_port = 22
remote_port = 6000
bandwidth_limit = 1MB
6. 参考地址
送人玫瑰,手有余香!