内网穿透工具 frp 配置详解

frp 是一款使用 Go 编写的高性能反向代理应用,专注于内网穿透,支持 TCP、UDP、HTTP、HTTPS 等协议。只需在公网机器运行 frps、内网机器运行 frpc,编写简单的 TOML 配置,即可把内网服务安全地暴露到公网。本文聚焦配置实践,不涉及源码与扩展开发。

frp 的组成

frp 由两部分组成:

  • frps:部署在拥有公网 IP 的服务器上,负责接收并转发公网请求。
  • frpc:部署在需要被访问的内网机器上,主动与 frps 建立连接。

公网用户访问 frps 的某个端口时,frps 会把流量沿 frpc 建立的隧道转发到内网服务的实际端口。

安装

frp 跨平台,下载对应平台的二进制包即可,无需额外依赖。

确认系统架构

下载前先确认主机的 CPU 架构,避免下错版本:

1
2
# Linux / macOS
uname -m
1
2
# Windows PowerShell
$env:PROCESSOR_ARCHITECTURE

常见输出与对应的发行包:

输出 架构 frp 发行包名中的标识
x86_64 / AMD64 64 位 Intel / AMD amd64
aarch64 / ARM64 64 位 ARM arm64
armv7l 32 位 ARM arm
i386 / i686 32 位 x86 386

例如:

  • Linux 服务器 uname -m 返回 x86_64 → 下载 frp_0.68.0_linux_amd64.tar.gz
  • 树莓派或 ARM 云服务器返回 aarch64 → 下载 frp_0.68.0_linux_arm64.tar.gz
  • Windows 返回 AMD64 → 下载 frp_0.68.0_windows_amd64.zip

确认操作系统类型

frp 官方发行包按「系统 + 架构」组合命名,格式为:

1
frp_{版本}_{系统}_{架构}.{压缩格式}

确认系统类型:

1
2
# Linux / macOS / BSD
uname -s
系统 uname -s 输出 包名中的系统标识 压缩格式
Linux Linux linux .tar.gz
macOS Darwin darwin .tar.gz
Windows —(查看系统信息) windows .zip
FreeBSD FreeBSD freebsd .tar.gz
OpenBSD OpenBSD openbsd .tar.gz

各系统常见的架构组合:

系统 支持的架构
Linux amd64、arm64、arm、386、loong64、mips64、riscv64
macOS amd64(Intel)、arm64(Apple Silicon)
Windows amd64、arm64、386
FreeBSD / OpenBSD amd64、arm64、386

把两者拼起来就是完整的包名,例如 ARM 架构的树莓派(Linux)应选 frp_0.68.0_linux_arm64.tar.gz,而 Intel 芯片的 Mac 应选 frp_0.68.0_darwin_amd64.tar.gz。

下载与放置

  1. 从 GitHub Releases 下载与「系统 + 架构」匹配的压缩包。
  2. 解压后把 frpc 放到内网机器,frps 放到公网机器。
  3. 编写配置文件(推荐 TOML 格式,YAML/JSON 也支持,旧的 INI 已不推荐)。

解压后的可执行文件名因系统而异:

系统 服务端程序 客户端程序
Linux / macOS / BSD frps frpc
Windows frps.exe frpc.exe

启动命令:

1
2
3
4
5
# Linux / macOS(服务端,公网机器)
./frps -c ./frps.toml

# Linux / macOS(客户端,内网机器)
./frpc -c ./frpc.toml
1
2
3
# Windows(在解压目录下)
.\frps.exe -c .\frps.toml
.\frpc.exe -c .\frpc.toml

长期后台运行的方式也因系统不同:

  • Linux:用 systemd 托管(见后文「使用 systemd 后台运行」)。
  • macOS:用 launchd 或 brew services 托管。
  • Windows:用 nssm、winsw 封装为 Windows 服务,或加入「启动」目录。

核心概念

配置项 作用
bindPort frps 监听客户端连接的端口
proxies frpc 上定义的转发规则,类型含 tcp、udp、http、https、stcp 等
localIP / localPort 内网实际服务的地址与端口
remotePort frps 上对外监听的端口,公网流量进入后被转发到内网
customDomains HTTP/HTTPS 代理使用的自定义域名

通过 SSH 访问内网机器(TCP 代理)

服务端 frps.toml:

1
bindPort = 7000

客户端 frpc.toml(假设公网 IP 为 x.x.x.x):

1
2
3
4
5
6
7
8
9
serverAddr = "x.x.x.x"
serverPort = 7000

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

启动两端后,即可通过公网访问内网 SSH:

1
ssh -o Port=6000 [email protected]

通过域名访问内网 Web 服务(HTTP 代理)

HTTP 代理不仅复用端口,还支持基于 HTTP 协议的诸多功能。

服务端 frps.toml:

1
2
bindPort = 7000
vhostHTTPPort = 8080

客户端 frpc.toml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
serverAddr = "x.x.x.x"
serverPort = 7000

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

[[proxies]]
name = "web2"
type = "http"
localPort = 8080
customDomains = ["www.yourdomain2.com"]

将域名的 A 记录解析到 x.x.x.x 后,浏览器访问 http://www.yourdomain.com:8080 即可访问内网 80 端口服务。多个域名共享 vhostHTTPPort 端口。

注意:https 类型的代理要求本地本身就是 HTTPS 服务(frps 不做 TLS 终止);若本地是 HTTP 服务想以 HTTPS 对外,可借助 https2http 插件。

UDP 代理

1
2
3
4
5
6
[[proxies]]
name = "dns"
type = "udp"
localIP = "127.0.0.1"
localPort = 53
remotePort = 6002

STCP 加密代理(不暴露公网端口)

stcp 代理在 frps 上不监听公网端口,访问方需运行另一个 frpc 作为访问者,安全性更高。

服务端 frps.toml:

1
bindPort = 7000

被访问端 frpc.toml:

1
2
3
4
5
6
7
8
9
serverAddr = "x.x.x.x"
serverPort = 7000

[[proxies]]
name = "secret_ssh"
type = "stcp"
secretKey = "my-secret-key"
localIP = "127.0.0.1"
localPort = 22

访问端 frpc.toml:

1
2
3
4
5
6
7
8
9
10
serverAddr = "x.x.x.x"
serverPort = 7000

[[visitors]]
name = "secret_ssh_visitor"
type = "stcp"
serverName = "secret_ssh"
secretKey = "my-secret-key"
bindAddr = "127.0.0.1"
bindPort = 6000

访问端本地连接:

1
ssh -o Port=6000 [email protected]

Token 认证

frpc 与 frps 配置相同 token 即可验证双方身份,防止未授权客户端接入:

1
2
3
# frps.toml
bindPort = 7000
auth.token = "abc"
1
2
3
4
# frpc.toml
serverAddr = "x.x.x.x"
serverPort = 7000
auth.token = "abc"

生产环境建议不要把密钥硬编码进配置文件,可使用 auth.tokenSource 从文件或外部命令加载 token(v0.64.0+ 支持文件、v0.66.0+ 支持命令)。

服务端 Dashboard

在 frps.toml 中开启:

1
2
3
4
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"

通过 http://[server addr]:7500 访问,可查看代理状态与统计信息。也可配置 TLS 证书启用 HTTPS:

1
2
webServer.tls.certFile = "server.crt"
webServer.tls.keyFile = "server.key"

注意:Dashboard 未针对大量 proxy 数据展示优化,数据量很大时访问可能变慢。

使用 systemd 后台运行(Linux)

创建服务单元文件(以 frps 为例):

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=frp server
After=network.target

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

[Install]
WantedBy=multi-user.target

启用并启动:

1
2
3
4
sudo systemctl daemon-reload
sudo systemctl enable frps
sudo systemctl start frps
sudo systemctl status frps

frpc 同理,创建对应服务单元并 ExecStart=/usr/local/frp/frpc -c ...。

常见问题排查

  • 端口被占用:确认 remotePort、vhostHTTPPort、bindPort 在公网服务器未被占用,且防火墙/安全组已放行。
  • 连不上 frps:检查 serverAddr/serverPort 是否正确、token 是否一致、NAT/防火墙是否允许出站。
  • HTTP 域名不生效:确认域名解析到 frps 服务器,vhostHTTPPort 已配置,customDomains 与实际 Host 一致。
  • stcp 连接失败:secretKey 与 serverName 必须匹配。
  • 后台运行:用 systemd 管理,避免 SSH 断开后进程退出。

总结

frp 的配置核心就是两份 TOML:公网机器跑 frps 并开放 bindPort,内网机器跑 frpc 并用 [[proxies]] 定义转发规则。TCP 代理做端口转发、HTTP 代理按域名分发、STCP 提供不暴露公网端口的安全通道。配合 token 认证与 systemd 后台运行,即可稳定地把内网服务发布到公网。更多配置项请参考 frp 官方文档。