本教程将指导你完整部署 frp(fast reverse proxy)内网穿透工具,包括服务端和客户端的安装与配置。内容基于 frp 官方项目整理,涵盖多种实用场景和最佳实践。
Table of contents
Open Table of contents
frp 简介
frp 是一个高性能的反向代理应用,可以帮助你将位于 NAT 或防火墙后的本地服务暴露到公网。它支持 TCP、UDP、HTTP 和 HTTPS 等多种协议,还提供了 P2P 连接模式。
主要特性
- 支持多种协议:TCP、UDP、HTTP、HTTPS
- 支持域名路由和 URL 路由
- 支持加密和压缩传输
- 支持负载均衡和健康检查
- 提供 Web 管理界面
- 支持 P2P 直连模式
- 支持插件扩展
应用场景
- 远程访问家庭或办公室内网设备
- 临时展示本地开发的 Web 应用
- 为本地服务提供公网访问能力
- 搭建私有云服务
- 游戏联机、远程桌面等
架构说明
frp 采用 C/S 架构,主要包含两个组件:
- frps(服务端):部署在具有公网 IP 的服务器上,负责接收客户端连接和转发流量
- frpc(客户端):部署在内网机器上,负责将本地服务暴露到公网
工作流程:
- frpc 连接到 frps 并建立控制连接
- 用户访问 frps 的公网地址
- frps 通过控制连接通知 frpc 建立新的工作连接
- frpc 建立工作连接并转发流量到本地服务
- 流量在 frps 和 frpc 之间双向传输
第一步:下载 frp
获取最新版本
访问 frp Releases 页面下载适合你操作系统和架构的版本。
Linux 系统下载示例
# 下载最新版本(以 v0.62.0 为例,请根据实际情况调整版本号)
wget https://github.com/fatedier/frp/releases/download/v0.62.0/frp_0.62.0_linux_amd64.tar.gz
# 解压
tar -xzf frp_0.62.0_linux_amd64.tar.gz
# 进入目录
cd frp_0.62.0_linux_amd64
Windows 系统下载
下载对应的 Windows 版本(如 frp_0.62.0_windows_amd64.zip),解压后即可使用。
文件说明
解压后的目录包含以下主要文件:
frps:服务端可执行文件(Linux)frps.exe:服务端可执行文件(Windows)frpc:客户端可执行文件(Linux)frpc.exe:客户端可执行文件(Windows)frps.toml:服务端配置文件示例frpc.toml:客户端配置文件示例
注意:部分杀毒软件可能会误报 frpc 为恶意软件并删除。这是因为 frp 作为网络工具具有创建反向代理的能力,可能被误判。如果遇到此问题,请在杀毒软件中将 frpc 添加到白名单。
第二步:部署服务端(frps)
服务端需要部署在具有公网 IP 的服务器上(如云服务器)。
基础配置
创建服务端配置文件 frps.toml:
# frps.toml
# 客户端连接端口
bindPort = 7000
这是最简单的配置,frps 将在 7000 端口监听客户端连接。
启动服务端
./frps -c ./frps.toml
完整配置示例
# frps.toml
# 客户端连接端口
bindPort = 7000
# HTTP 虚拟主机端口
vhostHTTPPort = 8080
# HTTPS 虚拟主机端口
vhostHTTPSPort = 8443
# TCP 多路复用 HTTP CONNECT 端口
tcpmuxHTTPConnectPort = 5002
# KCP 协议绑定端口(可选)
kcpBindPort = 7000
# QUIC 协议绑定端口(可选)
quicBindPort = 7000
# SSH 隧道网关端口(可选)
sshTunnelGateway.bindPort = 2200
# 限制允许的端口范围
allowPorts = [
{ start = 2000, end = 3000 },
{ single = 3001 },
{ single = 3003 },
{ start = 4000, end = 50000 }
]
# 子域名配置
subDomainHost = "frps.com"
# Web 管理界面
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"
# 启用 Prometheus 监控
enablePrometheus = true
# 身份验证
auth.method = "token"
auth.token = "your_secure_token_here"
# TLS 配置
transport.tls.force = true
transport.tls.certFile = "server.crt"
transport.tls.keyFile = "server.key"
配置说明
bindPort:客户端连接的主端口vhostHTTPPort:HTTP 服务的虚拟主机端口vhostHTTPSPort:HTTPS 服务的虚拟主机端口allowPorts:限制客户端可以使用的端口范围,防止滥用subDomainHost:子域名后缀,配合客户端的 subdomain 使用webServer:Web 管理界面配置auth.token:客户端连接的认证令牌,建议设置强密码
配置 systemd 服务(Linux)
创建服务文件 /etc/systemd/system/frps.service:
[Unit]
Description=frp server
After=network.target
[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/bin/frps -c /etc/frp/frps.toml
[Install]
WantedBy=multi-user.target
安装并启动服务:
# 复制文件到系统目录
sudo mkdir -p /etc/frp
sudo cp frps.toml /etc/frp/
sudo cp frps /usr/local/bin/
# 启动服务
sudo systemctl daemon-reload
sudo systemctl start frps
sudo systemctl enable frps
# 查看状态
sudo systemctl status frps
使用 Docker 部署(可选)
docker run -d \
--name frps \
--restart=always \
-p 7000:7000 \
-p 8080:8080 \
-p 7500:7500 \
-v /path/to/frps.toml:/etc/frp/frps.toml \
fatedier/frp:latest \
frps -c /etc/frp/frps.toml
第三步:部署客户端(frpc)
客户端部署在需要暴露服务的内网机器上。
基础配置
创建客户端配置文件 frpc.toml:
# frpc.toml
# 服务端地址(替换为你的服务器公网 IP)
serverAddr = "x.x.x.x"
serverPort = 7000
# 身份验证(需与服务端配置一致)
auth.method = "token"
auth.token = "your_secure_token_here"
# SSH 代理示例
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
启动客户端
./frpc -c ./frpc.toml
配置 systemd 服务(Linux)
创建服务文件 /etc/systemd/system/frpc.service:
[Unit]
Description=frp client
After=network.target
[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/bin/frpc -c /etc/frp/frpc.toml
[Install]
WantedBy=multi-user.target
安装并启动服务:
# 复制文件到系统目录
sudo mkdir -p /etc/frp
sudo cp frpc.toml /etc/frp/
sudo cp frpc /usr/local/bin/
# 启动服务
sudo systemctl daemon-reload
sudo systemctl start frpc
sudo systemctl enable frpc
# 查看状态
sudo systemctl status frpc
常见使用场景
场景一:SSH 远程访问
通过 frp 实现远程 SSH 访问内网机器。
客户端配置:
serverAddr = "x.x.x.x"
serverPort = 7000
auth.method = "token"
auth.token = "your_secure_token_here"
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
连接方式:
ssh -p 6000 user@x.x.x.x
场景二:Web 服务访问
将内网 Web 服务通过域名暴露到公网。
服务端配置:
bindPort = 7000
vhostHTTPPort = 8080
subDomainHost = "example.com"
客户端配置:
serverAddr = "x.x.x.x"
serverPort = 7000
[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["www.example.com"]
# 或使用子域名
# subdomain = "myapp"
DNS 配置:
- 将
www.example.com的 A 记录指向服务器公网 IP - 或将
*.example.com的泛解析指向服务器公网 IP
访问方式:
http://www.example.com:8080
场景三:HTTPS 服务
为本地 HTTP 服务启用 HTTPS。
客户端配置:
serverAddr = "x.x.x.x"
serverPort = 7000
[[proxies]]
name = "web_https"
type = "https"
customDomains = ["secure.example.com"]
[proxies.plugin]
type = "https2http"
localAddr = "127.0.0.1:80"
crtPath = "./server.crt"
keyPath = "./server.key"
hostHeaderRewrite = "127.0.0.1"
场景四:远程桌面(RDP)
暴露 Windows 远程桌面服务。
客户端配置:
serverAddr = "x.x.x.x"
serverPort = 7000
[[proxies]]
name = "rdp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3389
remotePort = 7001
连接方式:使用远程桌面客户端连接到 x.x.x.x:7001
场景五:文件服务器
快速搭建一个简单的文件服务器。
客户端配置:
serverAddr = "x.x.x.x"
serverPort = 7000
[[proxies]]
name = "file_server"
type = "tcp"
remotePort = 6001
[proxies.plugin]
type = "static_file"
localPath = "/path/to/files"
stripPrefix = "static"
httpUser = "admin"
httpPassword = "admin"
访问方式:
http://x.x.x.x:6001/static/
场景六:私密服务(STCP)
使用预共享密钥保护服务,只有知道密钥的客户端才能访问。
服务提供方(机器 A)配置:
serverAddr = "x.x.x.x"
serverPort = 7000
[[proxies]]
name = "secret_ssh"
type = "stcp"
secretKey = "your_secret_key"
localIP = "127.0.0.1"
localPort = 22
访问方(机器 B)配置:
serverAddr = "x.x.x.x"
serverPort = 7000
[[visitors]]
name = "secret_ssh_visitor"
type = "stcp"
serverName = "secret_ssh"
secretKey = "your_secret_key"
bindAddr = "127.0.0.1"
bindPort = 6000
在机器 B 上连接:
ssh -p 6000 127.0.0.1
场景七:P2P 模式(XTCP)
实现客户端之间的 P2P 直连,减少服务器流量消耗。
服务提供方配置:
serverAddr = "x.x.x.x"
serverPort = 7000
[[proxies]]
name = "p2p_ssh"
type = "xtcp"
secretKey = "p2p_secret"
localIP = "127.0.0.1"
localPort = 22
访问方配置:
serverAddr = "x.x.x.x"
serverPort = 7000
[[visitors]]
name = "p2p_ssh_visitor"
type = "xtcp"
serverName = "p2p_ssh"
secretKey = "p2p_secret"
bindAddr = "127.0.0.1"
bindPort = 6000
keepTunnelOpen = false
注意:P2P 模式可能不适用于所有类型的 NAT 设备。如果 XTCP 不工作,可以回退到 STCP 模式。
高级功能
负载均衡
多个客户端共享同一个端口,实现负载均衡。
客户端 1 配置:
[[proxies]]
name = "web1"
type = "tcp"
localPort = 8080
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "your_group_key"
客户端 2 配置:
[[proxies]]
name = "web2"
type = "tcp"
localPort = 8080
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "your_group_key"
健康检查
自动检测服务健康状态,故障时自动移除代理。
TCP 健康检查:
[[proxies]]
name = "web"
type = "tcp"
localPort = 8080
remotePort = 80
healthCheck.type = "tcp"
healthCheck.timeoutSeconds = 3
healthCheck.maxFailed = 3
healthCheck.intervalSeconds = 10
HTTP 健康检查:
[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["www.example.com"]
healthCheck.type = "http"
healthCheck.path = "/health"
healthCheck.timeoutSeconds = 3
healthCheck.maxFailed = 3
healthCheck.intervalSeconds = 10
带宽限制
限制单个代理的带宽使用。
[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000
transport.bandwidthLimit = "1MB"
transport.bandwidthLimitMode = "client"
加密和压缩
启用传输加密和压缩。
[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000
transport.useEncryption = true
transport.useCompression = true
URL 路由
根据 URL 路径将请求转发到不同的后端服务。
[[proxies]]
name = "web01"
type = "http"
localPort = 80
customDomains = ["web.example.com"]
locations = ["/"]
[[proxies]]
name = "web02"
type = "http"
localPort = 81
customDomains = ["web.example.com"]
locations = ["/api", "/admin"]
访问 /api 或 /admin 的请求会转发到 web02,其他请求转发到 web01。
环境变量
在配置文件中使用环境变量。
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 }}
使用方式:
export FRP_SERVER_ADDR=x.x.x.x
export FRP_SSH_REMOTE_PORT=6000
./frpc -c ./frpc.toml
热重载配置
frpc 支持热重载配置,无需重启进程。
首先在配置文件中启用 Web 服务器:
webServer.addr = "127.0.0.1"
webServer.port = 7400
修改配置后执行:
./frpc reload -c ./frpc.toml
验证配置:
./frpc verify -c ./frpc.toml
查看代理状态:
./frpc status -c ./frpc.toml
安全建议
1. 使用强认证令牌
auth.method = "token"
auth.token = "use_a_very_strong_random_token_here"
生成强随机令牌:
openssl rand -base64 32
2. 启用 TLS 加密
服务端配置:
transport.tls.force = true
transport.tls.certFile = "server.crt"
transport.tls.keyFile = "server.key"
客户端配置:
transport.tls.enable = true
transport.tls.trustedCaFile = "ca.crt"
3. 限制端口范围
在服务端限制客户端可以使用的端口:
allowPorts = [
{ start = 6000, end = 6100 }
]
4. 使用防火墙
在服务器上配置防火墙,只开放必要的端口:
# 允许 frps 端口
sudo ufw allow 7000/tcp
sudo ufw allow 8080/tcp
sudo ufw allow 7500/tcp
sudo ufw enable
5. 定期更新
定期检查并更新到最新版本,以获得安全修复和新功能。
6. 监控和日志
启用日志记录,定期检查异常访问:
# 服务端日志配置
log.to = "/var/log/frps.log"
log.level = "info"
log.maxDays = 7
故障排查
客户端无法连接到服务端
-
检查服务端是否正常运行:
sudo systemctl status frps -
检查防火墙是否开放端口:
sudo ufw status -
检查认证令牌是否一致
-
查看日志:
sudo journalctl -u frps -f sudo journalctl -u frpc -f
代理无法访问
-
检查端口是否被占用:
netstat -tuln | grep 端口号 -
检查本地服务是否正常运行
-
检查 DNS 解析是否正确(HTTP/HTTPS 代理)
-
检查防火墙规则
连接不稳定
-
启用 KCP 或 QUIC 协议:
transport.protocol = "kcp" -
启用连接池:
transport.poolCount = 5 -
调整心跳参数:
transport.heartbeatInterval = 30 transport.heartbeatTimeout = 90
性能问题
-
启用 TCP 多路复用:
transport.tcpMux = true -
禁用加密和压缩(如果不需要):
transport.useEncryption = false transport.useCompression = false -
使用 P2P 模式减少服务器负载
Web 管理界面
服务端 Dashboard
访问 http://服务器IP:7500,使用配置的用户名和密码登录。
Dashboard 功能:
- 查看所有在线客户端
- 查看所有活动代理
- 查看流量统计
- 查看连接状态
客户端 Admin UI
在客户端配置中启用:
webServer.addr = "127.0.0.1"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "admin"
访问 http://127.0.0.1:7400 查看客户端状态。
Prometheus 监控
在服务端启用 Prometheus:
enablePrometheus = true
访问 http://服务器IP:7500/metrics 获取监控数据。
配置文件格式
frp 从 v0.52.0 开始支持 TOML、YAML 和 JSON 格式的配置文件。INI 格式已被弃用。
TOML 格式(推荐)
serverAddr = "x.x.x.x"
serverPort = 7000
[[proxies]]
name = "ssh"
type = "tcp"
localPort = 22
remotePort = 6000
YAML 格式
serverAddr: x.x.x.x
serverPort: 7000
proxies:
- name: ssh
type: tcp
localPort: 22
remotePort: 6000
JSON 格式
{
"serverAddr": "x.x.x.x",
"serverPort": 7000,
"proxies": [
{
"name": "ssh",
"type": "tcp",
"localPort": 22,
"remotePort": 6000
}
]
}
总结
frp 是一个功能强大且易于使用的内网穿透工具,适用于各种场景。本教程涵盖了从基础安装到高级配置的完整流程。建议根据实际需求选择合适的配置,并注意安全防护。
关键要点:
- 服务端部署在公网服务器,客户端部署在内网机器
- 使用强认证令牌和 TLS 加密保护连接
- 根据场景选择合适的代理类型(TCP、HTTP、HTTPS、STCP、XTCP)
- 利用负载均衡和健康检查提高可用性
- 定期更新和监控系统状态
更多信息请参考:
内容基于 frp 官方文档改编,遵循 Apache License, Version 2.0。