之前搭了个 frp 把本地的 stable-diffusion-webui 暴露到公网上,当时在那篇隐藏 cmd 窗口的文章里简单提了一嘴 frp,但没细讲怎么配。后来有不少同学私信问 frp 咋搭的,干脆写一篇从零开始的完整教程吧。

本文基于 frp v0.52.0+ 版本,使用 TOML 格式配置文件。旧版的 INI 格式(frps.ini / frpc.ini)已经不推荐使用了,新功能只能在 TOML/YAML/JSON 格式下生效。

什么是内网穿透?

简单说,内网穿透就是让外网能访问你局域网里的设备。你家的电脑在路由器后面,没有公网 IP,外面根本连不进来。frp 就是干这事的——你有一台带公网 IP 的服务器当中转,把流量转发到你内网的机器上。

frp 的架构

frp 分两个角色:

  • frps(Server):部署在有公网 IP 的服务器上,负责接收外部请求并转发
  • frpc(Client):部署在你的内网机器上,负责把本地服务注册到 frps 上
1
外网用户 --> 公网服务器(frps) --> 内网机器(frpc) --> 本地服务

就这么简单,下面直接上配置。

一、服务端部署(frps)

1. 下载安装

GitHub Releases 页面下载对应平台的版本。服务器一般是 Linux amd64:

1
2
3
4
5
6
7
8
9
10
11
# 下载(以 v0.61.1 为例,去 GitHub 看最新版本号)
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

# 只需要 frps 和 frps.toml
sudo cp frps /usr/local/bin/
sudo mkdir -p /etc/frp
sudo cp frps.toml /etc/frp/

2. 配置 frps.toml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 服务端监听地址
bindAddr = "0.0.0.0"
# 服务端监听端口,frpc 连接用的
bindPort = 7000

# 认证配置
auth.method = "token"
auth.token = "your_strong_password_here"

# Web Dashboard
webServer.addr = "127.0.0.1"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "your_dashboard_password"

# HTTP/HTTPS 虚拟主机端口(可选,如果要用域名转发的话)
# vhostHTTPPort = 80
# vhostHTTPSPort = 443

# 日志配置
log.to = "./frps.log"
log.level = "info"
log.maxDays = 3

auth.token 一定要改成一个强密码!别用 12345678 这种,被人扫到就完蛋了。同理 Dashboard 的密码也要改。

3. 用 systemd 管理 frps

创建 service 文件:

1
sudo vim /etc/systemd/system/frps.service

写入以下内容:

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

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

[Install]
WantedBy=multi-user.target

启动并设为开机自启:

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

# 看一下状态
sudo systemctl status frps

4. 开放防火墙端口

别忘了开防火墙,不然 frpc 连不上:

1
2
3
4
5
6
7
8
9
10
# 如果用的 ufw
sudo ufw allow 7000/tcp
sudo ufw allow 7500/tcp # Dashboard,可选

# 如果用的 firewalld
sudo firewall-cmd --permanent --add-port=7000/tcp
sudo firewall-cmd --permanent --add-port=7500/tcp
sudo firewall-cmd --reload

# 如果是云服务器,还要去安全组里放行端口

云服务器(阿里云、腾讯云等)除了系统防火墙,还要去控制台的安全组里放行端口,很多人卡在这一步。

二、客户端配置(frpc)

1. 下载安装

跟服务端一样,去 GitHub Releases 下载对应你本地机器平台的版本。Windows 的话下载 frp_x.x.x_windows_amd64.zip,解压就行。

2. 配置 frpc.toml

假设我们要把本地的 Web 服务(比如 SD WebUI 跑在 127.0.0.1:7860)暴露到公网服务器的 6000 端口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 服务端地址
serverAddr = "你的服务器公网IP"
serverPort = 7000

# 认证,必须跟服务端一致
auth.method = "token"
auth.token = "your_strong_password_here"

# 日志
log.to = "./frpc.log"
log.level = "info"
log.maxDays = 3

# 代理配置
[[proxies]]
name = "sd-webui"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7860
remotePort = 6000

配置好之后启动:

1
2
3
4
5
# Linux
./frpc -c ./frpc.toml

# Windows(cmd 或 PowerShell)
frpc.exe -c frpc.toml

看到 login to server success 就说明连上了。这时候访问 http://你的服务器IP:6000 就能打开你本地的 Web 服务了。

3. 多个服务怎么办?

直接多加几个 [[proxies]] 就行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 6001

[[proxies]]
name = "sd-webui"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7860
remotePort = 6000

[[proxies]]
name = "my-web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8080
remotePort = 6002

三、安全注意事项

这个话题很重要,内网穿透相当于在公网上开了个门,不注意安全的话后果很严重。

1. Token 认证必须配

frp 默认使用 token 认证(auth.method = "token"),服务端和客户端的 token 必须一致。这是最基本的安全措施,不配 token 的话任何人都能连你的 frps。

2. Dashboard 密码要改

Dashboard 默认账号密码是 admin / admin一定要改。而且建议 Dashboard 只绑定 127.0.0.1,通过 SSH 隧道访问,不要直接暴露到公网。

3. 不要暴露敏感端口

千万不要把 3389(RDP)、22(SSH,除非你知道自己在干嘛)、3306(MySQL)等端口直接暴露到公网。如果非要暴露,至少改掉默认端口号,并且配合 allowPorts 限制可用端口范围。暴露数据库端口到公网 = 裸奔。

4. 服务端限制端口范围

frps.toml 中可以限制客户端能使用的端口范围:

1
2
3
4
5
# 只允许这些端口范围
allowPorts = [
{ start = 6000, end = 7000 },
{ start = 8000, end = 9000 },
]

5. TLS 加密

frp 从 v0.50.0 开始 默认开启 TLS 加密transport.tls.force = true),客户端与服务端之间的通信是加密的。如果需要强制要求 TLS,可以在 frps.toml 中加上:

1
transport.tls.force = true

四、Windows 下 frpc 开机自启

Windows 下 frpc 是个命令行程序,直接写 bat 自启动的话每次开机都会弹一个黑框,关了就没了。

关于如何在 Windows 下开机自启动命令行程序并隐藏 cmd 窗口,我之前专门写过一篇文章,详细介绍了用 VBS 脚本隐藏窗口的方法,详见这篇文章

简单说就是写一个 VBS 脚本来启动 frpc:

1
2
Set ws = CreateObject("Wscript.Shell")
ws.Run "cmd /c C:\frp\frpc.exe -c C:\frp\frpc.toml", 0

保存为 start_frpc.vbs,然后把这个 VBS 文件的快捷方式丢到启动文件夹里:

1
C:\Users\你的用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

或者用任务计划程序(Task Scheduler)也行,设置触发器为「计算机启动时」,操作选启动那个 VBS 脚本,勾选「不管用户是否登录」。

五、常用排错命令

1
2
3
4
5
6
7
8
9
10
11
# 查看 frps 状态
sudo systemctl status frps

# 查看 frps 日志
sudo journalctl -u frpc -f

# 或者直接看日志文件
tail -f /var/log/frps.log

# 检查端口是否在监听
ss -tlnp | grep 7000

参考资料