snowdreamtech/frps Docker Images for Frp Based on Alpine and Debian.
(amd64, arm32v5, arm32v6, arm32v7, arm64v8, i386, mips64le, ppc64le,riscv64, s390x)
Usage Basic 1 2 docker run --restart=always --network host -d -v /etc/frp/frps.toml:/etc/frp/frps.toml --name frps snowdreamtech/frps docker run --restart=always --network host -d -v /etc/frp/frpc.toml:/etc/frp/frpc.toml --name frpc snowdreamtech/frpc
Alpine 1 2 docker run --restart=always --network host -d -v /etc/frp/frps.toml:/etc/frp/frps.toml --name frps snowdreamtech/frps:alpine docker run --restart=always --network host -d -v /etc/frp/frpc.toml:/etc/frp/frpc.toml --name frpc snowdreamtech/frpc:alpine
Debian 1 2 docker run --restart=always --network host -d -v /etc/frp/frps.toml:/etc/frp/frps.toml --name frps snowdreamtech/frps:debian docker run --restart=always --network host -d -v /etc/frp/frpc.toml:/etc/frp/frpc.toml --name frpc snowdreamtech/frpc:debian
1 2 docker run --restart=always --network host -d -v /etc/frp/frps.toml:/etc/frp/frps.toml --name frps snowdreamtech/frps:bookworm docker run --restart=always --network host -d -v /etc/frp/frpc.toml:/etc/frp/frpc.toml --name frpc snowdreamtech/frpc:bookworm
Quick reference
https://github.com/snowdreamtech/frp/issues
Where to join discussions:
https://github.com/snowdreamtech/frp/discussions
snowdream sn0wdr1am@qq.com
Alpine (linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/riscv64,linux/s390x)
Debian (linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64,linux/mips64le,linux/ppc64le,linux/s390x)
Alpine:
1 2 3 4 5 6 7 8 9 10 - latest - 0.62-alpine3.21 - 0.63.0-alpine3.21 - 0.62-alpine - 0.63.0-alpine - alpine3.21 - alpine - 0.62 - 0.63.0
Debian:
1 2 3 4 5 6 - bookworm - debian - 0.62-bookworm - 0.63.0-bookworm - 0.62-debian - 0.63.0-debian
概览 一些概述,便于您快速的了解 frp。
frp 是什么? frp 是一款高性能的反向代理应用,专注于内网穿透。它支持多种协议,包括 TCP、UDP、HTTP、HTTPS 等,并且具备 P2P 通信功能。使用 frp,您可以安全、便捷地将内网服务暴露到公网,通过拥有公网 IP 的节点进行中转。
为什么选择 frp? 通过在具有公网 IP 的节点上部署 frp 服务端,您可以轻松地将内网服务穿透到公网,并享受以下专业特性:
多种协议支持:客户端服务端通信支持 TCP、QUIC、KCP 和 Websocket 等多种协议。
TCP 连接流式复用:在单个连接上承载多个请求,减少连接建立时间,降低请求延迟。
代理组间的负载均衡。
端口复用:多个服务可以通过同一个服务端端口暴露。
P2P 通信:流量不必经过服务器中转,充分利用带宽资源。
客户端插件:提供多个原生支持的客户端插件,如静态文件查看、HTTPS/HTTP 协议转换、HTTP、SOCKS5 代理等,以便满足各种需求。
服务端插件系统:高度可扩展的服务端插件系统,便于根据自身需求进行功能扩展。
用户友好的 UI 页面:提供服务端和客户端的用户界面,使配置和监控变得更加方便。
安装 关于如何安装 frp 的说明。
frp 采用 Go 语言编写,支持跨平台,只需下载适用于您平台的二进制文件即可执行,无需额外依赖。
系统需求 由于采用 Go 语言编写,因此系统需求与最新的 Go 语言对系统和平台的要求一致,具体请参考 Golang System requirements 。
下载 您可以从 GitHub 的 Release 页面中下载最新版本的客户端和服务器二进制文件。所有文件都打包在一个压缩包中,还包含了一份完整的配置参数说明。
部署
解压下载的压缩包。
将 frpc
复制到内网服务所在的机器上。
将 frps
复制到拥有公网 IP 地址的机器上,并将它们放在任意目录。
开始使用!
编写配置文件,目前支持的文件格式包括 TOML/YAML/JSON,旧的 INI 格式仍然支持,但已经不再推荐。
使用以下命令启动服务器:./frps -c ./frps.toml
。
使用以下命令启动客户端:./frpc -c ./frpc.toml
。
如果需要在后台长期运行,建议结合其他工具,如 systemd 和 supervisor
。
如果您是 Windows 用户,需要在命令提示符中执行相同的命令。
有关如何编写配置文件,请参考 示例 部分中的内容。
完整的配置项说明,请参考 Reference 中的内容。
使用 systemd 此示例演示如何在 Linux 系统下使用 systemd 来管理 frps 服务,包括启动、停止、配置后台运行和设置开机自启动。
在 Linux 系统下,使用 systemd
可以方便地控制 frps 服务端的启动、停止、配置后台运行以及开机自启动。
以下是具体的操作步骤:
安装 systemd
如果您的 Linux 服务器上尚未安装 systemd,可以使用包管理器如 yum
(适用于 CentOS/RHEL)或 apt
(适用于 Debian/Ubuntu)来安装它:
1 2 3 4 5 6 # 使用 yum 安装 systemd(CentOS/RHEL) yum install systemd # 使用 apt 安装 systemd(Debian/Ubuntu) apt install systemd
创建 frps.service 文件
使用文本编辑器 (如 vim) 在 /etc/systemd/system
目录下创建一个 frps.service
文件,用于配置 frps 服务。
1 2 $ sudo vim /etc/systemd/system/frps.service
写入内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [Unit] # 服务名称,可自定义 Description = frp server After = network.target syslog.target Wants = network.target [Service] Type = simple # 启动frps的命令,需修改为您的frps的安装路径 ExecStart = /path/to/frps -c /path/to/frps.toml [Install] WantedBy = multi-user.target
使用 systemd 命令管理 frps 服务
1 2 3 4 5 6 7 8 9 # 启动frp sudo systemctl start frps # 停止frp sudo systemctl stop frps # 重启frp sudo systemctl restart frps # 查看frp状态 sudo systemctl status frps
设置 frps 开机自启动
1 2 sudo systemctl enable frps
通过遵循上述步骤,您可以轻松地使用 systemd 来管理 frps 服务,实现启动、停止、自动运行和开机自启动。确保替换路径和配置文件名称以匹配您的实际安装。
概念 了解以下概念有助于更好地理解和使用 frp。
工作原理 frp 主要由两个组件组成:客户端(frpc) 和 服务端(frps)。通常情况下,服务端部署在具有公网 IP 地址的机器上,而客户端部署在需要穿透的内网服务所在的机器上。
由于内网服务缺乏公网 IP 地址,因此无法直接被非局域网内的用户访问。用户通过访问服务端的 frps,frp 负责根据请求的端口或其他信息将请求路由到相应的内网机器,从而实现通信。
代理 在 frp 中,一个代理对应一个需要公开访问的内网服务。一个客户端可以同时配置多个代理,以满足不同的需求。
代理类型 frp 支持多种代理类型,以适应不同的使用场景。以下是一些常见的代理类型:
TCP :提供纯粹的 TCP 端口映射,使服务端能够根据不同的端口将请求路由到不同的内网服务。
UDP :提供纯粹的 UDP 端口映射,与 TCP 代理类似,但用于 UDP 流量。
HTTP :专为 HTTP 应用设计,支持修改 Host Header 和增加鉴权等额外功能。
HTTPS :类似于 HTTP 代理,但专门用于处理 HTTPS 流量。
STCP :提供安全的 TCP 内网代理,要求在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。
SUDP :提供安全的 UDP 内网代理,与 STCP 类似,需要在被访问者和访问者的机器上都部署 frpc,不需要在服务端暴露端口。
XTCP :点对点内网穿透代理,与 STCP 类似,但流量不需要经过服务器中转。
TCPMUX :支持服务端 TCP 端口的多路复用,允许通过同一端口访问不同的内网服务。
每种代理类型适用于不同的使用情境,您可以根据需求选择合适的代理类型来配置 frp。
通过 SSH 访问内网机器 通过简单配置 TCP 类型的代理,使用户能够访问内网服务器。
步骤
在具有公网 IP 的机器上部署 frps
部署 frps 并编辑 frps.toml 文件。以下是简化的配置,其中设置了 frp 服务器用于接收客户端连接的端口:
在需要被访问的内网机器上部署 frpc
部署 frpc 并编辑 frpc.toml 文件,假设 frps 所在服务器的公网 IP 地址为 x.x.x.x。以下是示例配置:
1 2 3 4 5 6 7 8 9 10 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 6000
localIP
和 localPort
配置为需要从公网访问的内网服务的地址和端口。
remotePort
表示在 frp 服务端监听的端口,访问此端口的流量将被转发到本地服务的相应端口。
启动 frps 和 frpc
通过 SSH 访问内网机器
使用以下命令通过 SSH 访问内网机器,假设用户名为 test:
1 2 ssh -o Port=6000 test@x.x.x.x
frp 将请求发送到 x.x.x.x:6000
的流量转发到内网机器的 22 端口。
多个 SSH 服务复用同一端口 通过使用 tcpmux 类型的代理,您可以实现多个 SSH 服务通过同一端口进行暴露。这种方法还适用于任何支持 HTTP Connect 代理连接方式的客户端,以实现端口的复用。
步骤
在具有公网 IP 的机器上部署 frps
修改 frps.toml 文件以包含以下内容(这里使用了最简化的配置):
1 2 3 bindPort = 7000 tcpmuxHTTPConnectPort = 5002
在内网机器 A 上部署 frpc
创建 frpc 配置文件,例如 frpc.toml,然后将以下内容添加到配置文件中:
1 2 3 4 5 6 7 8 9 10 11 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "ssh1" type = "tcpmux" multiplexer = "httpconnect" customDomains = ["machine-a.example.com"] localIP = "127.0.0.1" localPort = 22
在内网机器 B 上部署另一个 frpc
创建 frpc 配置文件,例如 frpc.toml,然后将以下内容添加到配置文件中:
1 2 3 4 5 6 7 8 9 10 11 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "ssh2" type = "tcpmux" multiplexer = "httpconnect" customDomains = ["machine-b.example.com"] localIP = "127.0.0.1" localPort = 22
通过 SSH ProxyCommand 访问内网机器 A
使用 SSH ProxyCommand 访问内网机器 A,假设用户名为 test。使用以下命令:
1 2 ssh -o 'proxycommand socat - PROXY:x.x.x.x:%h:%p,proxyport=5002' test@machine-a.example.com
要访问内网机器 B,只需更改域名,假设用户名仍然为 test:
1 2 ssh -o 'proxycommand socat - PROXY:x.x.x.x:%h:%p,proxyport=5002' test@machine-b.example.com
通过按照以上步骤进行配置,您可以实现多个 SSH 服务复用同一端口,以便在具有公网 IP 的机器上进行访问。
通过自定义域名访问内网的 Web 服务 通过简单配置 HTTP 类型的代理,您可以让用户通过自定义域名访问内网的 Web 服务。
HTTP 类型的代理非常适合将内网的 Web 服务通过自定义域名提供给外部用户。相比于 TCP 类型代理,HTTP 代理不仅可以复用端口,还提供了基于 HTTP 协议的许多功能。
HTTPS 与此类似,但是需要注意,frp 的 https 代理需要本地服务是 HTTPS 服务,frps 端不会做 TLS 终止。也可以结合 https2http 插件来实现将本地的 HTTP 服务以 HTTPS 协议暴露出去。
步骤
配置 frps.toml
在 frps.toml 文件中添加以下内容,以指定 HTTP 请求的监听端口为 8080:
1 2 3 bindPort = 7000 vhostHTTPPort = 8080
如果需要配置 HTTPS 代理,还需要设置 vhostHTTPSPort
。
配置 frpc.toml
在 frpc.toml 文件中添加以下内容,确保设置了正确的服务器 IP 地址、本地 Web 服务监听端口和自定义域名:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "web" type = "http" localPort = 80 customDomains = ["www.yourdomain.com"] [[proxies]] name = "web2" type = "http" localPort = 8080 customDomains = ["www.yourdomain2.com"]
启动 frps 和 frpc
域名解析
将 www.yourdomain.com
和 www.yourdomain2.com
的域名 A 记录解析到服务器的 IP 地址 x.x.x.x
。如果服务器已经有对应的域名,您还可以将 CNAME 记录解析到原始域名。另外,通过修改 HTTP 请求的 Host 字段也可以实现相同的效果。
通过浏览器访问
使用浏览器访问 http://www.yourdomain.com:8080
即可访问内网机器上的 80 端口服务,访问 http://www.yourdomain2.com:8080
可以访问内网机器上的 8080 端口服务。
转发 DNS 查询请求 本示例演示如何通过简单配置 UDP 类型的代理来实现 DNS 查询请求的转发。
DNS 查询请求通常使用 UDP 协议,而 frp 支持对内网 UDP 服务的穿透,配置方式与 TCP 类似。
步骤
配置 frps.toml
在 frps.toml 文件中添加以下内容:
配置 frpc.toml
在 frpc.toml 文件中添加以下内容:
1 2 3 4 5 6 7 8 9 10 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "dns" type = "udp" localIP = "8.8.8.8" localPort = 53 remotePort = 6000
请注意,这里示例中反代了 Google 的 DNS 查询服务器的地址,仅用于测试 UDP 代理,并没有实际意义。
启动 frps 和 frpc
分别启动 frps 和 frpc。
测试 DNS 查询请求
使用以下命令通过 dig
工具测试 UDP 包转发是否成功,预期会返回 www.baidu.com
域名的解析结果:
1 dig @x.x.x.x -p 6000 www.baidu.com
转发 Unix 域套接字 通过配置 Unix 域套接字客户端插件,您可以使用 TCP 端口访问内网的 Unix 域套接字服务,例如 Docker Daemon。
步骤
配置 frps.toml
在 frps.toml 文件中添加以下内容:
配置 frpc.toml
在 frpc.toml 文件中添加以下内容,确保设置正确的 Unix 域套接字路径:
1 2 3 4 5 6 7 8 9 10 11 12 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "unix_domain_socket" type = "tcp" remotePort = 6000 [proxies.plugin] type = "unix_domain_socket" # Unix 域套接字路径 unixPath = "/var/run/docker.sock"
启动 frps 和 frpc
使用 curl 查看 Docker 版本信息
1 curl http://x.x.x.x:6000/version
对外提供简单的文件访问服务 通过配置 static_file
客户端插件,您可以将本地文件暴露在公网上,以供其他人访问。
通过使用 static_file
插件,您可以轻松地提供一个基于 HTTP 的文件访问服务,让其他人可以访问您指定的文件。
步骤
配置 frps.toml
在 frps.toml 文件中添加以下内容:
配置 frpc.toml
在 frpc.toml 文件中添加以下内容,确保设置合适的文件路径、用户名和密码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "test_static_file" type = "tcp" remotePort = 6000 [proxies.plugin] type = "static_file" # 本地文件目录,对外提供访问 localPath = "/tmp/file" # URL 中的前缀,将被去除,保留的内容即为要访问的文件路径 stripPrefix = "static" httpUser = "abc" httpPassword = "abc"
请根据实际情况修改 localPath
、stripPrefix
、httpUser
和 httpPassword
。
启动 frps 和 frpc
通过浏览器访问文件
使用浏览器访问 http://x.x.x.x:6000/static/
,以查看位于 /tmp/file
目录下的文件。系统会要求输入您设置的用户名和密码。
为本地 HTTP 服务启用 HTTPS 使用 https2http
插件将本地 HTTP 服务转换为 HTTPS 服务,以供外部访问。
步骤
配置 frps.toml
1 2 3 bindPort = 7000 vhostHTTPSPort = 443
配置 frpc.toml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "test_htts2http" type = "https" customDomains = ["test.yourdomain.com"] [proxies.plugin] type = "https2http" localAddr = "127.0.0.1:80" # HTTPS 证书相关的配置 crtPath = "./server.crt" keyPath = "./server.key" hostHeaderRewrite = "127.0.0.1" requestHeaders.set.x-from-where = "frp"
请注意,您需要根据您的域名和证书路径自行更改上述配置。
启动 frps 和 frpc
访问 HTTPS 服务
打开您的 Web 浏览器,访问 https://test.yourdomain.com
。
通过按照以上步骤进行配置,您将能够为本地 HTTP 服务启用 HTTPS,以实现安全的外部访问。
安全地暴露内网服务 通过创建一个只有授权用户能够访问的 SSH 服务代理,实现内网服务的安全暴露。
某些内网服务,如果直接暴露在公网上,可能存在安全风险。使用 stcp(secret tcp)
类型的代理可以让您安全地将内网服务暴露给经过授权的用户,这需要访问者也部署 frpc 客户端。
步骤
配置 frps.toml
在 frps.toml 文件中添加以下内容:
部署 frpc 客户端并配置
在需要将内网服务暴露到公网的机器上部署 frpc,并创建如下配置:
1 2 3 4 5 6 7 8 9 10 11 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "secret_ssh" type = "stcp" # 只有与此处设置的 secretKey 一致的用户才能访问此服务 secretKey = "abcdefg" localIP = "127.0.0.1" localPort = 22
在访问者机器上部署并配置 frpc
在想要访问内网服务的机器上也部署 frpc,并创建如下配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 serverAddr = "x.x.x.x" serverPort = 7000 [[visitors]] name = "secret_ssh_visitor" type = "stcp" # 要访问的 stcp 代理的名字 serverName = "secret_ssh" secretKey = "abcdefg" # 绑定本地端口以访问 SSH 服务 bindAddr = "127.0.0.1" bindPort = 6000
通过 SSH 访问内网机器
使用以下命令通过 SSH 访问内网机器,假设用户名为 test:
1 ssh -o Port=6000 test@127.0.0.1
点对点内网穿透 这个示例将演示如何通过点对点 (P2P) 连接来访问内网服务,流量不会通过服务器中转。
frp 提供了一种新的代理类型 xtcp
,用于在需要传输大量数据且不希望流量经过服务器的情况下实现内网穿透。
与 stcp
类似,使用 xtcp
需要在两端都部署 frpc 以建立直接连接。
需要注意的是,xtcp
并不适用于所有类型的 NAT 设备,如果穿透失败,可以尝试使用 stcp
代理。
步骤
配置需要暴露到外网的机器上的 frpc.toml 文件
在 frpc.toml 文件中添加以下内容,确保设置了正确的服务器地址和端口以及共享密钥 (secretKey
),以及本地服务的 IP 地址和端口:
1 2 3 4 5 6 7 8 9 10 11 12 13 serverAddr = "x.x.x.x" serverPort = 7000 # 如果默认的 STUN 服务器不可用,可以配置一个新的 STUN 服务器 # natHoleStunServer = "xxx" [[proxies]] name = "p2p_ssh" type = "xtcp" # 只有共享密钥 (secretKey) 与服务器端一致的用户才能访问该服务 secretKey = "abcdefg" localIP = "127.0.0.1" localPort = 22
在想要访问内网服务的机器上部署 frpc
在 frpc.toml 文件中添加以下内容,确保设置了正确的服务器地址和端口,共享密钥 (secretKey
) 以及要访问的 P2P 代理的名称:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 serverAddr = "x.x.x.x" serverPort = 7000 # 如果默认的 STUN 服务器不可用,可以配置一个新的 STUN 服务器 # natHoleStunServer = "xxx" [[visitors]] name = "p2p_ssh_visitor" type = "xtcp" # 要访问的 P2P 代理的名称 serverName = "p2p_ssh" secretKey = "abcdefg" # 绑定本地端口以访问 SSH 服务 bindAddr = "127.0.0.1" bindPort = 6000 # 如果需要自动保持隧道打开,将其设置为 true # keepTunnelOpen = false
通过 SSH 访问内网机器
使用 SSH 命令访问内网机器,假设用户名为 test
:
1 ssh -oPort=6000 test@127.0.0.1
虚拟网络 (VirtualNet) 使用 virtual_net
插件创建虚拟网络连接,实现客户端之间的 IP 层通信。
注意 :VirtualNet 是一个 Alpha 阶段的特性,目前不稳定,其配置方式和功能可能会在后续版本中随时调整变更。请勿在生产环境中使用此功能,仅建议用于测试和评估目的。
概述 虚拟网络(VirtualNet)功能是 frp v0.62.0 中引入的 Alpha 特性,它允许 frp 通过 TUN 接口创建和管理客户端与访问者之间的虚拟网络连接,实现设备间的完整网络连通性。
本示例将展示如何配置和使用 VirtualNet 功能。更多详细信息和工作原理,请参考 虚拟网络 (VirtualNet) 特性文档。
启用 VirtualNet 首先,由于 VirtualNet 目前是一个 Alpha 特性,您需要在配置中通过特性门控来启用它:
1 2 3 # frpc.toml featureGates = { VirtualNet = true }
示例配置 以下示例展示如何在两台机器之间建立虚拟网络连接:
服务端配置 (机器 A)
在 frpc.toml 中配置虚拟网络地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # frpc.toml (服务端) serverAddr = "x.x.x.x" serverPort = 7000 featureGates = { VirtualNet = true } # 配置虚拟网络接口 virtualNet.address = "100.86.0.1/24" [[proxies]] name = "vnet-server" type = "stcp" secretKey = "your-secret-key" [proxies.plugin] type = "virtual_net"
启动 frpc
注意:创建 TUN 接口需要 root 权限
客户端配置 (机器 B)
在 frpc.toml 中配置访问者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # frpc.toml (客户端) serverAddr = "x.x.x.x" serverPort = 7000 featureGates = { VirtualNet = true } # 配置虚拟网络接口 virtualNet.address = "100.86.0.2/24" [[visitors]] name = "vnet-visitor" type = "stcp" serverName = "vnet-server" secretKey = "your-secret-key" bindPort = -1 [visitors.plugin] type = "virtual_net" destinationIP = "100.86.0.1"
启动 frpc
测试连接 成功配置后,您可以从机器 B 通过虚拟 IP 地址访问机器 A:
1 2 3 # 在机器 B 上执行 ping 100.86.0.1
如果连接正常,您将看到来自 100.86.0.1 的响应。
限制和要求
Alpha 阶段特性 :VirtualNet 是实验性功能,配置和 API 可能在未来版本中变化,不建议在生产环境中使用
权限要求 :创建 TUN 接口需要提升的权限(root/管理员)
平台支持 :目前仅支持 Linux 和 macOS
默认状态 :作为 Alpha 特性,VirtualNet 默认是禁用的
配置文件 从 v0.52.0 版本开始,frp 开始支持 TOML、YAML 和 JSON 作为配置文件格式。
请注意,INI 已被弃用,并将在未来的发布中移除。新功能只能在TOML、YAML 或 JSON 中使用。希望使用这些新功能的用户应相应地切换其配置格式。
格式 可使用 TOML/YAML/JSON 任何一个您喜欢的格式来编写配置文件,frp 会自动适配进行解析。
文档示例主要通过 TOML 编写,如下的示例配置将本地 SSH 服务穿透到公网。
frps 配置:
frpc 配置:
1 2 3 4 5 6 7 8 9 10 serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 6000
同一个客户端可以配置多个代理,但是 name 必须确保唯一。
不同的客户端之间,可以通过配置不同的 user 来确保代理名称唯一。
模版渲染 配置文件支持使用环境变量进行模版渲染,模版格式采用 Go 的标准格式。
示例配置如下:
1 2 3 4 5 6 7 8 9 10 serverAddr = "{{ .Envs.FRP_SERVER_ADDR }}" serverPort = 7000 [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = {{ .Envs.FRP_SSH_REMOTE_PORT }}
启动 frpc 程序:
1 2 3 4 export FRP_SERVER_ADDR="x.x.x.x" export FRP_SSH_REMOTE_PORT="6000" ./frpc -c ./frpc.toml
frpc 会自动使用环境变量渲染配置文件模版,所有环境变量需要以 .Envs
为前缀。
YAML 锚点和引用 frp 支持 YAML 合并功能(锚点和引用,包括点前缀字段),在严格配置模式下无需使用 --strict-config=false
参数即可正常工作。
可以使用以点开头的字段作为锚点定义,类似于 Docker Compose 的 x-
前缀:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # frpc.yaml .common: &common type: "stcp" secretKey: "{{.Envs.FRPC_SECRET_KEY}}" localIP: "127.0.0.1" serverAddr: "x.x.x.x" serverPort: 7000 proxies: - name: "ssh" localPort: 22 <<: *common - name: "web" localPort: 80 <<: *common
配置校验 通过执行 frpc verify -c ./frpc.toml
或 frps verify -c ./frps.toml
可以对配置文件中的参数进行预先校验。
1 2 frpc: the configuration file ./frpc.toml syntax is ok
如果出现此结果,则说明新的配置文件没有错误,否则会输出具体的错误信息。
严格模式校验 默认情况下,frp 使用严格模式进行配置校验。如果需要禁用严格校验,可以使用 --strict-config=false
参数:
1 2 frpc verify -c ./frpc.yaml --strict-config=false
配置拆分 通过 includes
参数可以在主配置中包含其他配置文件,从而实现将代理配置拆分到多个文件中管理。
1 2 3 4 5 # frpc.toml serverAddr = "x.x.x.x" serverPort = 7000 includes = ["./confd/*.toml"]
1 2 3 4 5 6 7 8 # ./confd/test.toml [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 6000
上述配置在 frpc.toml 中通过 includes 额外包含了 ./confd
目录下所有的 toml 文件的代理配置内容,效果等价于将这两个文件合并成一个文件。
需要注意的是 includes 指定的文件中只能包含代理配置,通用参数的配置只能放在主配置文件中。
完整配置参数 由于 frp 目前支持的功能和配置项较多,未在文档中列出的功能参数可以在 参考 中查看。
监控 目前,frps 服务端支持两种监控系统:内存监控和 Prometheus 监控。
内存监控 内存中存储的监控数据主要用于 Dashboard 展示。当在 frps 配置中开启 Dashboard 功能后,内存监控默认启用。
请注意,内存中的监控数据在每次重启进程后会被清空,或者保留 7 天。监控数据可以通过 Dashboard 的地址发送 HTTP 请求获取,但目前此 API 尚不规范,不建议直接使用。
Prometheus 监控 由于设计问题,Prometheus 对外提供的查询接口与 Dashboard 的地址重用,因此要使用 Prometheus 监控,必须首先启用 Dashboard。
在 frps.ini 中启用 Dashboard 并设置 enablePrometheus = true
,然后你可以通过访问 http://{dashboard_addr}/metrics
来获取 Prometheus 的监控数据。
最后修改 August 11, 2025: docs: add tokenSource documentation for
身份认证 目前 frpc 和 frps 之间支持两种身份验证方式,token
和 oidc
,默认为 token
。这些认证方式允许您验证客户端与服务端之间的通信,并确保只有授权用户能够建立连接。
Token Token 身份认证是一种简单的身份认证方式,只需要在 frp 的客户端 frpc 和服务端 frps 配置文件中配置相同的 token 即可。
配置示例 1 2 3 4 # frps.toml bindPort = 7000 auth.token = "abc"
1 2 3 # frpc.toml auth.token = "abc"
从文件加载 Token Added in v0.64.0
frp 支持使用 tokenSource
从文件中加载认证 token,而不是在配置文件中硬编码。这个功能可以避免在配置文件中直接暴露敏感信息。
配置方式 tokenSource 与 token 字段互斥,只能选择其中一种方式配置。
服务端配置示例:
1 2 3 4 5 # frps.toml bindPort = 7000 auth.tokenSource.type = "file" auth.tokenSource.file.path = "/etc/frp/server_token"
客户端配置示例:
1 2 3 4 # frpc.toml auth.tokenSource.type = "file" auth.tokenSource.file.path = "/etc/frp/client_token"
注意事项
token 文件应该设置适当的权限(如 600),确保只有运行 frp 的用户可以读取
文件中的 token 会自动去除首尾空白字符
tokenSource 在配置加载时解析,不支持运行时动态重新加载
目前仅支持 file
类型的 tokenSource
OIDC (OpenID Connect) 身份认证 OIDC 身份认证是一种基于开放标准的身份认证方式,它通过使用 OIDC 提供者进行身份验证。
验证流程参考 Client Credentials Grant 。
配置示例 1 2 3 4 5 # frps.toml auth.method = "oidc" auth.oidc.issuer = "https://example-oidc-issuer.com/" auth.oidc.audience = "https://oidc-audience.com/.default"
1 2 3 4 5 6 # frpc.toml auth.method = "oidc" auth.oidc.clientID = "98692467-37de-409a-9fac-bb2585826f18" auth.oidc.clientSecret = "oidc_secret" auth.oidc.audience = "https://oidc-audience.com/.default" auth.oidc.tokenEndpointURL = "https://example-oidc-endpoint.com/oauth2/v2.0/token"
Web 界面 目前 frpc 和 frps 分别内置了相应的 Web 界面方便用户使用。
服务端 Dashboard 服务端 Dashboard 使用户可以通过浏览器查看 frp 的状态以及代理统计信息。
注:Dashboard 尚未针对大量的 proxy 数据展示做优化,如果出现 Dashboard 访问较慢的情况,请不要启用此功能。
需要在 frps.toml 中指定 dashboard 服务使用的端口,即可开启此功能:
1 2 3 4 5 6 7 # 默认为 127.0.0.1,如果需要公网访问,需要修改为 0.0.0.0。 webServer.addr = "0.0.0.0" webServer.port = 7500 # dashboard 用户名密码,可选,默认为空 webServer.user = "admin" webServer.password = "admin"
打开浏览器通过 http://[server addr]:7500
访问 Dashboard 界面,输入用户名密码 admin
。
你也可以通过配置 TLS 证书来启用 HTTPS 接口:
1 2 3 webServer.tls.certFile = "server.crt" webServer.tls.keyFile = "server.key"
客户端管理界面 frpc 内置的 Admin UI 可以帮助用户通过浏览器来查询和管理客户端的 proxy 状态和配置。
需要在 frpc.toml 中指定 admin 服务使用的端口,即可开启此功能:
1 2 3 4 5 6 # frpc.toml webServer.addr = "127.0.0.1" webServer.port = 7400 webServer.user = "admin" webServer.password = "admin"
打开浏览器通过 http://127.0.0.1:7400
访问 Admin UI。
如果想要在外网环境访问 Admin UI,可以将 7400 端口通过 frp 映射出去即可,但需要重视安全风险。
1 2 3 4 5 6 # frpc.toml [[proxies]] name = "admin_ui" type = "tcp" localPort = 7400 remotePort = 7400
通信安全及优化 加密与压缩 注: 当 frpc 和 frps 之间启用了 TLS 之后,流量会被全局加密,不再需要配置单个代理上的加密,新版本中已经默认启用。
每一个代理都可以选择是否启用加密和压缩的功能。
加密算法采用 aes-128-cfb,压缩算法采用 snappy。
在每一个代理的配置中使用如下参数指定:
1 2 3 4 5 6 7 8 [[proxies]] name = "ssh" type = "tcp" localPort = 22 remotePort = 6000 transport.useEncryption = true transport.useCompression = true
通过设置 transport.useEncryption = true
,将 frpc 与 frps 之间的通信内容加密传输,将会有效防止传输内容被截取。
如果传输的报文长度较长,通过设置 transport.useCompression = true
对传输内容进行压缩,可以有效减小 frpc 与 frps 之间的网络流量,加快流量转发速度,但是会额外消耗一些 CPU 资源。
TCP 多路复用 客户端和服务器端之间的连接支持多路复用,不再需要为每一个用户请求创建一个连接,使连接建立的延迟降低,并且避免了大量文件描述符的占用,使 frp 可以承载更高的并发数。
该功能默认启用,如需关闭,可以在 frps.toml 和 frpc.toml 中配置,该配置项在服务端和客户端必须一致:
1 2 3 # frps.toml 和 frpc.toml 中 transport.tcpMux = false
连接池 默认情况下,当用户请求建立连接后,frps 才会请求 frpc 主动与后端服务建立一个连接。当为指定的代理启用连接池后,frp 会预先和后端服务建立起指定数量的连接,每次接收到用户请求后,会从连接池中取出一个连接和用户连接关联起来,避免了等待与后端服务建立连接以及 frpc 和 frps 之间传递控制信息的时间。
这一功能适合有大量短连接请求时开启。
注: 当 TCP 多路复用启用后,连接池的提升有限,一般场景下无需关心。
首先可以在 frps.toml 中设置每个代理可以创建的连接池上限,避免大量资源占用,客户端设置超过此配置后会被调整到当前值:
1 2 3 # frps.toml transport.maxPoolCount = 5
在 frpc.toml 中为客户端启用连接池,指定预创建连接的数量:
1 2 3 # frpc.toml transport.poolCount = 1
支持 KCP 协议 底层通信协议支持选择 KCP 协议,相比于 TCP,在弱网环境下传输效率提升明显,但是会有一些额外的流量消耗。
开启 KCP 协议支持:
在 frps.toml 中启用 KCP 协议支持,指定一个 UDP 端口用于接收客户端请求:
1 2 3 4 5 # frps.toml bindPort = 7000 # kcp 绑定的是 UDP 端口,可以和 bindPort 一样 kcpBindPort = 7000
在 frpc.toml 指定需要使用的协议类型,其他代理配置不需要变更:
1 2 3 4 5 6 # frpc.toml serverAddr = "x.x.x.x" # serverPort 指定为 frps 的 kcpBindPort serverPort = 7000 transport.protocol = "kcp"
支持 QUIC 协议 底层通信协议支持选择 QUIC 协议,底层采用 UDP 传输,解决了 TCP 上的一些问题,传输效率更高,连接延迟低。
开启 QUIC 协议支持:
在 frps.toml 中启用 QUIC 协议支持,指定一个 UDP 端口用于接收客户端请求:
1 2 3 4 5 # frps.toml bindPort = 7000 # QUIC 绑定的是 UDP 端口,可以和 bindPort 一样 quicBindPort = 7000
在 frpc.toml 指定需要使用的协议类型,其他代理配置不需要变更:
1 2 3 4 5 # frpc.toml serverAddr = "x.x.x.x" # serverPort 指定为 frps 的 quicBindPort serverPort = 7000 transport.protocol = "quic"
自定义 TLS 协议加密 transport.useEncryption
和 STCP
等功能能有效防止流量内容在通信过程中被盗取,但是无法判断对方的身份是否合法,存在被中间人攻击的风险。为此 frp 支持 frpc 和 frps 之间的流量通过 TLS 协议加密,并且支持客户端或服务端单向验证,双向验证等功能。
当 frps.toml
中 transport.tls.force = true
时,表示 server 端只接受 TLS 连接的客户端,这也是 frps 验证 frpc 身份的前提条件。如果 frps.toml
中 transport.tls.trustedCaFile
内容是有效的话,那么默认就会开启 transport.tls.force = true
。
注意:启用此功能后除 xtcp ,可以不用再设置 use_encryption 重复加密
TLS 默认开启方式 从 v0.50.0 开始,transport.tls.enable
的默认值将会为 true,默认开启 TLS 协议加密。
如果 frps 端没有配置证书,则会使用随机生成的证书来加密流量。
默认情况下,frpc 开启 TLS 加密功能,但是不校验 frps 的证书。
frpc 单向校验 frps 身份 1 2 3 4 5 6 7 # frpc.toml transport.tls.trustedCaFile = "/to/ca/path/ca.crt" # frps.toml transport.tls.certFile = "/to/cert/path/server.crt" transport.tls.keyFile = "/to/key/path/server.key"
frpc 需要额外加载 ca 证书,frps 需要额外指定 TLS 配置。frpc 通过 ca 证书单向验证 frps 的身份。这就要求 frps 的 server.crt
对 frpc 的 ca 是合法的。
合法: 如果证书是 ca 签发的,或者证书是在 ca 的信任链中,那即认为: 该证书对 ca 而言是合法的。
frps 单向验证 frpc 的身份 1 2 3 4 5 6 7 # frpc.toml transport.tls.certFile = "/to/cert/path/client.crt" transport.tls.keyFile = "/to/key/path/client.key" # frps.toml transport.tls.trustedCaFile = "/to/ca/path/ca.crt"
frpc 需要额外加载 TLS 配置,frps 需要额外加载 ca 证书。frps 通过 ca 证书单向验证 frpc 的身份。这就要求 frpc 的 client.crt
对 frps 的 ca 是合法的。
双向验证 1 2 3 4 5 6 7 8 9 10 # frpc.toml transport.tls.certFile = "/to/cert/path/client.crt" transport.tls.keyFile = "/to/key/path/client.key" transport.tls.trustedCaFile = "/to/ca/path/ca.crt" # frps.toml transport.tls.certFile = "/to/cert/path/server.crt" transport.tls.keyFile = "/to/key/path/server.key" transport.tls.trustedCaFile = "/to/ca/path/ca.crt"
双向验证即 frpc 和 frps 通过本地 ca 证书去验证对方的身份。理论上 frpc 和 frps 的 ca 证书可以不同,只要能验证对方身份即可。
OpenSSL 生成证书示例 x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
如果出现上述报错,是因为 go 1.15 版本开始废弃 CommonName ,因此推荐使用 SAN 证书。
下面简单示例如何用 openssl 生成 ca 和双方 SAN 证书。
准备默认 OpenSSL 配置文件于当前目录。此配置文件在 linux 系统下通常位于 /etc/pki/tls/openssl.cnf
,在 mac 系统下通常位于 /System/Library/OpenSSL/openssl.cnf
。
如果存在,则直接拷贝到当前目录,例如 cp /etc/pki/tls/openssl.cnf ./my-openssl.cnf
。如果不存在可以使用下面的命令来创建。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 cat > my-openssl.cnf << EOF [ ca ] default_ca = CA_default [ CA_default ] x509_extensions = usr_cert [ req ] default_bits = 2048 default_md = sha256 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca string_mask = utf8only [ req_distinguished_name ] [ req_attributes ] [ usr_cert ] basicConstraints = CA:FALSE nsComment = "OpenSSL Generated Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer [ v3_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = CA:true EOF
生成默认 ca:
1 2 3 openssl genrsa -out ca.key 2048 openssl req -x509 -new -nodes -key ca.key -subj "/CN=example.ca.com" -days 5000 -out ca.crt
生成 frps 证书:
1 2 3 4 5 6 7 8 9 10 11 12 13 openssl genrsa -out server.key 2048 openssl req -new -sha256 -key server.key \ -subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=server.com" \ -reqexts SAN \ -config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.server.com")) \ -out server.csr openssl x509 -req -days 365 -sha256 \ -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -extfile <(printf "subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:example.server.com") \ -out server.crt
生成 frpc 的证书:
1 2 3 4 5 6 7 8 9 10 11 12 openssl genrsa -out client.key 2048 openssl req -new -sha256 -key client.key \ -subj "/C=XX/ST=DEFAULT/L=DEFAULT/O=DEFAULT/CN=client.com" \ -reqexts SAN \ -config <(cat my-openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:client.com,DNS:example.client.com")) \ -out client.csr openssl x509 -req -days 365 -sha256 \ -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -extfile <(printf "subjectAltName=DNS:client.com,DNS:example.client.com") \ -out client.crt
在本例中,server.crt 和 client.crt 都是由默认 ca 签发的,因此他们对默认 ca 是合法的。
负载均衡与健康检查 负载均衡 你可以将多个相同类型的代理加入到同一个 group
中,以实现负载均衡的能力。
目前支持的代理类型包括:tcp
, http
, tcpmux
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # frpc.toml [[proxies]] name = "test1" type = "tcp" localPort = 8080 remotePort = 80 loadBalancer.group = "web" loadBalancer.groupKey = "123" [[proxies]] name = "test2" type = "tcp" localPort = 8081 remotePort = 80 loadBalancer.group = "web" loadBalancer.groupKey = "123"
当用户连接 frps 服务器的 80 端口时,frps 会将接收到的用户连接随机分发给其中一个存活的代理。这可以确保即使一台 frpc 机器挂掉,仍然有其他节点能够提供服务。
对于 tcp 类型代理,需要确保 groupKey
相同以进行权限验证,同时 remotePort
也需一致。
对于 http 类型代理,需要保证 groupKey
, customDomains
(自定义域名),subdomain
和 locations
相同。
健康检查 通过给代理配置健康检查参数,可以在要反向代理的服务出现故障时,将该服务从 frps 中摘除。结合负载均衡的功能,这可用于实现高可用架构,避免服务单点故障。
要启用健康检查功能,需要在每个代理的配置中添加 healthCheck.type = {type}
。
目前支持的类型有 tcp
和 http
。
对于 tcp
,只要能够建立连接,即认为服务正常。
对于 http
,会发送一个 HTTP 请求,服务需要返回状态码 2xx 才会被视为正常。
以下是 tcp
示例配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [[proxies]] name = "test1" type = "tcp" localPort = 22 remotePort = 6000 # 启用健康检查,类型为 tcp healthCheck.type = "tcp" # 建立连接超时时间为 3 秒 healthCheck.timeoutSeconds = 3 # 连续 3 次检查失败,此 proxy 会被摘除 healthCheck.maxFailed = 3 # 每隔 10 秒进行一次健康检查 healthCheck.intervalSeconds = 10
以下是 http 示例配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 [[proxies]] name = "web" type = "http" localIP = "127.0.0.1" localPort = 80 customDomains = ["test.yourdomain.com"] # 启用健康检查,类型为 http healthCheck.type = "http" # 健康检查发送 http 请求的 path,后端服务需要返回 2xx 的 http 状态码 healthCheck.path = "/status" healthCheck.timeoutSeconds = 3 healthCheck.maxFailed = 3 healthCheck.intervalSeconds = 10
获取用户真实 IP HTTP X-Forwarded-For 目前只有 http
类型的代理或者启用了 https2http
或 https2https
插件的代理支持这一功能。
可以通过 HTTP 请求 header 中的 X-Forwarded-For
来获取用户真实 IP,默认启用。
Proxy Protocol frp 支持通过 Proxy Protocol
协议来传递经过 frp 代理的请求的真实 IP。
Proxy Protocol
功能启用后,frpc 在和本地服务建立连接后,会先发送一段 Proxy Protocol
的协议内容给本地服务,本地服务通过解析这一内容可以获得访问用户的真实 IP。所以不仅仅是 HTTP 服务,任何的 TCP 服务,只要支持这一协议,都可以获得用户的真实 IP 地址。
UDP 代理类型也支持 Proxy Protocol 功能,能够保留真实客户端 IP 地址。
需要注意的是,在代理配置中如果要启用此功能,需要本地的服务能够支持 Proxy Protocol
这一协议,目前 nginx 和 haproxy 都能够很好的支持。
TCP/HTTPS 代理示例 这里以 HTTPS
类型为例:
1 2 3 4 5 6 7 8 9 10 # frpc.toml [[proxies]] name = "web" type = "https" localPort = 443 customDomains = ["test.yourdomain.com"] # 目前支持 v1 和 v2 两个版本的 proxy protocol 协议。 transport.proxyProtocolVersion = "v2"
只需要在代理配置中增加一行 transport.proxyProtocolVersion = "v2"
即可开启此功能。
本地的 HTTPS 服务可以通过在 nginx 的配置中启用 Proxy Protocol
的解析并将结果设置在 X-Real-IP
这个 Header 中就可以在自己的 Web 服务中通过 X-Real-IP
获取到用户的真实 IP。
UDP 代理示例 UDP 代理也支持 Proxy Protocol 功能:
1 2 3 4 5 6 7 8 9 10 11 # frpc.toml [[proxies]] name = "dns" type = "udp" localIP = "127.0.0.1" localPort = 53 remotePort = 6000 # 启用 UDP 代理的 Proxy Protocol 支持 transport.proxyProtocolVersion = "v2"
启用后,frps 和 frpc 会把源 IP 信息写入 Proxy Protocol 头部,后端 UDP 服务或日志系统可以准确识别访问者的真实 IP 地址,这对于安全审计和访问控制特别有用。
端口范围映射 Added in v0.56.0
我们可以利用 Go template 的 range 语法结合内置的 parseNumberRangePair
函数来实现端口范围映射。
下面的示例,应用运行后会创建 8 个代理,名称为 test-6000, test-6001 ... test-6007
,分别将远端的端口映射到本地。
1 2 3 4 5 6 7 {{- range $_, $v := parseNumberRangePair "6000-6006,6007" "6000-6006,6007" }} [[proxies]] name = "tcp-{{ $v.First }}" type = "tcp" localPort = {{ $v.First }} remotePort = {{ $v.Second }} {{- end }}
客户端 动态配置更新 当你需要修改 frpc 的代理配置时,你可以使用 frpc reload
命令来实现动态加载配置文件,通常在数秒内完成代理的更新。
要启用此功能,需要在 frpc 中启用 webServer,以提供 API 服务。配置如下:
1 2 3 webServer.addr = "127.0.0.1" webServer.port = 7400
然后执行以下命令来重载配置:
frpc reload -c ./frpc.toml
等待一段时间后,客户端将根据新的配置文件创建、更新或删除代理。需要注意的是,非代理相关的公共部分的参数除了 start 外目前无法被修改。
命令行查看代理状态 frpc 支持通过 frpc status -c ./frpc.toml
命令查看代理的状态信息,此功能需要在 frpc 中启用 webServer。
使用代理连接 frps 在只能通过代理访问外部网络的环境中,frpc 支持通过 HTTP 或 SOCKS5 代理与 frps 建立连接。
你可以通过设置系统环境变量 HTTP_PROXY
或在 frpc 的配置文件中设置 transport.proxyURL
参数来使用此功能。
仅在 transport.protocol = "tcp"
时生效。
1 2 3 4 serverAddr = "x.x.x.x" serverPort = 7000 transport.proxyURL = "http://user:pwd@192.168.1.128:8080"
将 transport.proxyURL
设置为 socks5://user:pwd@192.168.1.128:8080
也可以连接到 SOCKS5 代理。
服务端管理 端口白名单 为了防止端口被滥用,可以手动指定允许哪些端口被使用,在服务端配置中通过 allowPorts
来指定:
1 2 3 4 5 6 7 8 # frps.ini allowPorts = [ { start = 2000, end = 3000 }, { single = 3001 }, { single = 3003 }, { start = 4000, end = 50000 } ]
allowPorts
可以配置允许使用的某个指定端口或者是一个范围内的所有端口。
端口复用 目前 frps 中的 vhostHTTPPort
和 vhostHTTPSPort
支持配置成和 bindPort
为同一个端口,frps 会对连接的协议进行分析,之后进行不同的处理。
例如在某些限制较严格的网络环境中,可以将 bindPort
和 vhostHTTPSPort
都设置为 443。
需要注意的是,如果你想将 vhostHTTPSPort
和 bindPort
配置为相同的端口,需要首先将 transport.tls.disableCustomTLSFirstByte
设置为false。
限速 代理限速 目前支持在客户端的代理配置中设置代理级别的限速,限制单个 proxy 可以占用的带宽。
1 2 3 4 5 6 7 8 # frpc.toml [[proxies]] name = "ssh" type = "tcp" localPort = 22 remotePort = 6000 transport.bandwidthLimit = "1MB"
在代理配置中增加 transport.bandwidthLimit
字段启用此功能,目前仅支持 MB
和 KB
单位。
限速能力默认在客户端实现,如果希望启用服务端限速,需要额外配置 transport.bandwidthLimitMode = "server"
。
客户端插件 默认情况下,frpc 仅会将请求转发到本地 TCP 或 UDP 端口,即通过 localIP
和 localPort
指定的本地服务地址。
通过启用客户端插件功能,可以在仅启动 frpc 的情况下内置一些简单的本地服务,从而实现通常需要额外启动其他服务才能实现的功能。
在每个代理的配置中,你可以通过 plugin
来配置要使用的插件和相关参数。启用客户端插件后,无需再配置 localIP
和 localPort
。
客户端插件可用于各种类型的代理,前提是插件本身支持的协议。例如,静态文件访问插件可以通过 TCP 或 HTTP 代理进行暴露。
以下是使用 http_proxy
插件的示例:
1 2 3 4 5 6 7 8 9 [[proxies]] name = "http_proxy" type = "tcp" remotePort = 6000 [proxies.plugin] type = "http_proxy" httpUser = "abc" httpPassword = "abc"
httpUser
和 httpPassword
即为 http_proxy
插件可选的配置参数。
其他插件和相关配置请参考 Reference 中的内容。
服务端插件 frp 服务端插件的作用是在不侵入自身代码的前提下,扩展 frp 服务端的能力。
frp 服务端插件会以单独进程的形式运行,并且监听在一个端口上,对外提供 RPC 接口,响应 frps 的请求。
frps 在执行某些操作前,会根据配置向服务端插件发送 RPC 请求,根据插件的响应来执行相应的操作。
RPC 请求 服务端插件接收到操作请求后,可以给出三种回应。
拒绝操作,需要返回拒绝操作的原因。
允许操作,不需要修改操作内容。
允许操作,对操作请求进行修改后,返回修改后的内容。
接口 接口路径可以在 frps 配置中为每个插件单独配置,这里以 /handler
为例。
Request
1 2 3 4 5 6 7 8 9 10 POST /handler?version=0.1.0&op=Login { "content": { ... // 具体的操作信息 } } 请求 Header X-Frp-Reqid: 用于追踪请求
Response
非 200 的返回都认为是请求异常。
拒绝执行操作
1 2 3 4 5 { "reject": true, "reject_reason": "invalid user" }
允许且内容不需要变动
1 2 3 4 5 { "reject": false, "unchange": true }
允许且需要替换操作内容
1 2 3 4 5 6 7 { "unchange": false, "content": { ... // 替换后的操作信息,格式必须和请求时的一致 } }
操作类型 目前插件支持管理的操作类型有 Login
、NewProxy
、CloseProxy
、Ping
、NewWorkConn
和 NewUserConn
。
Login 用户登录操作信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { "content": { "version": <string>, "hostname": <string>, "os": <string>, "arch": <string>, "user": <string>, "timestamp": <int64>, "privilege_key": <string>, "run_id": <string>, "pool_count": <int>, "metas": map<string>string, "client_address": <string> } }
NewProxy 创建代理的相关信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 { "content": { "user": { "user": <string>, "metas": map<string>string "run_id": <string> }, "proxy_name": <string>, "proxy_type": <string>, "use_encryption": <bool>, "use_compression": <bool>, "bandwidth_limit": <string>, "bandwidth_limit_mode": <string>, "group": <string>, "group_key": <string>, // tcp and udp only "remote_port": <int>, // http and https only "custom_domains": []<string>, "subdomain": <string>, "locations": []<string>, "http_user": <string>, "http_pwd": <string>, "host_header_rewrite": <string>, "headers": map<string>string, // stcp only "sk": <string>, // tcpmux only "multiplexer": <string> "metas": map<string>string } }
CloseProxy 代理关闭。(仅用于通知)
注意: 当单个 frpc 会注册大量 proxy 时,慎重使用此接口,可能会由于连接数超限而影响服务的可用性。
1 2 3 4 5 6 7 8 9 10 11 { "content": { "user": { "user": <string>, "metas": map<string>string "run_id": <string> }, "proxy_name": <string> } }
Ping 心跳相关信息
1 2 3 4 5 6 7 8 9 10 11 12 { "content": { "user": { "user": <string>, "metas": map<string>string "run_id": <string> }, "timestamp": <int64>, "privilege_key": <string> } }
NewWorkConn 创建工作连接
1 2 3 4 5 6 7 8 9 10 11 12 13 { "content": { "user": { "user": <string>, "metas": map<string>string "run_id": <string> }, "run_id": <string> "timestamp": <int64>, "privilege_key": <string> } }
NewUserConn 创建用户连接 (支持 tcp
、stcp
、https
和 tcpmux
协议)。
1 2 3 4 5 6 7 8 9 10 11 12 13 { "content": { "user": { "user": <string>, "metas": map<string>string "run_id": <string> }, "proxy_name": <string>, "proxy_type": <string>, "remote_addr": <string> } }
frps 中插件配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 bindPort = 7000 [[httpPlugins]] name = "user-manager" addr = "127.0.0.1:9000" path = "/handler" ops = ["Login"] [[httpPlugins]] name = "port-manager" addr = "127.0.0.1:9001" path = "/handler" ops = ["NewProxy"]
addr: 插件监听的网络地址,支持 HTTP 和 HTTPS,默认为 HTTP。
path: 插件监听的请求路径。
ops: 插件需要处理的操作列表,多个 op 以英文逗号分隔。
tls_verify: 如果是 HTTPS 协议,支持忽略 TLS 身份验证。
元数据 为了减少 frps 的代码修改,同时提高管理插件的扩展能力,在 frpc 的配置文件中引入自定义元数据的概念。元数据会在调用 RPC 请求时发送给插件。
有两种类型的元数据条目,全局条目和每个代理配置下的条目。全局元数据将在客户端登录时附加在 Login 请求中,并在其他 RPC 请求中附加在 user.metas
中。
每个代理配置下的元数据条目仅会在 NewProxy 操作中通过 metas 传递。
1 2 3 4 5 6 7 8 9 10 11 12 13 # frpc.toml serverAddr = "127.0.0.1" serverPort = 7000 user = "fake" metadatas.token = "fake" metadatas.version = "1.0.0" [[proxies]] name = "ssh" type = "tcp" localPort = 22 remotePort = 6000 metadatas.id = "123"
SSH Tunnel Gateway Added in v0.53.0
概念 SSH 支持反向代理能力 rfc 。
frp 支持在 frps 端监听一个 ssh 端口,通过走 ssh -R 协议来完成 TCP 协议代理,该模式下不需要依赖 frpc。
SSH 反向隧道代理和通过 frp 代理 SSH 端口是不同的 2 个概念。SSH 反向隧道代理本质上是在你不想使用 frpc 的时候,通过 ssh client 连接 frps 来完成基本的反向代理。
参数 1 2 3 4 5 6 7 # frps.toml sshTunnelGateway.bindPort = 0 sshTunnelGateway.privateKeyFile = "" sshTunnelGateway.autoGenPrivateKeyPath = "" sshTunnelGateway.authorizedKeysFile = ""
Field
Type
Description
Required
bindPort
int
frps 监听的 ssh server 端口。
YES
privateKeyFile
string
默认为空。ssh server 使用的私钥文件,为空frps会读取 autoGenPrivateKeyPath 路径下的私钥文件。可复用本地 /home/user/.ssh/id_rsa 文件或自定义路径。
No
autoGenPrivateKeyPath
string
默认为 ./.autogen_ssh_key。文件不存在或内容为空,frps会自动生成 RSA 私钥文件内容存入该文件。
No
authorizedKeysFile
string
默认为空。空不对ssh客户端进行鉴权认证。不空可实现ssh免密登录认证,可复用本地 /home/user/.ssh/authorized_keys 文件或自定义路径。
No
基本使用 服务端 frps 最简配置
1 2 sshTunnelGateway.bindPort = 2200
将上述配置放入 frps.toml, 运行 ./frps -c frps.toml
,此时会在 2200 的端口监听,接受 ssh 反向代理的请求。
注意:
使用最简配置,会在当前运行目录自动创建一个 .autogen_ssh_key
的私钥文件,frps 的 ssh server 会使用到该私钥文件,用来加解密数据。也可以复用本地已有的私钥文件,如 /home/user/.ssh/id_rsa
。
最简配置模式下运行的frps,通过 ssh 连接 frps 是不鉴权的,强烈建议 frps 配置 token,在 ssh 命令行指定 token。
客户端 ssh 命令格式为
1 2 ssh -R :80:{local_ip:port} v0@{frps address} -p {frps ssh listen port} {tcp|http|https|stcp|tcpmux} --remote_port {real remote port} --proxy_name {proxy_name} --token {frp token}
--proxy_name
非必填,为空会随机生成一个。
登录 frps 的用户名统一为 v0,目前没有任何含义,即 v0@{frps address}
。
server 端的 proxy 监听的端口由 --remote_port
决定。
{tcp|http|https|stcp|tcpmux}
支持的完整命令参数可通过 –help 获取。 如: ssh -R :80::8080 v0@127.0.0.1 -p 2200 http --help
token 非必填,为了安全强烈建议在frps配置上token。
TCP 代理 1 2 ssh -R :80:127.0.0.1:8080 v0@{frp address} -p 2200 tcp --proxy_name "test-tcp" --remote_port 9090
在 frps 启动一个 9090 的端口代理本地的 8080 服务。
1 2 3 4 5 6 7 frp (via SSH) (Ctrl+C to quit) User: ProxyName: test-tcp Type: tcp RemoteAddress: :9090
等同于:
1 2 frpc tcp --proxy_name "test-tcp" --local_ip 127.0.0.1 --local_port 8080 --remote_port 9090
更多参数可执行 –help 获取。
HTTP 代理 1 2 ssh -R :80:127.0.0.1:8080 v0@{frp address} -p 2200 http --proxy_name "test-http" --custom_domain test-http.frps.com
等同于
1 2 frpc http --proxy_name "test-http" --custom_domain test-http.frps.com
可以通过以下命令访问 http 服务:
curl 'http://test-http.frps.com'
更多参数可执行 --help
获取。
HTTPS/STCP/TCPMUX 代理 通过如下命令获取使用方式:
ssh -R :80:127.0.0.1:8080 v0@{frp address} -p 2200 {https|stcp|tcpmux} --help
高级使用 复用本机的 id_rsa 文件 1 2 3 4 5 # frps.toml sshTunnelGateway.bindPort = 2200 sshTunnelGateway.privateKeyFile = "/home/user/.ssh/id_rsa"
ssh 协议握手阶段需要交换公钥用来加密数据,所以 frps 端的 ssh server 需要指定一个私钥文件,可以复用本机已存在的;如果为空,frps会自动创建一个 rsa 私钥文件。
指定自动生成私钥文件地址 1 2 3 4 5 # frps.toml sshTunnelGateway.bindPort = 2200 sshTunnelGateway.autoGenPrivateKeyPath = "/var/frp/ssh-private-key-file"
frps自动创建私钥文件并指定路径存储。
注意:frps 更换私钥文件,会导致 ssh 客户端登录失败,如果需要成功登录,可以删除 /home/user/.ssh/known_hosts
文件中的旧的记录。
使用本机已存在的 authorized_keys 文件,实现 ssh 免密登录鉴权 1 2 3 4 5 # frps.toml sshTunnelGateway.bindPort = 2200 sshTunnelGateway.authorizedKeysFile = "/home/user/.ssh/authorized_keys"
authorizedKeysFile 是 ssh 免密登录使用的文件,存放用户公钥信息,一行一个。
authorizedKeysFile 为空, frps 不对 ssh 客户端进行任何认证。frps 不支持 ssh 用户名+密码模式认证。
可复用本机已有的 authorized_keys
文件对客户端进行认证。
注意:authorizedKeysFile 是 ssh 登录阶段的用户认证,token 是 frps 已有的认证,2 者没有关联,ssh 认证在前,frps 认证 token 在后,强烈建议至少开启1个,如果 authorizedKeysFile 为空,强烈建议 frps 端开启 token 认证,否则有安全风险。
使用自定义的 authorized_keys 文件,实现 ssh 免密登录鉴权 1 2 3 4 5 # frps.toml sshTunnelGateway.bindPort = 2200 sshTunnelGateway.authorizedKeysFile = "/var/frps/custom_authorized_keys_file"
自定义 authorized_keys
文件路径。
authorizedKeysFile 文件变动可能会导致 ssh 登录认证失败,可能需要重新将公钥信息放入 authorizedKeysFile。
虚拟网络 (VirtualNet) Alpha feature, added in v0.62.0
注意 :VirtualNet 是一个 Alpha 阶段的特性,目前不稳定,其配置方式和功能可能会在后续版本中随时调整变更。请勿在生产环境中使用此功能,仅建议用于测试和评估目的。
概述 虚拟网络(VirtualNet)功能允许 frp 通过 TUN 接口创建和管理客户端之间的虚拟网络连接。这一功能将 frp 的能力扩展到了传统端口转发之外,实现了完整的网络层通信。
通过 VirtualNet 功能,你可以:
在不同客户端之间建立 IP 层级的网络连接,不需要为每个服务单独配置端口转发
使应用程序无需感知 frp 的存在,直接通过 IP 访问远程服务
建立类似 VPN 的连接,但由 frp 负责管理
使用要求 使用 VirtualNet 功能需要满足以下条件:
权限要求 :创建 TUN 接口需要 root/管理员权限
平台支持 :目前仅支持 Linux 和 macOS 平台
特性门控 :需要通过配置 featureGates = { VirtualNet = true }
显式启用
地址分配 :每个端点必须配置唯一的 IP 地址/CIDR
配置方法 启用 VirtualNet 由于 VirtualNet 是 Alpha 特性,需要在配置中显式启用:
1 2 3 # frpc.toml featureGates = { VirtualNet = true }
服务端配置 首先,为 frpc 配置虚拟网络地址:
1 2 3 4 5 6 7 8 # frpc.toml (服务端) serverAddr = "x.x.x.x" serverPort = 7000 featureGates = { VirtualNet = true } # 配置虚拟网络接口 virtualNet.address = "100.86.0.1/24"
然后,为代理配置 virtual_net
插件:
1 2 3 4 5 6 7 8 # frpc.toml (服务端) [[proxies]] name = "vnet-server" type = "stcp" secretKey = "your-secret-key" [proxies.plugin] type = "virtual_net"
客户端配置 客户端需要配置访问者插件以连接到虚拟网络:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # frpc.toml (客户端) serverAddr = "x.x.x.x" serverPort = 7000 featureGates = { VirtualNet = true } # 配置虚拟网络接口 virtualNet.address = "100.86.0.2/24" [[visitors]] name = "vnet-visitor" type = "stcp" serverName = "vnet-server" secretKey = "your-secret-key" bindPort = -1 [visitors.plugin] type = "virtual_net" destinationIP = "100.86.0.1" # 目标虚拟 IP 地址
工作原理 VirtualNet 功能基于以下技术实现:
TUN 虚拟接口 :在每个 frp 客户端创建一个 TUN 虚拟网络接口
路由控制 :通过 VNet 控制器管理客户端间的路由表
数据包转发 :在 frp 隧道内部封装和转发 IP 数据包
工作流程如下:
frp 创建 TUN 接口并分配 IP 地址
服务端使用 virtual_net
插件注册连接到 VNet 控制器
客户端使用 virtual_net
访问者插件将目标 IP 的流量路由到对应连接
数据包在 frp 管理的虚拟网络中传输,实现不同机器之间的 IP 层连通性
TCP & UDP 了解 frp TCP
, UDP
类型的代理。
TCP 和 UDP 是 frp 中两种最基础的代理类型,用于代理监听在 TCP 和 UDP 端口的服务。
TCP 代理 1 2 3 4 5 6 7 [[proxies]] name = "ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 6000
UDP 代理 1 2 3 4 5 6 7 [[proxies]] name = "dns" type = "udp" localIP = "127.0.0.1" localPort = 53 remotePort = 6000
通过 type 指定代理类型。
frp 会为本地服务的端口,在 frps 所在的服务端监听对应的远程端口,将远程端口接收到的连接和本地服务的端口关联,透传流量,从而实现让用户在外部访问到内部服务。
HTTP & HTTPS 了解 frp HTTP
, HTTPS
类型的代理。
HTTP 和 HTTPS 是 frp 中针对这两种协议额外提供了一些特殊的能力。本质上目前这两种应用层协议的底层协议都是 TCP。
如果不需要用到相关的特殊功能,可以直接使用 TCP 类型的代理,更加简单方便。
HTTP 和 HTTPS 协议的一个特点是发送的请求都具有 Host 字段,通过该字段描述要访问的服务。基于这个特点,frp 服务端只需要监听在一个端口(通过 vhostHTTPPort
和 vhostHTTPSPort
指定)。就可以根据请求的 Host 来决定需要路由给哪一个代理,而不需要像 TCP 类型那样为每一个服务绑定一个端口。
通常情况下 frp 不会修改转发的任何数据。但有一些后端服务会根据 HTTP 请求 header 中的 Host 字段来展现不同的网站,例如 nginx 的虚拟主机服务,启用 Host Header 的修改功能可以动态修改 HTTP 请求中的 Host 字段。需要注意的是,该功能仅限于 HTTP 类型的代理。
1 2 3 4 5 6 7 8 # frpc.toml [[proxies]] name = "web" type = "http" localPort = 80 customDomains = ["test.yourdomain.com"] hostHeaderRewrite = "dev.yourdomain.com"
原来 HTTP 请求中的 Host 字段 test.yourdomain.com
转发到后端服务时会被替换为 dev.yourdomain.com
。
对于类型为 HTTP 的代理,可以设置在转发中动态添加的 Header 参数
1 2 3 4 5 6 7 8 9 10 # frpc.toml [[proxies]] name = "web" type = "http" localPort = 80 customDomains = ["test.yourdomain.com"] hostHeaderRewrite = "dev.yourdomain.com" requestHeaders.set.x-from-where = "frp" responseHeaders.set.foo = "bar"
根据如上的配置,会在请求的 Header 中加上 x-from-where: frp
,在响应的 Header 中加上 foo: bar
。
设置 BasicAuth 鉴权 由于所有客户端共用一个 frps 的 HTTP 服务端口,任何知道你的域名和 URL 的人都能访问到你部署在内网的服务,但是在某些场景下需要确保只有限定的用户才能访问。
frp 支持通过 HTTP Basic Auth 来保护你的 web 服务,使用户需要通过用户名和密码才能访问到你的服务。
该功能目前仅限于 HTTP 类型的代理,需要在 frpc 的代理配置中添加用户名和密码的设置。
1 2 3 4 5 6 7 8 9 # frpc.toml [[proxies]] name = "web" type = "http" localPort = 80 customDomains = ["test.yourdomain.com"] httpUser = "abc" httpPassword = "abc"
通过浏览器访问 http://test.yourdomain.com
,需要输入配置的用户名和密码才能访问。
自定义二级域名 在多人同时使用一个 frps 时,通过自定义二级域名的方式来使用会更加方便。
通过在 frps 的配置文件中配置 subdomainHost
,就可以启用该特性。之后在 frpc 的 http、https 类型的代理中可以不配置 customDomains
,而是配置一个 subdomain
参数。
只需要将 *.{subdomainHost}
解析到 frps 所在服务器。之后用户可以通过 subdomain 自行指定自己的 web 服务所需要使用的二级域名,通过 {subdomain}.{subdomainHost}
来访问自己的 web 服务。
1 2 3 # frps.toml subdomainHost = "frps.com"
将泛域名 *.frps.com
解析到 frps 所在服务器的 IP 地址。
1 2 3 4 5 6 7 # frpc.toml [[proxies]] name = "web" type = "http" localPort = 80 subdomain = "test"
frps 和 frpc 都启动成功后,通过 test.frps.com
就可以访问到内网的 web 服务。
注:如果 frps 配置了 subdomainHost
,则 customDomains
中不能是属于 subdomainHost
的子域名或者泛域名。
同一个 HTTP 或 HTTPS 类型的代理中 customDomains
和 subdomain
可以同时配置。
路由 URL 路由 frp 支持根据请求的 URL 路径路由转发到不同的后端服务。
通过配置文件中的 locations 字段指定一个或多个 proxy 能够匹配的 URL 前缀(目前仅支持最大前缀匹配,之后会考虑正则匹配)。例如指定 locations = "/news"
,则所有 URL 以 /news
开头的请求都会被转发到这个服务。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # frpc.toml [[proxies]] name = "web01" type = "http" localPort = 80 customDomains = ["web.yourdomain.com"] locations = ["/"] [[proxies]] name = "web02" type = "http" localPort = 81 customDomains = ["web.yourdomain.com"] locations = ["/news", "/about"]
按照上述的示例配置后,web.yourdomain.com
这个域名下所有以 /news
以及 /about
作为前缀的 URL 请求都会被转发到 web02,其余的请求会被转发到 web01。
STCP & SUDP 了解 frp STCP
, SUDP
类型的代理。
STCP 和 SUDP 的 (S) 的含义是 Secret。其作用是为 TCP 和 UDP 类型的服务提供一种安全访问的能力,避免让端口直接暴露在公网上导致任何人都能访问到。
这两种代理要求在被访问服务的机器上以及要访问的用户的机器上都部署上 frp 的客户端。被访问的服务所在机器叫做服务端,另一端叫做访问端。
frp 会在访问端监听一个端口和服务端的端口做映射。访问端的用户需要提供相同的密钥才能连接成功,从而保证安全性。
XTCP 了解 frp XTCP
类型的代理。
XTCP 的配置方式和 STCP 很类似。但是会采用 P2P 的方式进行打洞穿透,如果成功,后续的流量将不会经过 frps,而是直接通信,不再受到 frps 所在服务器的带宽限制。
由于打洞成功率取决于所处网络的 NAT 类型,所以 XTCP 的可用性和稳定性无法保证。在需要可靠连接的情况下,建议使用 STCP 替代。
当 visitor 配置了 keepTunnelOpen = true
时,frpc 会定期检测隧道是否打开,如果没有,则会尝试打洞建立隧道,这样可以始终保持隧道打开,在需要连接对端服务时,可以避免延迟。
默认情况下,visitor 会在接收到用户连接后尝试打洞,如果打洞失败,可以尝试多次建立连接,程序会尝试其他的打洞策略,有可能在多次重试后成功打洞。一旦打洞成功,后续新增连接不必重复打洞,而是可以复用隧道。
Fallback 机制 可以通过配置 fallback 到 stcp visitor 实现在打洞失败时,回退到 stcp 建立连接。
示例配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [[visitors]] name = "stcp-visitor" type = "stcp" serverName = "stcp-test" secretKey = "abc" bindPort = -1 [[visitors]] name = "xtcp-visitor" type = "xtcp" serverName = "xtcp-test" secretKey = "abc" bindAddr = "127.0.0.1" bindPort = 9002 fallbackTo = "stcp-visitor" fallbackTimeoutMs = 200
当连接 127.0.0.1:9002
超过 200ms p2p 打洞还未成功的话,会回退到使用 stcp-visitor 建立连接。fallback 后,之前触发的打洞操作仍然会继续,一般来说打洞完成需要的耗时会比较长。
如果打洞成功,下次建立新的连接时,将不需要再次打洞,会很快完成连接建立,不会触发 fallback。
需要注意根据访问端和被访问端的延迟情况来合理设置超时时间,以避免超时时间太短,即使打洞成功连接也来不及建立,而一直触发 fallback。
stcp-visitor 的 bindPort
设置为 -1 表示不需要监听物理端口,只接受 fallback 的连接即可。
TCPMUX 了解 frp TCPMUX
类型的代理。
frp 支持将单个端口收到的连接路由到不同的代理,类似 vhostHTTPPort
和 vhostHTTPSPort
。
目前支持的复用器只有 httpconnect
。
当在 frps.toml
中设置 tcpmuxHTTPConnectPort
,frps 将会监听在这个端口,接收 HTTP CONNECT 请求。
frps 会根据 HTTP CONNECT 请求中的 host 路由到不同的后端代理。
示例配置如下:
1 2 3 4 # frps.toml bindPort = 7000 tcpmuxHTTPConnectPort = 1337
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 # frpc.toml serverAddr = "x.x.x.x" serverPort = 7000 [[proxies]] name = "proxy1" type = "tcpmux" multiplexer = "httpconnect" customDomains = ["test1"] localPort = 80 [[proxies]] name = "proxy2" type = "tcpmux" multiplexer = "httpconnect" customDomains = ["test2"] localPort = 8080
通过上面的配置,frps 如果接收到 HTTP CONNECT 请求内容:
1 2 CONNECT test1 HTTP/1.1\r\n\r\n
该连接将会被路由到 proxy1 。
通用配置 通用配置结构。
LogConfig
Field
Type
Description
Required
to
string
日志输出文件路径,如果为 console,则会将日志打印在标准输出中。
No
level
string
日志级别,可选值为 trace, debug, info, warn, error,默认级别为 info。
No
maxDays
int
日志文件最多保留天数,默认为 3 天。
No
disablePrintColor
bool
禁用标准输出中的日志颜色。
No
WebServerConfig
Field
Type
Description
Required
addr
string
webServer 监听地址,默认为 127.0.0.1。
No
port
int
webServer 监听端口。
Yes
user
string
HTTP BasicAuth 用户名。
No
password
string
HTTP BasicAuth 密码。
No
assetsDir
string
静态资源目录,Dashboard 使用的资源默认打包在二进制文件中,通过指定此参数使用自定义的静态资源。
No
pprofEnable
bool
启动 Go HTTP pprof,用于应用调试。
No
tls
TLSConfig
Dashboard 启用 HTTPS 的 TLS 相关配置。
No
TLSConfig
Field
Type
Description
Required
certFile
string
TLS 证书文件路径。
Yes
keyFile
string
TLS 密钥文件路径。
Yes
trustedCaFile
string
CA 证书文件路径。
No
serverName
string
TLS Server 名称。
No
QUICOptions
Field
Type
Description
Required
keepalivePeriod
int
默认值为 10 秒。
No
maxIdleTimeout
int
默认值为 30 秒。
No
maxIncomingStreams
int
默认值为 100000。
No
PortsRange
Field
Type
Description
Required
start
int
起始端口。
No
end
int
终止端口。
No
single
int
单一端口。
No
Field
Type
Description
Required
set
map[string]string
在 Header 中设置指定的 KV 值。
No
Field
Type
Description
Required
name
string
Header 名称。
Yes
value
string
Header 值。
Yes
ValueSource
Field
Type
Description
Required
type
string
数据源类型,目前仅支持 “file”。
Yes
file
FileSource
文件数据源配置,当 type 为 “file” 时必填。
No
FileSource
Field
Type
Description
Required
path
string
文件路径。
Yes
服务端配置 frp 服务端详细配置说明。
ServerConfig
Field
Type
Description
Required
auth
AuthServerConfig
鉴权配置。
No
bindAddr
string
服务端监听地址,用于接收 frpc 的连接,默认监听 0.0.0.0。
No
bindPort
int
服务端监听端口,默认值为 7000。
No
kcpBindPort
int
服务端监听 KCP 协议端口,用于接收配置了使用 KCP 协议的 frpc 连接。
No
quicBindPort
int
服务端监听 QUIC 协议端口,用于接收配置了使用 QUIC 协议的 frpc 连接。
No
proxyBindAddr
string
代理监听地址,可以使代理监听在不同的网卡地址,默认情况下同 bindAddr。
No
vhostHTTPPort
int
HTTP 类型代理监听的端口,启用后才能支持 HTTP 类型的代理。
No
vhostHTTPTimeout
int
HTTP 类型代理在服务端的 ResponseHeader 超时时间,默认为 60s。
No
vhostHTTPSPort
int
HTTPS 类型代理监听的端口,启用后才能支持 HTTPS 类型的代理。
No
tcpmuxHTTPConnectPort
int
tcpmux 类型且复用器为 httpconnect 的代理监听的端口。
No
tcpmuxPassthrough
bool
对于 tcpmux 类型的代理是否透传 CONNECT 请求。
No
subDomainHost
string
二级域名后缀。
No
custom404Page
string
自定义 404 错误页面地址。
No
sshTunnelGateway
SSHTunnelGateway
ssh 隧道网关配置。
No
webServer
WebServerConfig
服务端 Dashboard 配置。
No
enablePrometheus
bool
是否提供 Prometheus 监控接口,需要同时启用了 webServer 后才会生效。
No
log
LogConfig
日志配置。
No
transport
ServerTransportConfig
网络层配置。
No
detailedErrorsToClient
bool
服务端返回详细错误信息给客户端,默认为 true。
No
maxPortsPerClient
int
限制单个客户端最大同时存在的代理数,默认无限制。
No
userConnTimeout
int
用户建立连接后等待客户端响应的超时时间,单位秒,默认为 10 秒。
No
udpPacketSize
int
代理 UDP 服务时支持的最大包长度,默认为 1500,服务端和客户端的值需要一致。
No
natholeAnalysisDataReserveHours
int
打洞策略数据的保留时间,默认为 168 小时,即 7 天。
No
allowPorts
[]PortsRange
允许代理绑定的服务端端口。
No
httpPlugins
[]HTTPPluginOptions
服务端 HTTP 插件配置。
No
AuthServerConfig
Field
Type
Description
Required
method
string
鉴权方式,可选值为 token 或 oidc,默认为 token。
No
additionalScopes
[]string
鉴权信息附加范围,可选值为 HeartBeats 和 NewWorkConns
No
token
string
在 method 为 token 时生效,客户端需要设置一样的值才能鉴权通过。与 tokenSource 字段互斥。
No
tokenSource
ValueSource
从文件中加载 token 的配置。与 token 字段互斥。
No
oidc
AuthOIDCServerConfig
oidc 鉴权配置。
No
AuthOIDCServerConfig
Field
Type
Description
Required
issuer
string
No
audience
string
No
skipExpiryCheck
bool
No
skipIssuerCheck
bool
No
ServerTransportConfig
Field
Type
Description
Required
tcpMuxKeepaliveInterval
int
tcp mux 的心跳检查间隔时间,单位秒。
No
tcpKeepalive
int
和客户端底层 TCP 连接的 keepalive 间隔时间,单位秒,配置为负数表示不启用。
No
maxPoolCount
int
允许客户端设置的最大连接池大小,如果客户端配置的值大于此值,会被强制修改为最大值,默认为 5。
No
heartbeatTimeout
int
服务端和客户端心跳连接的超时时间,单位秒,默认为 90 秒。
No
quic
QUICOptions
QUIC 协议配置参数。
No
tls
TLSServerConfig
服务端 TLS 协议配置。
No
TLSServerConfig
Field
Type
Description
Required
force
bool
是否只接受启用了 TLS 的客户端连接。
No
TLSConfig
TLS 协议配置,内嵌结构。
No
HTTPPluginOptions
Field
Type
Description
Required
name
string
插件名称。
Yes
addr
string
插件接口的地址。
Yes
path
string
插件接口的 Path。
Yes
ops
[]string
插件需要生效的操作列表,具体可选值请参考服务端插件的说明文档。
Yes
tlsVerify
bool
当插件地址为 HTTPS 协议时,是否校验插件的 TLS 证书,默认为不校验。
No
SSHTunnelGateway
Field
Type
Description
Required
bindPort
int
SSH 服务器监听端口。
YES
privateKeyFile
string
SSH 服务器私钥文件路径。若为空,frps将读取autoGenPrivateKeyPath路径下的私钥文件。
No
autoGenPrivateKeyPath
string
私钥文件自动生成路径,默认为./.autogen_ssh_key。若文件不存在或内容为空,frps将自动生成RSA私钥文件并存储到该路径。
No
authorizedKeysFile
string
SSH 客户端授权密钥文件路径。若为空,则不进行SSH客户端鉴权认证。非空可实现SSH免密登录认证。
客户端配置 frp 客户端的详细配置说明。
ClientConfig
ClientCommonConfig
Field
Type
Description
Required
auth
AuthClientConfig
客户端鉴权配置。
No
user
string
用户名,设置此参数后,代理名称会被修改为 {user}.{proxyName},避免代理名称和其他用户冲突。
No
serverAddr
string
连接服务端的地址。
No
serverPort
int
连接服务端的端口,默认为 7000。
No
natHoleStunServer
string
xtcp 打洞所需的 stun 服务器地址,默认为 stun.easyvoip.com:3478。
No
dnsServer
string
使用 DNS 服务器地址,默认使用系统配置的 DNS 服务器,指定此参数可以强制替换为自定义的 DNS 服务器地址。
No
loginFailExit
bool
第一次登陆失败后是否退出,默认为 true。
No
start
[]string
指定启用部分代理,当配置了较多代理,但是只希望启用其中部分时可以通过此参数指定,默认为全部启用。
No
log
LogConfig
日志配置。
No
webServer
WebServerConfig
客户端 AdminServer 配置。
No
transport
ClientTransportConfig
客户端网络层配置。
No
virtualNet
VirtualNetConfig
虚拟网络配置,Alpha 特性。
No
featureGates
map[string]bool
特性门控,用于启用或禁用实验性功能。
No
udpPacketSize
int
代理 UDP 服务时支持的最大包长度,默认为 1500,服务端和客户端需要保持配置一致。
No
metadatas
map[string]string
附加元数据,会传递给服务端插件,提供附加能力。
No
includes
[]string
指定额外的配置文件目录,其中的 proxy 和 visitor 配置会被读取加载。
No
ClientTransportConfig
Field
Type
Description
Required
protocol
string
和 frps 之间的通信协议,可选值为 tcp, kcp, quic, websocket, wss。默认为 tcp。
No
dialServerTimeout
int
连接服务端的超时时间,默认为 10s。
No
dialServerKeepalive
int
和服务端底层 TCP 连接的 keepalive 间隔时间,单位秒。
No
connectServerLocalIP
string
连接服务端时所绑定的本地 IP。
No
proxyURL
string
连接服务端使用的代理地址,格式为 {protocol}://user:passwd@192.168.1.128 :8080 protocol 目前支持 http、socks5、ntlm。
No
poolCount
int
连接池大小。
No
tcpMux
bool
TCP 多路复用,默认启用。
No
tcpMuxKeepaliveInterval
int
tcp_mux
的心跳检查间隔时间。
No
quic
QUICOptions
QUIC 协议配置参数。
No
heartbeatInterval
int
向服务端发送心跳包的间隔时间,默认为 30s。建议启用 tcp_mux_keepalive_interval
,将此值设置为 -1。
No
heartbeatTimeout
int
和服务端心跳的超时时间,默认为 90s。
No
tls
TLSClientConfig
客户端 TLS 协议配置。
No
TLSClientConfig
Field
Type
Description
Required
enable
bool
是否和服务端之间启用 TLS 连接,默认启用。
No
disableCustomTLSFirstByte
bool
启用 TLS 连接时,不发送 0x17 特殊字节。默认为 true。当配置为 true 时,无法和 vhostHTTPSPort 端口复用。
No
TLSConfig
TLS 协议配置,内嵌结构。
No
AuthClientConfig
Field
Type
Description
Required
method
string
鉴权方式,可选值为 token 或 oidc,默认为 token。
No
additionalScopes
[]string
鉴权信息附加范围,可选值为 HeartBeats 和 NewWorkConns
No
token
string
在 method 为 token 时生效,客户端需要设置一样的值才能鉴权通过。与 tokenSource 字段互斥。
No
tokenSource
ValueSource
从文件中加载 token 的配置。与 token 字段互斥。
No
oidc
AuthOIDCClientConfig
oidc 鉴权配置。
No
AuthOIDCClientConfig
Field
Type
Description
Required
clientID
string
No
clientSecret
string
No
audience
string
No
scope
string
No
tokenEndpointURL
string
No
additionalEndpointParams
map[string]string
No
VirtualNetConfig
Field
Type
Description
Required
address
string
虚拟网络接口的 IP 地址和网段,格式为 CIDR (例如 “100.86.0.1/24”)。
Yes
代理配置 frp 代理的详细配置说明。
ProxyBaseConfig
Field
Type
Description
Required
name
string
代理名称。
Yes
type
string
代理类型,可选值为 tcp, udp, http, https, tcpmux, stcp, sudp, xtcp。
Yes
annotations
map[string]string
代理的注释信息,会被展示在 server 的 dashboard 中。
No
transport
ProxyTransport
代理网络层配置。
No
metadatas
map[string]string
附加元数据,会传递给服务端插件,提供附加能力。
No
loadBalancer
LoadBalancerConfig
负载均衡配置。
No
healthCheck
HealthCheckConfig
健康检查配置。
No
ProxyBackend
代理后端服务配置。
Yes
ProxyTransport
Field
Type
Description
Required
useEncryption
bool
是否启用加密功能,启用后该代理和服务端之间的通信内容都会被加密传输,如果 frpc 启用了全局 TLS,则不需要再启用此参数。
No
useCompression
bool
是否启用压缩功能,启用后该代理和服务端之间的通信内容都会被压缩传输。
No
bandwidthLimit
string
设置单个 proxy 的带宽限流,单位为 MB 或 KB,0 表示不限制,如果启用,默认会作用于对应的 frpc。
No
bandwidthLimitMode
string
限流类型,客户端限流或服务端限流,可选值为 client 和 server,默认为客户端限流。
No
proxyProtocolVersion
string
启用 proxy protocol 协议的版本,可选值为 v1 和 v2。如果启用,则 frpc 和本地服务建立连接后会发送 proxy protocol 的协议,包含了原请求的 IP 地址和端口等内容。
No
ProxyBackend
Field
Type
Description
Required
localIP
string
被代理的本地服务 IP,默认为 127.0.0.1。
No
localPort
int
被代理的本地服务端口。
No
plugin
ClientPluginOptions
客户端插件配置,如果启用了客户端插件,则不需要配置 localIP 和 localPort,流量会由客户端插件接管。不同的插件类型对应不同的配置,例如 HTTPProxyPluginOptions 。
No
LoadBalancerConfig
Field
Type
Description
Required
group
string
负载均衡分组名称,用户请求会以轮询的方式发送给同一个 group 中的代理。
Yes
groupKey
string
负载均衡分组密钥,用于对负载均衡分组进行鉴权,groupKey 相同的代理才会被加入到同一个分组中。
No
HealthCheckConfig
Field
Type
Description
Required
type
string
健康检查类型,可选值为 tcp 和 http,配置后启用健康检查功能,tcp 是连接成功则认为服务健康,http 要求接口返回 2xx 的状态码则认为服务健康。
Yes
timeoutSeconds
int
健康检查超时时间(秒),默认为 3s。
No
maxFailed
int
健康检查连续错误次数,连续检查错误多少次认为服务不健康,默认为 1。
No
intervalSeconds
int
健康检查周期(秒),每隔多长时间进行一次健康检查,默认为 10s。
No
path
string
健康检查的 HTTP 接口,如果健康检查类型是 http,则需要配置此参数,指定发送 http 请求的 path,例如 /health
。
No
httpHeaders
[]HTTPHeader
健康检查的 HTTP 请求头,仅在健康检查类型是 http 时生效。
No
DomainConfig
Field
Type
Description
Required
customDomains
[]string
自定义域名列表。
No
subdomain
string
子域名。
No
TCPProxyConfig
Field
Type
Description
Required
ProxyBaseConfig
基础配置。
Yes
remotePort
int
服务端绑定的端口,用户访问服务端此端口的流量会被转发到对应的本地服务。
No
UDPProxyConfig
Field
Type
Description
Required
ProxyBaseConfig
基础配置。
Yes
remotePort
int
服务端绑定的端口,用户访问服务端此端口的流量会被转发到对应的本地服务。
No
HTTPProxyConfig
Field
Type
Description
Required
ProxyBaseConfig
基础配置。
Yes
DomainConfig
域名配置。
Yes
locations
[]string
URL 路由配置。
No
httpUser
string
HTTP Basic Auth 用户名。
No
httpPassword
string
HTTP Basic Auth 密码。
No
hostHeaderRewrite
string
替换 Host Header。
No
requestHeaders
HeaderOperations
对请求 Header 的操作配置。
No
responseHeaders
HeaderOperations
对响应 Header 的操作配置。
No
routeByHTTPUser
string
根据 HTTP Basic Auth user 路由。
No
HTTPSProxyConfig
TCPMuxProxyConfig
Field
Type
Description
Required
ProxyBaseConfig
基础配置。
Yes
DomainConfig
域名配置。
Yes
httpUser
string
用户名,如果配置此参数,通过 HTTP CONNECT 建立连接时需要通过 Proxy-Authorization 附加上正确的身份信息。
No
httpPassword
string
密码。
No
routeByHTTPUser
string
根据 HTTP Basic Auth user 路由。
No
multiplexer
string
复用器类型,目前仅支持 httpconnect。
No
STCPProxyConfig
Field
Type
Description
Required
ProxyBaseConfig
基础配置。
Yes
secretKey
string
密钥,服务端和访问端的密钥需要一致,访问端才能访问到服务端。
No
allowUsers
[]string
允许访问的 visitor 用户列表,默认只允许同一用户下的 visitor 访问,配置为 * 则允许任何 visitor 访问。
No
XTCPProxyConfig
Field
Type
Description
Required
ProxyBaseConfig
基础配置。
Yes
secretKey
string
密钥,服务端和访问端的密钥需要一致,访问端才能访问到服务端。
No
allowUsers
[]string
允许访问的 visitor 用户列表,默认只允许同一用户下的 visitor 访问,配置为 * 则允许任何 visitor 访问。
No
SUDPProxyConfig
Field
Type
Description
Required
ProxyBaseConfig
基础配置。
Yes
secretKey
string
密钥,服务端和访问端的密钥需要一致,访问端才能访问到服务端。
No
allowUsers
[]string
允许访问的 visitor 用户列表,默认只允许同一用户下的 visitor 访问,配置为 * 则允许任何 visitor 访问。
No
访问者配置 frp 访问者的详细配置说明。
VisitorBaseConfig
Field
Type
Description
Required
name
string
访问者名称。
Yes
type
string
访问者类型,可选值为 stcp, sudp, xtcp。
Yes
transport
VisitorTransport
访问者网络层配置。
No
secretKey
string
密钥,服务端和访问端的密钥需要一致,访问端才能访问到服务端。
No
serverUser
string
要访问的 proxy 所属的用户名,如果为空,则默认为当前用户。
No
serverName
string
要访问的 proxy 名称。
Yes
bindAddr
string
visitor 监听的本地地址,通过访问监听的地址和端口,连接到远端代理的服务。
No
bindPort
int
visitor 监听的本地端口,如果为 -1,表示不需要监听物理端口,通常可以用于作为其他 visitor 的 fallback。
Yes
plugin
VisitorPluginOptions
访问者插件配置,用于扩展 visitor 功能。不同的插件类型对应不同的配置。
No
VisitorTransport
Field
Type
Description
Required
useEncryption
bool
是否启用加密功能,启用后该代理和服务端之间的通信内容都会被加密传输,如果 frpc 启用了全局 TLS,则不需要再启用此参数。
No
useCompression
bool
是否启用压缩功能,启用后该代理和服务端之间的通信内容都会被压缩传输。
No
STCPVisitorConfig
SUDPVisitorConfig
XTCPVisitorConfig
Field
Type
Description
Required
VisitorBaseConfig
基础配置。
Yes
protocol
string
隧道底层通信协议,可选 quic 和 kcp,默认为 quic。
No
keepTunnelOpen
bool
是否保持隧道打开,如果开启,会定期检查隧道状态并尝试保持打开。
No
maxRetriesAnHour
int
每小时尝试打开隧道的次数,默认值为 8。
No
minRetryInterval
int
重试打开隧道的最小间隔时间,单位: 秒,默认为 90s。
No
fallbackTo
string
回退到的其他 visitor 名称。
No
fallbackTimeoutMs
int
连接建立超过多长时间(ms) 后回退到其他 visitor。
No
客户端插件配置 frp 客户端插件的详细配置说明。
HTTPProxyPluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “http_proxy”。
Yes
httpUser
string
HTTP 代理用户名。
No
httpPassword
string
HTTP 代理密码。
No
Socks5PluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “socks5”。
Yes
username
string
用户名。
No
password
string
密码。
No
StaticFilePluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “static_file”。
Yes
localPath
string
静态文件所在本地路径。
Yes
stripPrefix
string
去除用户 HTTP 请求 Path 的特定前缀。
No
httpUser
string
HTTP Basic Auth 用户名。
No
httpPassword
string
HTTP Basic Auth 密码。
No
UnixDomainSocketPluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “unix_domain_socket”。
Yes
unixPath
string
UNIX 域套接字的地址。
Yes
HTTP2HTTPSPluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “http2https”。
Yes
localAddr
string
本地 HTTPS 服务地址。
Yes
hostHeaderRewrite
string
替换 Host header。
No
requestHeaders
HeaderOperations
对请求 Header 的操作配置。
No
HTTPS2HTTPPluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “https2http”。
Yes
localAddr
string
本地 HTTPS 服务地址。
Yes
hostHeaderRewrite
string
替换 Host header。
No
requestHeaders
HeaderOperations
对请求 Header 的操作配置。
No
enableHTTP2
bool
是否启用 HTTP/2,默认启用。
No
crtPath
string
TLS 证书文件路径。
No
keyPath
string
TLS 密钥文件路径。
No
HTTPS2HTTPSPluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “https2https”。
Yes
localAddr
string
本地 HTTPS 服务地址。
Yes
hostHeaderRewrite
string
替换 Host header。
No
requestHeaders
HeaderOperations
对请求 Header 的操作配置。
No
enableHTTP2
bool
是否启用 HTTP/2,默认启用。
No
crtPath
string
TLS 证书文件路径。
No
keyPath
string
TLS 密钥文件路径。
No
TLS2RawPluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “tls2raw”。
Yes
localAddr
string
本地服务地址。
Yes
crtPath
string
TLS 证书文件路径。
No
keyPath
string
TLS 密钥文件路径。
No
VirtualNetPluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “virtual_net”。
Yes
访问者插件配置 frp 访问者插件的详细配置说明。
VirtualNetVisitorPluginOptions
Field
Type
Description
Required
type
string
插件类型,设置为 “virtual_net”。
Yes
destinationIP
string
要访问的目标虚拟 IP 地址。通常是服务端的虚拟网络地址。
Yes