跳转至

Frp 网络穿透工具(v0.66.0)

📖 概述

FRP (Fast Reverse Proxy) 是一个高性能的反向代理应用,可以帮助你将内网服务暴露到公网。

📦 安装

Bash
# 解压到指定目录
tar -zxvf frp_0.66.0_linux_amd64.tar.gz -C /opt/
cd /opt
mv frp_0.66.0_linux_amd64 frp

# 查看目录结构
tree frp/
frp/
├── frpc                 # 客户端程序
├── frpc.toml            # 客户端配置文件
├── frps                 # 服务端程序
├── frps.toml            # 服务端配置文件
├── LICENSE              # 开源协议
└── systemd/             # Systemd 服务文件
    ├── frpc.service
    ├── frpc@.service
    ├── frps.service
    └── frps@.service

📚 基本概念

术语 说明
frps FRP 服务端,运行在具有公网 IP 的服务器上
frpc FRP 客户端,运行在内网需要穿透的服务器上
proxy 代理配置,定义要暴露的内网服务
auth.token 认证令牌,用于服务端和客户端之间的认证
clientID 客户端唯一标识(v0.66+ 新增)

服务端配置(frps.toml)

基础配置参数

TOML
bindAddr = "0.0.0.0"
bindPort = 7000
参数 必填 默认值 说明 示例
bindAddr 0.0.0.0 服务端监听地址 bindAddr = "0.0.0.0"
bindPort 7000 服务端与客户端通信的 TCP 端口 bindPort = 7000
kcpBindPort - KCP 协议监听的 UDP 端口 kcpBindPort = 7000
quicBindPort - QUIC 协议监听的 UDP 端口 quicBindPort = 7001

说明

  • bindAddr:默认监听所有网卡,生产环境可指定具体 IP
  • kcpBindPort:KCP 适合高延迟、易丢包网络,但多消耗 10-20% 带宽
  • quicBindPort:QUIC 协议,基于 UDP 的低延迟传输

代理端口配置

参数 必填 默认值 说明 示例
vhostHTTPPort - HTTP 反向代理监听端口 vhostHTTPPort = 80
vhostHTTPSPort - HTTPS 反向代理监听端口 vhostHTTPSPort = 443
tcpMux true 是否启用 TCP 多路复用 tcpMux = true
tcpMuxKeepaliveInterval 60 TCP 多路复用保活间隔(秒) tcpMuxKeepaliveInterval = 60

说明

  • vhostHTTPPort:启用后,可通过域名访问内网 HTTP 服务
  • vhostHTTPSPort:启用后,可通过域名访问内网 HTTPS 服务
  • tcpMux:启用后,多个连接可复用同一个 TCP 连接,提高性能

Web 控制台配置(Dashboard)

TOML
1
2
3
4
webServer.addr = "0.0.0.0"
webServer.port = 5500
webServer.user = "admin"
webServer.password = "your_password"
参数 必填 默认值 说明 示例
webServer.addr 0.0.0.0 Dashboard 监听地址 webServer.addr = "0.0.0.0"
webServer.port - Dashboard 监听端口 webServer.port = 5500
webServer.user admin Dashboard 登录用户名 webServer.user = "admin"
webServer.password admin Dashboard 登录密码 webServer.password = "xxx"
webServer.tls.certFile - Dashboard SSL 证书路径 webServer.tls.certFile = "/etc/ssl/dashboard.pem"
webServer.tls.keyFile - Dashboard SSL 密钥路径 webServer.tls.keyFile = "/etc/ssl/dashboard.key"

说明

  • Dashboard 用于查看 frp 运行状态、代理信息、客户端管理等
  • v0.66+ 支持客户端唯一标识(clientID)管理
  • 生产环境建议启用 SSL 保护 Dashboard

日志配置

TOML
1
2
3
log.to = "/var/log/frps.log"
log.level = "warn"
log.maxDays = 7
参数 必填 默认值 说明 示例
log.to console 日志文件路径,console 表示输出到终端 log.to = "/var/log/frps.log"
log.level info 日志级别:trace, debug, info, warn, error log.level = "warn"
log.maxDays - 日志保留天数 log.maxDays = 7
log.disablePrintColor false 是否禁用日志颜色 log.disablePrintColor = false

日志级别说明

  • trace:最详细,包含所有调试信息
  • debug:详细调试信息
  • info:一般信息(推荐)
  • warn:警告信息
  • error:错误信息

认证配置

TOML
auth.token = "your_token_here"
参数 必填 默认值 说明 示例
auth.token 推荐 - 客户端连接所需的认证令牌 auth.token = "your_token_here"
auth.additionalScopes - 额外认证范围:HeartBeats, NewWorkConns auth.additionalScopes = ["HeartBeats"]

OIDC 认证(高级)

TOML
1
2
3
4
5
[auth.oidc]
issuer = "https://accounts.google.com"
audience = "your-audience"
skipExpiryCheck = false
skipIssuerCheck = false

说明

  • auth.token:服务端和客户端必须配置相同的 token 才能连接
  • auth.additionalScopes:启用后,心跳和新连接也需要认证
  • OIDC 认证:支持外部身份提供商(如 Google、Azure AD)

连接限制配置

TOML
maxPoolCount = 5
maxPortsPerClient = 0
参数 必填 默认值 说明 示例
maxPoolCount 5 每个代理的连接池最大连接数 maxPoolCount = 5
maxPortsPerClient 0 每个客户端可使用的最大端口数,0 表示无限制 maxPortsPerClient = 0
allowPorts - 允许客户端使用的端口 allowPorts = [{start=5002,end=5100}]

allowPorts 格式说明

TOML
1
2
3
4
allowPorts = [
  { single = 5001 },           # 单个端口
  { start = 5002, end = 5100 } # 端口范围
]

子域名配置

参数 必填 默认值 说明 示例
subDomainHost - 子域名主机名 subDomainHost = "example.com"

说明

  • 启用后,客户端可使用 xxx.example.com 形式的子域名
  • 需要配置 DNS 泛解析 *.example.com 到服务器 IP

传输配置

TOML
1
2
3
4
[transport]
tcpMux = true
tcpMuxKeepaliveInterval = 60
tcpKeepalive = 60
参数 必填 默认值 说明 示例
transport.tcpMux true 是否启用 TCP 多路复用 transport.tcpMux = true
transport.tcpMuxKeepaliveInterval 60 TCP 多路复用保活间隔(秒) transport.tcpMuxKeepaliveInterval = 60
transport.tcpKeepalive 60 TCP 保活间隔(秒) transport.tcpKeepalive = 60
transport.maxPoolCount 5 连接池最大连接数 transport.maxPoolCount = 5

功能开关(Feature Gates)

v0.66+ 新增:实验性功能开关

TOML
[featureGates]
VirtualNet = false  # 虚拟网络功能(Alpha)
功能 说明 状态
VirtualNet 虚拟网络,创建 TUN 设备实现 Layer 3 连通性 Alpha

说明

  • 实验性功能默认关闭
  • 配置为 true 启用
  • 生产环境慎用

完整服务端配置示例

TOML
# === 基础配置 ===
bindAddr = "0.0.0.0"
bindPort = 5000
# kcpBindPort = 5000  # 不启用 KCP 时注释

# === 代理端口 ===
vhostHTTPPort = 5080
vhostHTTPSPort = 5443

# === 认证配置 ===
auth.token = "your_token_here"

# === Dashboard 配置 ===
webServer.addr = "0.0.0.0"
webServer.port = 5500
webServer.user = "admin"
webServer.password = "your_password"

# === 日志配置 ===
log.to = "/var/log/frps.log"
log.level = "warn"
log.maxDays = 7

# === 连接限制 ===
maxPoolCount = 5
maxPortsPerClient = 0

# === 允许端口 ===
allowPorts = [
  { single = 5001 },
  { start = 5002, end = 5100 }
]

# === 子域名 ===
# subDomainHost = "example.com"

# === 传输配置 ===
[transport]
tcpMux = true
tcpKeepalive = 60

客户端配置(frpc.toml)

基础配置参数

TOML
serverAddr = "x.x.x.x"
serverPort = 5000
参数 必填 默认值 说明 示例
serverAddr - 服务端地址(公网 IP 或域名) serverAddr = "x.x.x.x"
serverPort - 服务端 bindPort 端口 serverPort = 5000
clientID - 客户端唯一标识(v0.66+ 新增) clientID = "unique-client-001"
loginFailExit true 登录失败后是否退出 loginFailExit = false

说明

  • clientID:用于服务端 Dashboard 识别和管理客户端
  • loginFailExit = false:登录失败后持续重试,适合移动网络

认证配置

TOML
auth.token = "your_token_here"
参数 必填 默认值 说明 示例
auth.token 推荐 - 与服务端一致的认证令牌 auth.token = "your_token_here"
auth.additionalScopes - 额外认证范围:HeartBeats, NewWorkConns auth.additionalScopes = ["HeartBeats"]

日志配置

TOML
1
2
3
log.to = "/var/log/frpc.log"
log.level = "warn"
log.maxDays = 7
参数 必填 默认值 说明 示例
log.to console 日志文件路径 log.to = "/var/log/frpc.log"
log.level info 日志级别:trace, debug, info, warn, error log.level = "warn"
log.maxDays - 日志保留天数 log.maxDays = 7
log.disablePrintColor false 是否禁用日志颜色 log.disablePrintColor = false

Web 控制台配置(Admin API)

TOML
1
2
3
4
webServer.addr = "0.0.0.0"
webServer.port = 5400
webServer.user = "admin"
webServer.password = "your_password"
参数 必填 默认值 说明 示例
webServer.addr 127.0.0.1 Web 控制台监听地址 webServer.addr = "0.0.0.0"
webServer.port - Web 控制台监听端口 webServer.port = 5400
webServer.user - Web 控制台用户名 webServer.user = "admin"
webServer.password - Web 控制台密码 webServer.password = "xxx"

说明

  • 启用后可通过 Web 界面管理 frpc(如热重载配置)
  • API 端点:http://127.0.0.1:5400/api/reload

传输配置

TOML
1
2
3
4
[transport]
protocol = "tcp"
heartbeatInterval = 30
heartbeatTimeout = 90
参数 必填 默认值 说明 示例
transport.protocol tcp 与服务端通信的协议:tcp, kcp, quic transport.protocol = "tcp"
transport.heartbeatInterval 30 心跳间隔(秒) transport.heartbeatInterval = 30
transport.heartbeatTimeout 90 心跳超时时间(秒) transport.heartbeatTimeout = 90
transport.poolCount 1 连接池大小(预建立连接数) transport.poolCount = 1
transport.tcpMux true 是否启用 TCP 多路复用 transport.tcpMux = true

说明

  • protocol = "kcp":在高延迟、易丢包网络下性能更好
  • poolCount:预建立连接数,越大连接建立越快,但消耗更多资源

完整客户端配置示例

TOML
# === 服务端配置 ===
serverAddr = "x.x.x.x"
serverPort = 5000
clientID = "unique-client-001"

# === 认证配置 ===
auth.token = "your_token_here"

# === Web 控制台 ===
webServer.addr = "0.0.0.0"
webServer.port = 5400
webServer.user = "admin"
webServer.password = "your_password"

# === 日志配置 ===
log.to = "/var/log/frpc.log"
log.level = "warn"
log.maxDays = 7

# === 传输配置 ===
[transport]
protocol = "tcp"
heartbeatInterval = 30
heartbeatTimeout = 90
poolCount = 1
tcpMux = true

常用代理配置

TCP 端口映射

场景:将内网 SSH 服务暴露到公网

TOML
1
2
3
4
5
6
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
参数 说明 示例
name 代理名称(唯一) "ssh"
type 代理类型 "tcp"
localIP 内网服务地址 "127.0.0.1"
localPort 内网服务端口 22
remotePort 服务端暴露的公网端口 6000

使用方式: ssh -p 6000 user@x.x.x.x

特殊场景

TOML
1
2
3
4
5
6
# 启用代理(默认启用)
enabled = true

# 负载均衡组
loadBalancer.group = "ssh-group"
loadBalancer.groupKey = "secret-key"

UDP 服务

场景:将内网 DNS 服务暴露到公网

TOML
1
2
3
4
5
6
[[proxies]]
name = "dns"
type = "udp"
localIP = "8.8.8.8"
localPort = 53
remotePort = 6001
参数 说明 示例
name 代理名称 "dns"
type 代理类型 "udp"
localIP 内网服务地址 "8.8.8.8"
localPort 内网服务端口 53
remotePort 服务端暴露的公网端口 6001

HTTP 反向代理

场景:将内网 Web 服务通过域名暴露到公网

TOML
1
2
3
4
5
6
[[proxies]]
name = "web"
type = "http"
localIP = "127.0.0.1"
localPort = 80
customDomains = ["www.yourdomain.com"]
参数 说明 示例
name 代理名称 "web"
type 代理类型 "http"
localIP 内网服务地址 "127.0.0.1"
localPort 内网服务端口 80
customDomains 自定义域名数组 ["www.yourdomain.com"]

使用方式: 访问 http://www.yourdomain.com

多域名配置

TOML
customDomains = ["lovev.top", "www.lovev.top"]

HTTPS 反向代理

场景:将内网 HTTPS 服务通过域名暴露到公网

TOML
1
2
3
4
5
6
[[proxies]]
name = "web-https"
type = "https"
localIP = "127.0.0.1"
localPort = 443
customDomains = ["www.yourdomain.com"]
参数 说明 示例
name 代理名称 "web-https"
type 代理类型 "https"
localIP 内网服务地址 "127.0.0.1"
localPort 内网服务端口 443
customDomains 自定义域名数组 ["www.yourdomain.com"]

使用方式: 访问 <https://www.yourdomain.com>

子域名配置

场景:使用子域名访问不同服务

TOML
# 服务端配置
subDomainHost = "example.com"

# 客户端配置
[[proxies]]
name = "blog"
type = "http"
localIP = "127.0.0.1"
localPort = 80
subdomain = "blog"

使用方式: 访问 http://blog.example.com

负载均衡(v0.66+ 增强)

场景:多个后端服务负载均衡

TOML
[[proxies]]
name = "web-01"
type = "http"
localIP = "127.0.0.1"
localPort = 80
customDomains = ["www.yourdomain.com"]

# 负载均衡组
loadBalancer.group = "web-group"
loadBalancer.groupKey = "secret-key"

# 健康检查
healthCheck.type = "http"
healthCheck.path = "/status"
healthCheck.intervalSeconds = 10
healthCheck.maxFailed = 3
healthCheck.timeoutSeconds = 2
参数 说明 示例
loadBalancer.group 负载均衡组名 "web-group"
loadBalancer.groupKey 组密钥(组内必须一致) "secret-key"
healthCheck.type 健康检查类型:tcp, http "http"
healthCheck.path 健康检查路径 "/status"
healthCheck.intervalSeconds 检查间隔(秒) 10
healthCheck.maxFailed 最大失败次数 3
healthCheck.timeoutSeconds 超时时间(秒) 2

HTTPS 负载均衡(v0.66+ 新增)

TOML
1
2
3
4
5
6
7
8
[[proxies]]
name = "web-https-01"
type = "https"
localIP = "127.0.0.1"
localPort = 443
customDomains = ["www.yourdomain.com"]
loadBalancer.group = "web-https-group"
loadBalancer.groupKey = "secret-key"

代理启用/禁用开关(v0.66+ 新增)

TOML
1
2
3
4
5
6
7
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
enabled = false  # 禁用但不删除配置

说明

  • enabled = true:启用代理(默认)
  • enabled = false:禁用代理,配置保留

插件功能

场景:使用内置插件

TOML
# HTTP 代理插件
[[proxies]]
name = "http-proxy"
type = "tcp"
remotePort = 6002

[proxies.plugin]
type = "http_proxy"
httpUser = "abc"
httpPassword = "abc"

# Unix Domain Socket 插件
[[proxies]]
name = "unix-socket"
type = "tcp"
remotePort = 6003

[proxies.plugin]
type = "unix_domain_socket"
unixPath = "/var/run/docker.sock"

可用插件

  • http_proxy:HTTP 代理
  • socks5:SOCKS5 代理
  • unix_domain_socket:Unix 域套接字
  • http2https:HTTP 转 HTTPS
  • https2http:HTTPS 转 HTTP

高级配置

元数据(Metadata)

TOML
[[proxies]]
name = "web"
type = "http"
localIP = "127.0.0.1"
localPort = 80
customDomains = ["www.yourdomain.com"]

# 元数据
metadatas.key1 = "value1"
metadatas.key2 = "value2"

说明

  • 元数据可传递给服务端
  • 用于自定义路由、认证等场景

注解(Annotations)

TOML
1
2
3
4
5
6
7
8
9
[[proxies]]
name = "web"
type = "http"
localIP = "127.0.0.1"
localPort = 80

# 注解
annotations."k8s.io/service-name" = "my-service"
annotations."k8s.io/service-namespace" = "default"

说明

  • 注解用于 K8s 等场景
  • 格式:annotations."key" = "value"

流量控制

TOML
[[proxies]]
name = "web"
type = "http"
localIP = "127.0.0.1"
localPort = 80

# 流量控制
transport.proxyProtocolVersion = "v2"
transport.useEncryption = true
transport.useCompression = true
参数 说明 示例
transport.proxyProtocolVersion Proxy Protocol 版本 "v2"
transport.useEncryption 是否启用加密 true
transport.useCompression 是否启用压缩 true

启动与管理

启动命令

Bash
# 服务端启动
./frps -c ./frps.toml

# 后台启动
nohup ./frps -c frps.toml > /dev/null 2>&1 &

# 客户端启动
./frpc -c ./frpc.toml

# 后台启动
nohup ./frpc -c frpc.toml > /dev/null 2>&1 &

配置验证

Bash
1
2
3
4
5
# 验证服务端配置
./frps -c ./frps.toml --verify

# 验证客户端配置
./frpc -c ./frpc.toml --verify

热重载配置

Bash
1
2
3
4
5
# 通过 Web API 重载
curl http://127.0.0.1:5400/api/reload

# 查看状态
curl http://127.0.0.1:5400/api/status

Systemd 服务配置

frps.service(服务端)

INI
[Unit]
Description=Frp Server Service
After=network.target

[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/opt/frp/frps -c /opt/frp/frps.toml

[Install]
WantedBy=multi-user.target

frpc.service(客户端)

INI
[Unit]
Description=Frp Client Service
After=network.target

[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/opt/frp/frpc -c /opt/frp/frpc.toml

[Install]
WantedBy=multi-user.target

启用服务:

Bash
# 复制服务文件
cp frps.service /etc/systemd/system/
cp frpc.service /etc/systemd/system/

# 重载 systemd
systemctl daemon-reload

# 启用并启动
systemctl enable frps
systemctl start frps

systemctl enable frpc
systemctl start frpc

# 查看状态
systemctl status frps
systemctl status frpc

故障排查

检查连接状态

Bash
1
2
3
4
5
# 查看 Dashboard
curl http://127.0.0.1:5500

# 查看代理状态
curl http://127.0.0.1:5400/api/status

查看日志

Bash
# 实时日志
tail -f /var/log/frps.log
tail -f /var/log/frpc.log

# 最近错误
grep -i "error" /var/log/frps.log
grep -i "error" /var/log/frpc.log

# Systemd 日志
journalctl -u frps -n 50 --no-pager
journalctl -u frpc -n 50 --no-pager

测试连通性

Bash
1
2
3
4
5
6
# 测试服务端端口
telnet x.x.x.x 5000

# 测试代理
curl -I http://www.yourdomain.com
curl -I https://www.yourdomain.com

常见问题

问题 原因 解决
连接被拒绝 防火墙阻止 检查安全组规则
token 认证失败 token 不一致 检查服务端和客户端配置
域名无法访问 DNS 未解析 检查 DNS 配置
端口无法使用 端口被占用 检查端口占用情况
KCP 连接失败 端口冲突 检查 kcpBindPort 是否与 bindPort 相同

v0.66+ 新增功能检查

Bash
1
2
3
4
5
# 查看客户端唯一标识
curl http://127.0.0.1:5400/api/client/status

# 查看 Store 管理(内置存储)
curl http://127.0.0.1:5400/api/store/proxies

版本差异速查

配置格式对比

配置项 v0.27.0(INI) v0.66.0(TOML)
服务端端口 bind_port = 7000 bindPort = 5000
KCP 端口 kcp_bind_port = 7000 kcpBindPort = 5000
HTTP 端口 vhost_http_port = 80 vhostHTTPPort = 5080
认证 Token token = xxx auth.token = "xxx"
Dashboard 端口 dashboard_port = 7500 webServer.port = 5500
日志文件 log_file = ./frps.log log.to = "/var/log/frps.log"
自定义域名 custom_domains = a.com,b.com customDomains = ["a.com","b.com"]

v0.66.0 新增功能

功能 说明
clientID 客户端唯一标识,用于多客户端管理
enabled 代理启用/禁用开关
loadBalancer.group(HTTPS) HTTPS 负载均衡支持
tokenSource 动态令牌认证(OIDC 增强)
featureGates 功能开关机制
VirtualNet 虚拟网络(实验性)
metadatas / annotations 元数据和注解支持
新版 Dashboard 现代化 UI、暗黑模式