2026 frp 自建内网穿透:Docker 部署替代 ngrok 实现外网访问内网服务

1871 字
9 分钟
2026 frp 自建内网穿透:Docker 部署替代 ngrok 实现外网访问内网服务

你家里跑着 Jellyfin 影视库、Navidrome 音乐服务和一台 NAS,但在外面想访问它们的时候,被现实狠狠打了一拳——运营商没给公网 IP,你处在 CGNAT(运营商级 NAT)后面。

你试过 ngrok,免费版每分钟只让传 20 个请求,URL 还是随机的。你试过 Tailscale/ZeroTier,确实能连,但每个访问者都要装客户端。你甚至想过买一台有公网 IP 的 VPS 把所有服务搬上去,但钱包在抗议。

frp 就是来解决这个问题的。它是一个用 Go 语言编写的内网穿透代理服务器,GitHub 上 107k Star,是目前最流行的自建穿透方案。你只需要一台有公网 IP 的云服务器跑 frps(服务端),在家里的设备上跑 frpc(客户端),就能把内网服务安全地暴露到公网上。访问者不需要装任何东西,直接浏览器打开就能用。

而且 Go 语言的优势在这里体现得很明显——单二进制、零依赖、跨平台。不管你的 VPS 是 Linux 还是家里的树莓派、群晖 NAS,都能轻松跑起来。


一、frp 与其他穿透方案对比#

对比项frpngrokTailscaleCloudflare Tunnel
语言GoGoGoGo
价格免费开源免费额度少免费(个人)免费
自建可控✅ 完全可控❌ 依赖协调服务器⚠️ 依赖 Cloudflare
TCP/UDP 穿透✅ 支持❌ 仅 HTTP❌ 仅 HTTP(S)
客户端安装❌ 不需要❌ 不需要✅ 需安装❌ 不需要
配置灵活度⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
性能高(Go 原生)中等高(P2P 直连时)中等

简单结论: 如果追求极致灵活、完全可控,且需要 TCP/UDP 全协议支持,frp 是最优解Tailscale 适合设备间互联,ngrok 适合临时测试,Cloudflare Tunnel 适合 HTTP 服务但受 CF 政策约束。


二、frp 架构#

frp 有清晰的 C/S 架构:

     公网 VPS(有公网 IP)
     ┌─────────────────┐
     │ frps (服务端) │
     │ 端口 7000 │
     └────────┬────────┘
          
  ┌───────────────┼───────────────┐
  │ │ │
  ▼ ▼ ▼
┌────────┐ ┌────────────┐ ┌──────────────┐
│ frpc │ │ frpc │ │ 外部客户端 │
│ (家里)│ │ (办公室) │ │ (用户浏览器) │
└────────┘ └────────────┘ └──────────────┘
  
  
┌────────────┐
│ Jellyfin │
│ Navidrome │
│ SSH 服务 │
└────────────┘

工作流程:

  1. 家里的 frpc 主动连接 VPS 上的 frps(无需开放家庭端口)
  2. frps 在公网上监听指定端口
  3. 用户访问 VPS 的 IP:端口,frps 把流量转发到家里的 frpc
  4. frpc 再转发到对应的内网服务

三、Docker Compose 部署#

3.1 服务端部署(frps — 跑在 VPS 上)#

version: '3.8'
services:
frps:
image: snowdreamtech/frps:latest
container_name: frps
restart: unless-stopped
network_mode: host
volumes:
- ./frps.toml:/etc/frp/frps.toml

使用 network_mode: host 是因为 frp 需要绑定大量随机端口,用 bridge 网络会非常麻烦。

创建 frps.toml 配置文件:

bindPort = 7000
kcpBindPort = 7000 # 启用 KCP 加速
quicBindPort = 7000 # 启用 QUIC 协议
bindAddr = "0.0.0.0"
# 鉴权
auth.token = "你的强密码请替换"
# Dashboard 监控面板
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "你的管理密码请替换"
# 日志
log.to = "console"
log.level = "info"
log.maxDays = 3
# 允许的最大连接数
transport.maxPoolCount = 50
# 默认客户端端口范围(用于 TCP 穿透)
vhostHTTPPort = 8080 # HTTP 穿透统一端口
vhostHTTPSPort = 8443 # HTTPS 穿透统一端口

3.2 客户端部署(frpc — 跑在家庭内网设备上)#

version: '3.8'
services:
frpc:
image: snowdreamtech/frpc:latest
container_name: frpc
restart: unless-stopped
network_mode: host
volumes:
- ./frpc.toml:/etc/frp/frpc.toml

创建 frpc.toml 配置文件:

serverAddr = "你的VPS公网IP"
serverPort = 7000
auth.token = "和服务端一样的密码"
# ===== 代理配置 =====
# 穿透 SSH(22 端口)
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000 # 访问 VPS:6000 → SSH 到家里的机器
# 穿透 Jellyfin(HTTP 服务)
[[proxies]]
name = "jellyfin"
type = "http"
localIP = "127.0.0.1"
localPort = 8096
customDomains = ["jellyfin.你的域名.com"]
# 穿透 Navidrome(HTTP 服务)
[[proxies]]
name = "navidrome"
type = "http"
localIP = "127.0.0.1"
localPort = 4533
customDomains = ["music.你的域名.com"]

3.3 启动服务#

Terminal window
# VPS 上启动 frps
docker compose up -d
# 家里的机器上启动 frpc
docker compose up -d

启动后访问 http://你的VPS_IP:7500 就能看到 frp Dashboard 监控面板了。


四、配置详解#

4.1 代理类型#

类型用途示例
tcp任意 TCP 服务SSH、RDP、数据库、Minecraft
udp任意 UDP 服务DNS、游戏语音
httpWeb 服务JellyfinNavidromeHomepage
httpsHTTPS 服务需配置证书
stcp安全 TCP(P2P 直连)仅 frpc 之间可访问
xtcpP2P 穿透两端都用 frpc,不经过服务器中转

4.2 安全配置#

# frps.toml 安全相关
auth.token = "your-strong-random-token"
auth.additionalScopes = ["HeartBeats", "NewWorkConns"]
# TLS 加密(推荐开启)
transport.tls.force = true
# 限制客户端 IP
allowPorts = [
{ start = 6000, end = 6005 },
{ start = 7000, end = 7005 }
]

4.3 性能优化#

frps.toml
transport.maxPoolCount = 100
transport.tcpMux = true # TCP 多路复用
# frpc.toml 启用 KCP 加速
transport.protocol = "kcp" # 使用 KCP 替代 TCP,丢包率高时效果明显

KCP 协议在家庭网络丢包率高的情况下特别有效,可以显著降低延迟。如果网络质量好,默认的 TCP 协议就够用了。


五、实战场景#

场景 1:SSH 远程管理家里的 Linux 机器#

[[proxies]]
name = "ssh-home"
type = "tcp"
localIP = "192.168.1.100"
localPort = 22
remotePort = 6000

连接命令:ssh root@你的VPS_IP -p 6000

场景 2:暴露 Web 服务(配合 Caddy 反代)#

先在 VPS 上给 frp 的 HTTP 穿透配一个 Caddy 反代

jellyfin.你的域名.com {
reverse_proxy localhost:8080 # frps 的 vhostHTTPPort
}

frpc 配置:

[[proxies]]
name = "jellyfin-web"
type = "http"
localIP = "192.168.1.100"
localPort = 8096
customDomains = ["jellyfin.你的域名.com"]

场景 3:游戏服务器穿透(Minecraft)#

[[proxies]]
name = "minecraft"
type = "tcp"
localIP = "192.168.1.100"
localPort = 25565
remotePort = 25565

朋友直接连接 你的VPS_IP:25565,就像访问一台公网服务器一样。


六、Dashboard 监控#

frp 内置了 Web Dashboard,启动后访问 http://你的VPS_IP:7500

  • 总览:在线客户端数、代理数、流量统计
  • 代理状态:每个代理的在线状态、流量、延迟
  • 客户端列表:连接的 frpc 详情
  • 实时日志:查看连接日志

这对排查连接问题非常有用。


FAQ#

Q: frp 和 Tailscale 有什么区别? A: 核心区别在于连接方式。Tailscale 走的是 P2P 直连(基于 WireGuard),需要双方都安装客户端;frp 走的是服务器中转,客户端不需要安装任何东西。frp 适合暴露服务给非技术人员使用,Tailscale 适合你自己的设备组网。

Q: VPS 需要什么配置? A: frps 极其轻量,1核1GB 内存的 VPS 跑 frps 同时穿透 10 个服务毫无压力。带宽决定了访问速度——建议至少 5Mbps。

Q: 安全吗? A: frp 支持 Token 鉴权、TLS 加密传输、IP 白名单。建议:① 设置强 Token ② 开启 TLS ③ Dashboard 不要暴露到公网 ④ 定期更新版本。

Q: HTTP 穿透和 TCP 穿透怎么选? A: Web 服务(Jellyfin/Navidrome/Gitea)用 HTTP 穿透 + 域名访问;非 HTTP 服务(SSH/Minecraft/RDP)用 TCP 穿透 + 端口映射。

Q: 可以用 frp 穿透 RDP 远程桌面吗? A: 可以。用 TCP 类型穿透 3389 端口,然后在远程电脑上 mstsc /v:你的VPS_IP:remotePort 即可连接。

Q: frp 最新文档在哪里? A: 官方文档:https://gofrp.org/ 或直接看 GitHub 仓库 https://github.com/fatedier/frp (107k⭐)

Q: frp v2 有什么区别? A: frp v2 目前还在开发中(dev 分支),重构了配置格式,加入了更多企业级功能。目前生产环境建议使用 v1.x 稳定版。


frp 解决了自建服务”出不去”的核心痛点。下一篇我们来聊聊另一个 Go 写的反向代理神器——Traefik,它能自动发现 Docker 容器并自动配置 HTTPS。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
2026 frp 自建内网穿透:Docker 部署替代 ngrok 实现外网访问内网服务
https://www.kshare.top/posts/2026-frp-自建内网穿透docker-部署替代-ngrok/
作者
Kshare
发布于
2026-06-23
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
Kshare
Hello, I'm Kshare.
公告
站点已开启广告(类型:弹窗广告),给您带来的不便敬请谅解。如有更好的广告建议,欢迎发送邮件至 t9uzrz6u@anonaddy.me,感谢您的支持!
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
187
分类
9
标签
190
总字数
490,175
运行时长
0
最后活动
0 天前

文章目录