背景

在日常开发和运维工作中,我们经常会遇到这样的场景:

  • 在家需要访问公司内网的开发服务器
  • 需要将本地开发的小程序或 Web 应用暴露给外部测试
  • 远程访问部署在家庭网络的 NAS 或树莓派
  • 将内网的 Windows 远程桌面服务暴露给外部访问

这些场景的共同特点是:你的服务在内网中,没有公网 IP,无法直接从互联网访问

传统的解决方案包括花生壳、Ngrok 等第三方服务,但它们往往有诸多限制:

方案 限制
花生壳 免费版带宽有限,需要付费才能获得更多功能
Ngrok 免费版只能访问随机生成的 URL,不支持自定义域名
花生壳 服务不稳定,安全性无法保证
商业 VPN 配置复杂,成本高昂

今天要介绍的 frp (Fast Reverse Proxy) 完美解决了这些问题,让你拥有完全可控、稳定、高效的内网穿透系统。

什么是 frp

frp 是一个开源的高性能反向代理工具,通过客户端-服务器架构,将内网服务安全地暴露到公网。

核心特性

特性 说明
多协议支持 支持 TCP、UDP、HTTP、HTTPS、SOCKS5 等协议
简单配置 仅需一个配置文件即可完成穿透设置
高性能 支持 TCP 流复用、KCP、QUIC 等加速协议
安全可靠 支持 TLS 加密、Token 认证、OIDC 认证
热更新 支持在不重启服务的情况下更新配置
Web 仪表盘 提供可视化的服务监控和管理界面
P2P 模式 支持点对点直连,大幅降低服务器带宽消耗
插件扩展 提供丰富的插件支持静态文件、HTTP 代理等

GitHub 数据

  • Star: 97.4K
  • 语言: Go
  • 协议: Apache-2.0
  • 维护: 活跃维护中

工作原理

┌─────────────┐      ┌─────────────┐      ┌─────────────┐
│   用户端     │ ---> │   frps      │ ---> │   frpc      │
│  (公网)     │      │  (服务器)    │      │  (内网)     │
└─────────────┘      └─────────────┘      └─────────────┘
                                             │
                                             v
                                        ┌─────────────┐
                                        │  内网服务    │
                                        │  (SSH/Web)  │
                                        └─────────────┘
  1. frps (Server): 部署在有公网 IP 的服务器上,作为中转桥梁
  2. frpc (Client): 部署在需要暴露的内网机器上,建立到 frps 的连接
  3. 用户通过访问 frps 的公网地址,间接访问到内网服务

快速开始

安装

GitHub Release 页面下载对应平台的二进制文件:

# 下载 (Linux AMD64 为例)
wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
tar -xzf frp_0.61.1_linux_amd64.tar.gz
cd frp_0.61.1_linux_amd64

# 服务器端文件
ls frps*

# 客户端文件
ls frpc*

服务器端配置

编辑 frps.toml

# frps.toml - 服务器配置
bindPort = 7000              # frpc 连接的端口

# Web 仪表盘 (可选)
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"

# 允许使用的端口范围 (可选)
allowPorts = [
  { start = 2000, end = 3000 },
  { single = 3001 },
  { start = 4000, end = 50000 }
]

启动服务器:

./frps -c ./frps.toml

客户端配置

编辑 frpc.toml

# frpc.toml - 客户端配置
serverAddr = "你的服务器IP"
serverPort = 7000

# 认证配置 (与服务器一致)
auth.method = "token"
auth.token = "your_token_here"

[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6000

启动客户端:

./frpc -c ./frpc.toml

SSH 远程访问

配置完成后,即可通过服务器 IP 访问内网 SSH:

ssh -oPort=6000 用户名@服务器IP

核心功能详解

1. HTTP/HTTPS 服务暴露

将内网 Web 服务通过自定义域名暴露到公网:

服务器端配置:

# frps.toml
bindPort = 7000
vhostHTTPPort = 8080
vhostHTTPSPort = 8443
subDomainHost = "example.com"

客户端配置:

# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "web"
type = "http"
localPort = 80
customDomains = ["www.example.com"]

[[proxies]]
name = "api"
type = "http"
localPort = 8080
customDomains = ["api.example.com"]
locations = ["/api"]

DNS 配置:
www.example.comapi.example.com 的 A 记录解析到服务器 IP。

2. 保护敏感服务 (STCP)

对于敏感服务,可以使用 Secret TCP 模式,需要预共享密钥才能访问:

服务端 (机器 B):

# frpc.toml
[[proxies]]
name = "secret_ssh"
type = "stcp"
secretKey = "abcdefg"
localIP = "127.0.0.1"
localPort = 22

访问端 (机器 C):

# frpc.toml
[[visitors]]
name = "secret_ssh_visitor"
type = "stcp"
serverName = "secret_ssh"
secretKey = "abcdefg"
bindAddr = "127.0.0.1"
bindPort = 6000

访问时执行:

ssh -oPort=6000 user@127.0.0.1

3. P2P 直连模式 (XTCP)

用于传输大量数据的场景,数据直接在各户端之间传输,服务器只负责建立连接:

# frpc.toml (被访问端)
[[proxies]]
name = "p2p_ssh"
type = "xtcp"
secretKey = "abcdefg"
localIP = "127.0.0.1"
localPort = 22
# frpc.toml (访问端)
[[visitors]]
name = "p2p_ssh_visitor"
type = "xtcp"
serverName = "p2p_ssh"
secretKey = "abcdefg"
bindAddr = "127.0.0.1"
bindPort = 6000

4. TCP 端口复用

多个 SSH 服务共享同一端口,通过域名区分:

服务器端:

# frps.toml
bindPort = 7000
tcpmuxHTTPConnectPort = 5002

机器 A:

# frpc.toml
[[proxies]]
name = "ssh1"
type = "tcpmux"
multiplexer = "httpconnect"
customDomains = ["machine-a.example.com"]
localIP = "127.0.0.1"
localPort = 22

机器 B:

# frpc.toml
[[proxies]]
name = "ssh2"
type = "tcpmux"
multiplexer = "httpconnect"
customDomains = ["machine-b.example.com"]
localIP = "127.0.0.1"
localPort = 22

5. 插件功能

frp 提供丰富的插件扩展:

插件 用途
unix_domain_socket 暴露 Unix 域套接字
http_proxy HTTP 代理
socks5 SOCKS5 代理
static_file 静态文件服务器
https2http HTTPS 转 HTTP
https2https HTTPS 转 HTTPS

静态文件服务器示例:

[[proxies]]
name = "file_server"
type = "tcp"
remotePort = 6000
[proxies.plugin]
type = "static_file"
localPath = "/tmp/files"
stripPrefix = "static"
httpUser = "admin"
httpPassword = "admin"

6. 负载均衡

支持多个后端服务负载均衡:

[[proxies]]
name = "web1"
type = "tcp"
localPort = 8080
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "secret"

[[proxies]]
name = "web2"
type = "tcp"
localPort = 8081
remotePort = 80
loadBalancer.group = "web"
loadBalancer.groupKey = "secret"

7. 健康检查

支持服务健康检查,实现高可用:

[[proxies]]
name = "web"
type = "http"
localIP = "127.0.0.1"
localPort = 80
customDomains = ["web.example.com"]
healthCheck.type = "http"
healthCheck.path = "/status"
healthCheck.timeoutSeconds = 3
healthCheck.maxFailed = 3
healthCheck.intervalSeconds = 10

高级配置

TLS 加密

frp 默认启用 TLS,强制服务器端仅接受 TLS 连接:

# frps.toml
transport.tls.force = true
transport.tls.certFile = "server.crt"
transport.tls.keyFile = "server.key"

KCP 协议加速

使用 KCP 协议可以减少延迟 30-40%:

# frps.toml
bindPort = 7000
kcpBindPort = 7000
# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000
transport.protocol = "kcp"

QUIC 协议支持

QUIC 是基于 UDP 的新一代多路复用传输协议:

# frps.toml
bindPort = 7000
quicBindPort = 7000
# frpc.toml
transport.protocol = "quic"

连接池

预建立连接池,减少连接建立时间:

# frps.toml
transport.maxPoolCount = 5
# frpc.toml
transport.poolCount = 2

热更新配置

修改配置后无需重启客户端:

./frpc reload -c ./frpc.toml

端口范围映射

批量创建端口映射:

{{- range $_, $v := parseNumberRangePair "6000-6007" "6000-6007" }}
[[proxies]]
name = "tcp-{{ $v.First }}"
type = "tcp"
localPort = {{ $v.First }}
remotePort = {{ $v.Second }}
{{- end }}

实战场景

场景一:远程访问家中 NAS

假设你有一台群晖 NAS 部署在家庭网络,想要从外部访问:

# NAS 上的 frpc.toml
serverAddr = "你的服务器IP"
serverPort = 7000

[[proxies]]
name = "nasDSM"
type = "tcp"
localIP = "192.168.1.100"
localPort = 5000
remotePort = 5000

[[proxies]]
name = "nasSSH"
type = "tcp"
localIP = "192.168.1.100"
localPort = 22
remotePort = 2222

场景二:暴露本地开发环境

开发微信小程序或需要回调的 Web 应用时使用:

# frpc.toml
serverAddr = "你的服务器IP"
serverPort = 7000

[[proxies]]
name = "web"
type = "https"
customDomains = ["dev.yourdomain.com"]

[proxies.plugin]
type = "https2http"
localAddr = "127.0.0.1:8080"
crtPath = "./server.crt"
keyPath = "./server.key"
hostHeaderRewrite = "127.0.0.1"

场景三:Windows 远程桌面

# frpc.toml
serverAddr = "你的服务器IP"
serverPort = 7000

[[proxies]]
name = "rdp"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3389
remotePort = 3389
transport.useEncryption = true
transport.useCompression = true

场景四:搭建 SOCKS5 代理

通过服务器转发网络流量:

[[proxies]]
name = "socks5"
type = "tcp"
remotePort = 1080
[proxies.plugin]
type = "socks5"
httpUser = "user"
httpPassword = "password"

常见问题

Q1: frpc 被杀毒软件误删怎么办?

frp 是网络穿透工具,部分杀毒软件会将其误判为潜在有害程序。请在杀毒软件中将 frpc 添加到白名单。

Q2: 如何选择 TCP/KCP/QUIC 协议?

协议 适用场景
TCP 稳定可靠,兼容性最好
KCP 网络延迟高时,可提升 30-40% 速度
QUIC 需要低延迟和高吞吐量的场景

Q3: frp 和 VPN 有什么区别?

  • VPN: 建立虚拟网络,所有流量都走 VPN,适合长期办公场景
  • frp: 按需暴露特定端口和服务,资源消耗更小,配置更灵活

Q4: 如何保证传输安全?

  1. 启用 TLS 加密 (transport.tls.enable = true)
  2. 使用 Token 或 OIDC 认证
  3. 对敏感服务使用 STCP 模式 + 预共享密钥
  4. 使用 HTTP Basic Auth 保护 Web 服务

Q5: 连接不稳定怎么办?

  1. 检查服务器防火墙是否放行端口
  2. 尝试更换传输协议 (TCP → KCP/QUIC)
  3. 启用连接池和 TCP 流复用
  4. 检查网络 NAT 类型是否限制穿透

总结

frp 是一款功能强大、配置灵活的内网穿透工具,具有以下核心优势:

优势 说明
✅ 完全可控 自建服务,数据完全自主掌控
✅ 高性能 支持 KCP/QUIC 加速,TCP 流复用
✅ 多协议 TCP、UDP、HTTP、HTTPS、SOCKS5
✅ 安全可靠 TLS 加密、Token/OIDC 认证
✅ 功能丰富 负载均衡、健康检查、热更新
✅ 易于使用 配置文件简洁,学习成本低
✅ 活跃社区 97K+ Star,持续迭代更新

无论是远程访问家庭设备、暴露开发环境,还是搭建私有 VPN,frp 都能提供稳定、高效的解决方案。建议有相关需求的读者部署自己的 frp 服务,享受完全自主的内网穿透体验。


相关资源

  • GitHub: https://github.com/fatedier/frp
  • 官方文档: https://frp.readthedocs.io/
  • 插件仓库: https://github.com/gofrp/plugin

如果你觉得这个工具对你有帮助,欢迎关注我们的更多技术分享。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐