背景
家里或公司内网的机器没有公网 IP,外面想 SSH 进去、连 MySQL、访问内网 Web 系统——传统的方案是路由器做端口映射,或者买花生壳这种商业服务。frp(Fast Reverse Proxy)用一台有公网 IP 的 VPS 作为"中转",让任何内网服务"看起来"跑在公网 IP 上,部署简单,开源免费。
适用场景:
- 远程办公,需要从公网 SSH 进内网开发机
- 临时把内网 MySQL 暴露给第三方调试
- 异地访问家里的 NAS、摄像头、Git 服务
- 没有公网 IP 的云主机需要对外提供 Web 服务
前置知识:
- 一台有公网 IP 的 VPS(带宽建议 ≥ 5Mbps)
- Linux 基础(systemd、iptables)
- 一点网络常识(端口、TCP/UDP)
注意:frp 把内网服务"反向"暴露到公网,任何能连到 frps 端口的人都能访问。请务必:
- 使用
token 鉴权 - 配合
fail2ban 或 ACL 限制来源 IP - 暴露 SSH 等高危服务时启用
stcp/xtcp 加密模式
一、frp 工作原理
1
2
| [公网客户端] ──> frps (公网 VPS :7000) ──> frpc (内网机器)
↑ 中转、反向代理 ↑ 主动连接建立隧道
|
关键点:
- frps(server)跑在公网 VPS,监听
bind_port(默认 7000) - frpc(client)跑在内网机器,主动连到 frps,建立长连接
- 公网客户端访问
VPS_IP:remote_port,frps 把流量通过已建立的隧道转发给 frpc,再由 frpc 转发到内网的 local_ip:local_port
支持的代理类型(frp 0.20+):
| 类型 | 用途 | 备注 |
|---|
tcp | 纯 TCP 端口映射 | SSH、MySQL、Redis、自定义协议 |
udp | 纯 UDP 端口映射 | DNS、游戏、VoIP |
http | HTTP 应用 | 支持改 Host Header、basic auth |
https | HTTPS 应用 | 配合证书 |
stcp | 安全 TCP(需两边都跑 frpc) | 不在服务端暴露端口,访问者也需密钥 |
xtcp | 点对点穿透 | 流量不经过服务器中转,UDP 打洞 |
二、安装
2.1 下载二进制
frp 0.43.0(2022-02 发布,长期维护版本):
1
2
3
4
5
6
7
| # Linux x86_64
curl -O https://github.com/fatedier/frp/releases/download/v0.43.0/frp_0.43.0_linux_amd64.tar.gz
tar -zxvf frp_0.43.0_linux_amd64.tar.gz -C /usr/local/games
mv /usr/local/games/frp_0.43.0_linux_amd64 /usr/local/games/rp
# Windows 客户端
# https://github.com/fatedier/frp/releases/download/v0.43.0/frp_0.43.0_windows_amd64.zip
|
2024-05 更新提示:frp 已迭代到 0.60+,大版本(v0.50+)开始推 TOML 配置,0.43 仍是 INI 经典格式。本篇示例兼顾 0.43(INI)和 0.50+(TOML)。
2.2 Docker 部署
1
2
3
4
5
6
7
8
9
| # 服务端
docker run -d --restart=always --network host \
-v /etc/frp/frps.ini:/etc/frp/frps.ini \
--name frps snowdreamtech/frps
# 客户端
docker run -d --restart=always --network host \
-v /etc/frp/frpc.ini:/etc/frp/frpc.ini \
--name frpc snowdreamtech/frpc
|
--network host 让 frpc 直接监听内网服务端口,避免 Docker 端口映射的复杂性。
三、配置详解(INI 经典格式)
3.1 服务端 frps.ini
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| [common]
bind_addr = 0.0.0.0
bind_port = 7000
# 鉴权令牌,客户端必须一致
token = your_strong_token_here
# Dashboard 端口(可选,浏览器看连接状态)
dashboard_port = 7500
dashboard_user = admin
dashboard_pwd = your_dashboard_pwd
# 日志
log_file = /var/log/frps.log
log_level = info
log_max_days = 7
# 允许的端口范围(防止被滥用)
allow_ports = 2000-3000,5000-6000,6000-10000
|
关键参数:
token 必设,防止别人白嫖你的 VPSallow_ports 限制客户端能使用的 remote_port 段dashboard_port 默认关闭,开启后通过浏览器看连接状态
3.2 客户端 frpc.ini(内网机器)
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
| [common]
server_addr = x.x.x.x # frps 的公网 IP
server_port = 7000
token = your_strong_token_here
# SSH 暴露
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 6000
# MySQL 暴露
[mysql]
type = tcp
local_ip = 127.0.0.1
local_port = 3306
remote_port = 3307
# Web 服务(HTTP 代理)
[web]
type = http
local_port = 8080
local_ip = 127.0.0.1
custom_domains = your.domain.com
locations = /
# 加密模式(推荐用于敏感服务)
[secret_ssh]
type = stcp
# 只有知道 sk 的人才能连
sk = abcdefgh
local_ip = 127.0.0.1
local_port = 22
|
四、HTTPS / Web 应用场景
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
| # frps.ini(服务端)
[common]
bind_addr = 0.0.0.0
bind_port = 7000
vhost_http_port = 80
vhost_https_port = 443
token = your_strong_token_here
# frpc.ini(客户端)
[common]
server_addr = x.x.x.x
server_port = 7000
token = your_strong_token_here
[blog]
type = http
local_port = 3000
local_ip = 127.0.0.1
custom_domains = blog.example.com
[wiki]
type = https
local_port = 443
local_ip = 127.0.0.1
custom_domains = wiki.example.com
|
注意:域名解析到 frps 的公网 IP,frps 根据 custom_domains 路由到不同 frpc。
五、systemd 守护(推荐生产方式)
5.1 服务端 /etc/systemd/system/rps.service
1
2
3
4
5
6
7
8
9
10
11
12
13
| [Unit]
Description = frp server
After = network.target syslog.target
Wants = network.target
[Service]
Type = simple
ExecStart = /usr/local/games/rp/frps -c /usr/local/games/rp/frps.ini
Restart = always
RestartSec = 5s
[Install]
WantedBy = multi-user.target
|
5.2 客户端 /etc/systemd/system/rpc.service
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| [Unit]
Description = frp client
After = network.target
Wants = network.target
[Service]
Type = simple
ExecStart = /usr/local/games/rp/frpc -c /usr/local/games/rp/frpc.ini
Restart = always
RestartSec = 20s
User = nobody
[Install]
WantedBy = multi-user.target
|
1
2
3
4
| systemctl daemon-reload
systemctl enable --now rps # 服务端
systemctl enable --now rpc # 客户端
systemctl status rpc
|
5.3 验证连接
1
2
3
| # 从公网客户端访问
ssh -p 6000 root@<vps-public-ip>
# 实际上等同于 SSH 进内网机器的 22 端口
|
六、TOML 格式(frp 0.50+)
frp 0.50+ 推荐 TOML:
1
2
3
4
5
6
7
8
9
| # frps.toml
bindAddr = "0.0.0.0"
bindPort = 7000
auth.method = "token"
auth.token = "your_strong_token_here"
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "your_dashboard_pwd"
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000
auth.method = "token"
auth.token = "your_strong_token_here"
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000
[[proxies]]
name = "mysql"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3306
remotePort = 3307
|
七、批量部署多个内网机器
假设一台公网 VPS 暴露多个内网客户的 MySQL/SSH:
1
2
3
4
5
6
7
8
9
10
11
12
13
| # 客户端 A(客户 A)
[mysql]
type = tcp
local_ip = 127.0.0.1
local_port = 3306
remote_port = 6101
# 客户端 B(客户 B)
[mysql]
type = tcp
local_ip = 127.0.0.1
local_port = 3306
remote_port = 6102
|
配合 fail2ban:因为所有 frpc 看到的来源都是 127.0.0.1,必须在 frps 端 配置 fail2ban,按 frps 日志里的真实 IP 拉黑。
1
2
3
4
| # /etc/fail2ban/filter.d/frps.conf
[Definition]
failregex = ^.*get a user connection \[<HOST>:[0-9]*\]
ignoreregex = ^.*\[.*gateway.*
|
八、常见问题
8.1 连接后立即断开
- 检查 VPS 的
7000 和 remote_port 是否在安全组/防火墙开放 - 客户端
server_addr 写错(写成了内网 IP) token 不一致
8.2 速度慢
- frp 走 TCP 中转,带宽 =
min(VPS 上行, frpc 上行) - 加密模式
stcp/xtcp 略增加 CPU 消耗 - 大文件传输考虑
rclone + 临时公网 OSS
8.3 0.50+ 升级后 INI 不识别
frp 0.50 删除了对 INI 的支持,统一 TOML。用 v0.43.0 仍是 INI,v0.52.3 之后基本 TOML 化。
九、卸载
1
2
3
4
5
6
| systemctl stop rpc
systemctl disable rpc
rm -rf /etc/systemd/system/rpc.service
rm -rf /usr/local/games/rp
systemctl daemon-reload
systemctl reset-failed rpc
|
小结
frp 0.20~0.43 是经典 INI 时代,0.50+ 切到 TOML,核心架构没变:主动连接 + 长隧道 + 端口映射。生产部署三个要点:
- 必设
token,避免被白嫖 - 配合 fail2ban,按 frps 日志真实 IP 拉黑攻击者
- systemd 守护 +
Restart=always,客户端断开自动重连
下一步:
- 把 frps 配合
nginxWebUI 做证书自动续期(HTTP 代理场景) - 用
stcp/xtcp 加密模式暴露 SSH - 高敏感服务用
WireGuard 替代 frp(点对点,无中转)
2024 视角:frp 0.59+ 在云原生时代的"角色变化"
2017 那篇 frp 是"内网穿透神器"。2024 视角下,frp 仍是经典,但有 3 个新选择更激进。
一、frp 版本进化(2024 主流)
- frp 0.59+(2024-06 起持续更新):全面 TOML 化,INI 已被废弃。
- 新特性:
- WebSocket over TLS(2024):WSS 模式走 443 端口,能穿透企业防火墙
- QUIC 协议(实验性):UDP 传输,比 TCP 模式延迟低 20%
- 带宽限制 / 速率统计:精确控制客户端带宽
- 多 frpc 共享 frps:跨 NAT 设备互联
1
2
3
4
5
6
7
8
9
10
11
12
| # frps.toml (0.59+)
bindAddr = "0.0.0.0"
bindPort = 7000
auth.method = "token"
auth.token = "your_strong_token"
# 启用 WSS(重要:能穿透企业防火墙)
transport.websocket.enable = true
transport.websocket.url = "/_frp_ws"
# 启用 QUIC(2024 新)
transport.quic.enable = true
|
二、Cloudflare Tunnel——2024 主流替代
- Cloudflare Tunnel(cloudflared):不需要公网 VPS——Cloudflare 边缘做"中转"。
1
2
3
4
5
6
7
8
9
10
11
12
| # 装
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared focal main' | sudo tee /etc/apt/sources.list.d/cloudflared.list
apt update && apt install cloudflared
# 登录
cloudflared tunnel login
cloudflared tunnel create my-tunnel
cloudflared tunnel route dns my-tunnel myapp.example.com
# 启动(后台)
cloudflared tunnel --config /etc/cloudflared/config.yml run my-tunnel
|
1
2
3
4
5
6
7
8
| # /etc/cloudflared/config.yml
tunnel: my-tunnel
credentials-file: /root/.cloudflared/xxxxxx.json
ingress:
- hostname: myapp.example.com
service: http://localhost:3000
- service: http_status:404
|
- 优势:
- 不需要公网 VPS(Cloudflare 边缘免费)
- 零暴露端口(只用 HTTPS 443 出站)
- Cloudflare 整套生态:CDN / WAF / DDoS 防护 / 零信任鉴权
- 免费 50 个 tunnel / 1000 次请求/秒
- 2024 大量新项目用 Cloudflare Tunnel 替代 frp。
三、Tailscale —— “点对点 VPN” 替代内网穿透
2017 那篇 frp 是"反代中转"。2024 主流是 P2P VPN:
1
2
3
4
| # 装 Tailscale
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up
# 自动获得 100.x.x.x 虚拟 IP
|
- Tailscale SSH 替代 SSH 隧道:
- 不需要公网 IP
- 不需要 frp 中转
- 鉴权走 Tailscale ACL(不是 SSH 公私钥)
1
2
3
4
| # 直接 SSH 任何 Tailscale 设备
ssh user@machine-name
# Tailscale 自动协商点对点连接(UDP 打洞)
# 如果 P2P 失败,自动 fallback 到 Tailscale DERP 中转(仍比 frp 简单)
|
- Tailscale ACL(基于 WireGuard):
1
2
3
4
5
6
7
8
9
10
| // tailscale ACL
{
"acls": [
{
"action": "accept",
"src": ["group:dev"],
"dst": ["tag:prod-server:22"]
}
]
}
|
四、frp 在 K8s 时代的"角色"
- 2024 趋势:K8s 项目用 Ingress + Cloudflare Tunnel 替代 frp。
- frp 仍在用的场景:
- 自建机房(无 Cloudflare)
- 临时调试(1 小时建一个隧道)
- 边缘设备(IoT / 工厂)
- 企业内网(不能用 Cloudflare)
五、frp 安全加固的"现代"姿势
2017 那篇给 token 鉴权。2024 升级:
1
2
3
4
5
6
7
8
9
10
| # frps.toml - 强认证
auth.method = "token"
auth.token = "<random-32-chars>"
auth.additionalScopes = ["Heartbeat"]
# TLS 加密(防中间人)
transport.tls.force = true
# 限速(防滥用)
transport.maxPoolCount = 5
|
1
2
3
4
5
6
7
| # frpc.toml - 强认证
auth.method = "token"
auth.token = "<random-32-chars>"
# 多重 TLS
transport.tls.enable = true
transport.tls.disableCustomTLSFirstByte = false
|
六、frp 性能优化
- 2024 实测:frp 0.59+ 在 1Gbps 内网下,单 tunnel 可达 800+ Mbps(TCP 直连)。
- 多 tunnel 负载(frp 0.59+):
1
2
3
4
5
6
7
| [[proxies]]
name = "web1"
type = "tcp"
localPort = 80
remotePort = 8080
# 启用多路复用
transport.bandwidthLimit = "100MB"
|
- QUIC 协议(2024 实验):减少握手延迟(首次连接 0-RTT)。
七、frp 的"替代品"对比(2024)
| 工具 | 架构 | 适用 |
|---|
| frp | 客户端-服务器 | 自建 VPS、临时穿透 |
| Cloudflare Tunnel | 客户端-Cloudflare 边缘 | 不需要 VPS、零信任 |
| Tailscale | P2P(WireGuard) | 长期组网、家庭 / 远程办公 |
| ZeroTier | P2P + Controller | 多平台、大规模 |
| nps(国产) | 客户端-服务器 | 国内网络、简单场景 |
| lanproxy(国产) | Java 写 | 简单 Java 项目集成 |
| rathole(2022+) | Rust 写 | 性能敏感、嵌入式 |
| bore(Rust) | 极简 | 个人项目、临时调试 |
八、frp + Cloudflare Tunnel 的"混合"
- 2024 一些项目同时用 frp + Cloudflare Tunnel:
- frp 做"内网到 VPS"的隧道
- Cloudflare Tunnel 做"VPS 到公网"的暴露
- 效果:VPS 的 IP 永远不暴露(Cloudflare 边缘代为接受流量)
九、AI 时代的"运维代理"
- 2024 LLM 时代:AI Agent(如 Claude Code / Devin)需要 SSH 访问内网服务器。
- Tailscale / Cloudflare Tunnel 让 AI Agent 不需要公网 IP 就能访问内网。
- 未来:frp 在 AI Agent 场景会"云化"——AI Agent 通过 Tunnel 远程执行命令。
源文档:
os/linux/第三方tools/net/frp/内网穿透.md(内网穿透场景、systemd 模板、Docker 部署)os/linux/第三方tools/net/frp/frp.md(多客户端批量配置、fail2ban 集成、TOML 新格式)