28 KiB
title, author, created, updated, tags
| title | author | created | updated | tags | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 通过 VPS + FRP + Caddy 实现内网穿透域名访问 | shenwei | 2026-06-04 | 2026-06-04 |
|
#vps #caddy #frp #reverse-proxy #troubleshooting #cloudflare #aliyun #ubuntu #toml
概述
核心思路: DNS(Cloudflare 或阿里云)将子域名指向公网 VPS;VPS 上运行 Caddy 提供 HTTPS 反代;内网主机通过 frp 将本地服务以反向隧道方式暴露到 VPS 的 127.0.0.1:<某端口>;Caddy 反代到该端口完成最终请求。
架构组成:
- VPS 运行
frps(frp 服务端) +Caddy(HTTPS 反代) - 每台内网设备 运行
frpc(frp 客户端),将本地服务映射到 VPS 的独立端口 - DNS 把所有子域名 A 记录指向 VPS 公网 IP
frp 的优势: 专为内网穿透设计,支持 NAT 穿透、自动重连、Web Dashboard,适合多设备多端口场景。
⚠️ 配置格式说明: 本文档统一使用 frp TOML 格式(
frps.toml/frpc.toml),不再使用旧版 INI 格式。frp 自 v0.52 起将 TOML 作为推荐格式,v0.65 完全采用。如果你旧配置是.ini,请按本文档末尾的 INI → TOML 迁移对照表 进行迁移。
前置共识(已知条件)
- 域名:
ishenwei.online(DNS 在 Cloudflare 或阿里云控制台管理,本文以 Cloudflare 为主,阿里云步骤类似) - 公网 VPS: Ubuntu,固定公网 IP
192.227.222.142 - FRP 版本: v0.65.0
- 统一 Token:
Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs - 内网服务清单:
| 服务 | 内网地址 | 期望公网域名 |
|---|---|---|
| NAS DSM | 192.168.3.17:5000 |
nas.ishenwei.online |
| NAS MySQL | 192.168.3.17:3306 |
mysql.ishenwei.online |
| Ubuntu1 n8n | 192.168.3.47:5678 |
n8n.ishenwei.online |
| Ubuntu1 Transmission | 192.168.3.47:9091 |
transmission.ishenwei.online |
| Ubuntu1 Grafana | 192.168.3.47:3000 |
grafana.ishenwei.online |
🧱 拓扑图
Internet
│
▼
┌──────────────────────────────────────┐
│ VPS (192.227.222.142) │
│ - frps 监听 7000 │
│ - Caddy 80 / 443 (TLS) │
│ ├─ nas.ishenwei.online → 127.0.0.1:15000
│ ├─ n8n.ishenwei.online → 127.0.0.1:15679
│ └─ ... │
└──────────────────────────────────────┘
▲ ▲
│ frp tunnel │ frp tunnel
┌───────┴────────┐ ┌───────┴────────┐
│ NAS │ │ Ubuntu1 │
│ 192.168.3.17 │ │ 192.168.3.47 │
│ frpc.toml │ │ frpc.toml │
│ 5000 → 15000 │ │ 9091 → 19091 │
│ 4533 → 14533 │ │ 3000 → 13000 │
│ ... │ │ ... │
└────────────────┘ └────────────────┘
第 1 步:DNS 配置
Cloudflare 配置
进入 Cloudflare Dashboard → DNS:
| 主机记录 | 记录类型 | 记录值 | 代理状态 | TTL |
|---|---|---|---|---|
| nas | A | 192.227.222.142 | 🚫 DNS only | 600 |
| n8n | A | 192.227.222.142 | 🚫 DNS only | 600 |
| transmission | A | 192.227.222.142 | 🚫 DNS only | 600 |
| grafana | A | 192.227.222.142 | 🚫 DNS only | 600 |
| ubuntu1 | A | 192.227.222.142 | 🚫 DNS only | 600 |
⚠️ 重要:必须关闭 Cloudflare 代理(小灰云),使用 DNS only 模式,否则:
- Caddy 申请 Let's Encrypt 证书会失败
- SSH 等非 HTTP/HTTPS TCP 流量无法穿过 Cloudflare
阿里云 DNS 配置
进入阿里云控制台 → 域名解析,添加同样的 A 记录即可。
验证 DNS
任意机器执行:
dig nas.ishenwei.online +short
# 应返回 192.227.222.142
第 2 步:VPS 安装 Caddy + frps
1. 安装 Caddy
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo chmod o+r /usr/share/keyrings/caddy-stable-archive-keyring.gpg
sudo chmod o+r /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
Caddy 安装后自动注册为 systemd 服务并运行。
2. 安装 frp 服务端(frps)
cd /opt
sudo mkdir frp && cd frp
FRP_VER=0.65.0
sudo curl -LO https://github.com/fatedier/frp/releases/download/v${FRP_VER}/frp_${FRP_VER}_linux_amd64.tar.gz
sudo tar xzf frp_${FRP_VER}_linux_amd64.tar.gz
# 保留版本目录: /opt/frp/frp_0.65.0_linux_amd64/
💡 路径约定:本文按 FRP 配置详细笔记 的约定,所有二进制和配置文件都放在
/opt/frp/frp_0.65.0_linux_amd64/下。
3. 创建 /opt/frp/frp_0.65.0_linux_amd64/frps.toml
# ===== 监听配置 =====
bindAddr = "0.0.0.0"
bindPort = 7000
# ===== 认证(必须与所有 frpc 一致)=====
auth.method = "token"
auth.token = "Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs"
# ===== 日志 =====
log.to = "/var/log/frps.log"
log.level = "info"
log.maxDays = 7
# ===== 管理 Dashboard =====
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "StrongPassword123!"
# ===== 安全限制(可选,推荐)=====
allowPorts = [
{ start = 10000, end = 65535 }
]
# 心跳超时(秒)
transport.heartbeatTimeout = 90
4. 创建 systemd 服务 /etc/systemd/system/frps.service
[Unit]
Description=frp server (frps)
After=network.target
[Service]
Type=simple
ExecStart=/opt/frp/frp_0.65.0_linux_amd64/frps -c /opt/frp/frp_0.65.0_linux_amd64/frps.toml
Restart=on-failure
RestartSec=10
LimitNOFILE=1048576
[Install]
WantedBy=multi-user.target
启动并验证:
sudo systemctl daemon-reload
sudo systemctl enable --now frps
sudo systemctl status frps
ss -ltnp | grep 7000
journalctl -u frps -f
5. VPS 防火墙配置
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp # Caddy HTTP
sudo ufw allow 443/tcp # Caddy HTTPS
sudo ufw allow 7000/tcp # frp server 端口
sudo ufw allow 7500/tcp # frp dashboard
sudo ufw allow 60022 # Ubuntu1 SSH
sudo ufw allow 60023 # NAS SSH
sudo ufw allow 60024 # Ubuntu2 SSH
sudo ufw allow 60026 # MacMini SSH
sudo ufw allow 65005 # WebDAV
sudo ufw allow 63307 # NAS MySQL
sudo ufw allow 10080 # NAS Web
sudo ufw allow 12222 # Gitea SSH
sudo ufw enable
sudo ufw status verbose
💡 如果只想从本地访问 frp dashboard,无需开放 7500:
ssh -L 7500:127.0.0.1:7500 ubuntu@192.227.222.142然后浏览器打开
http://127.0.0.1:7500。
第 3 步:内网设备安装 frpc
1. 安装 frp 客户端(每台内网设备执行)
cd /opt
sudo mkdir frp && cd frp
FRP_VER=0.65.0
# Linux amd64
sudo curl -LO https://github.com/fatedier/frp/releases/download/v${FRP_VER}/frp_${FRP_VER}_linux_amd64.tar.gz
sudo tar xzf frp_${FRP_VER}_linux_amd64.tar.gz
# macOS ARM64 (MacMini M 系列)
# sudo curl -LO https://github.com/fatedier/frp/releases/download/v${FRP_VER}/frp_${FRP_VER}_darwin_arm64.tar.gz
# sudo tar xzf frp_${FRP_VER}_darwin_arm64.tar.gz
2. 内网 NAS(192.168.3.17)配置
创建 /opt/frp/frp_0.65.0_linux_amd64/frpc.toml:
# ===== 服务器连接 =====
serverAddr = "192.227.222.142"
serverPort = 7000
auth.method = "token"
auth.token = "Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs"
# ===== 日志 =====
log.level = "info"
log.maxDays = 3
log.disablePrintColor = false
# ===== 客户端管理界面(可选)=====
webServer.addr = "127.0.0.1"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "admin"
# ===== NAS DSM: 本地 5000 → VPS :15000 =====
[[proxies]]
name = "nas"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5000
remotePort = 15000
# ===== Navidrome: 本地 4533 → VPS :14533 =====
[[proxies]]
name = "navidrome"
type = "tcp"
localIP = "127.0.0.1"
localPort = 4533
remotePort = 14533
# ===== Calibre: 本地 8083 → VPS :18083 =====
[[proxies]]
name = "calibre"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8083
remotePort = 18083
# ===== WebDAV: 本地 5005 → VPS :65005 =====
[[proxies]]
name = "webdav"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5005
remotePort = 65005
# ===== Miniflux: 本地 8080 → VPS :18080 =====
[[proxies]]
name = "miniflux"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8080
remotePort = 18080
# ===== Zipline: 本地 3333 → VPS :13333 =====
[[proxies]]
name = "zipline"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3333
remotePort = 13333
# ===== NAS SSH: 本地 22 → VPS :60023 =====
[[proxies]]
name = "nas_ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 60023
# ===== NAS MySQL: 本地 3307 → VPS :63307 =====
[[proxies]]
name = "mysql"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3307
remotePort = 63307
# ===== NAS Web: 本地 80 → VPS :10080 =====
[[proxies]]
name = "nas_web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 80
remotePort = 10080
# ===== Jellyfin: 本地 8096 → VPS :18096 =====
[[proxies]]
name = "jellyfin"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8096
remotePort = 18096
# ===== Gitea Web (给 Caddy 反代): 本地 3000 → VPS :13001 =====
[[proxies]]
name = "gitea-web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3000
remotePort = 13001
# ===== Gitea SSH (直接暴露): 本地 2222 → VPS :12222 =====
[[proxies]]
name = "gitea-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 2222
remotePort = 12222
3. 内网 Ubuntu1(192.168.3.47)配置
创建 /opt/frp/frp_0.65.0_linux_amd64/frpc.toml:
# ===== 服务器连接 =====
serverAddr = "192.227.222.142"
serverPort = 7000
auth.method = "token"
auth.token = "Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs"
# ===== 日志 =====
log.level = "info"
log.maxDays = 3
# ===== 客户端管理界面 =====
webServer.addr = "127.0.0.1"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "admin"
# ===== Ubuntu1 SSH: 本地 22 → VPS :60022 =====
[[proxies]]
name = "ubuntu1-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 60022
# ===== Transmission: 本地 9091 → VPS :19091 =====
[[proxies]]
name = "transmission"
type = "tcp"
localIP = "127.0.0.1"
localPort = 9091
remotePort = 19091
# ===== Grafana: 本地 3000 → VPS :13000 =====
[[proxies]]
name = "grafana"
type = "tcp"
localIP = "127.0.0.1"
localPort = 3000
remotePort = 13000
# ===== Homarr: 本地 7575 → VPS :17575 =====
[[proxies]]
name = "homarr"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7575
remotePort = 17575
# ===== Superset: 本地 8777 → VPS :18777 =====
[[proxies]]
name = "superset"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8777
remotePort = 18777
# ===== TK (生产): 本地 8888 → VPS :18888 =====
[[proxies]]
name = "tk"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8888
remotePort = 18888
# ===== Portainer: 本地 9000 → VPS :19443 =====
[[proxies]]
name = "ubuntu1-portainer"
type = "tcp"
localIP = "127.0.0.1"
localPort = 9000
remotePort = 19443
# ===== STQ: 本地 5173 → VPS :15173 =====
[[proxies]]
name = "stq"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5173
remotePort = 15173
# ===== STQ Admin: 本地 7000 → VPS :17000 =====
[[proxies]]
name = "stq-admin"
type = "tcp"
localIP = "127.0.0.1"
localPort = 7000
remotePort = 17000
# ===== STQ n8n: 本地 62000 → VPS :15678 =====
[[proxies]]
name = "stq-n8n"
type = "tcp"
localIP = "127.0.0.1"
localPort = 62000
remotePort = 15678
4. 内网 MacMini(macOS ARM64)配置示例
创建 /opt/frp/frp_0.65.0_darwin_arm64/frpc.toml:
serverAddr = "192.227.222.142"
serverPort = 7000
auth.method = "token"
auth.token = "Gg8sqHJVgh42KQ0oTatMjl6AywWqAzaaT0B77a4qD46tXtoH9j9mXb2k1YitObhs"
log.level = "info"
log.maxDays = 3
webServer.addr = "127.0.0.1"
webServer.port = 7400
webServer.user = "admin"
webServer.password = "admin"
[[proxies]]
name = "macmini-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 60026
[[proxies]]
name = "n8n"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5678
remotePort = 15679
[[proxies]]
name = "vaultwarden"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5151
remotePort = 15151
[[proxies]]
name = "it-tools"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8999
remotePort = 18999
[[proxies]]
name = "drawio"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8085
remotePort = 18085
💡 MacMini 一般通过 tmux 运行 frpc(非 systemd),见 FRP 配置详细笔记。
5. 创建 frpc systemd 服务(Linux)
创建 /etc/systemd/system/frpc.service:
[Unit]
Description=frp client
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/opt/frp/frp_0.65.0_linux_amd64/frpc -c /opt/frp/frp_0.65.0_linux_amd64/frpc.toml
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
启动:
sudo systemctl daemon-reload
sudo systemctl enable --now frpc
sudo systemctl status frpc
修改配置后重启:
sudo systemctl restart frpc
sudo journalctl -u frpc -n 50
第 4 步:VPS 上配置 Caddy 反向代理
编辑 /etc/caddy/Caddyfile:
# 默认 :80 站点(可保留作为占位)
:80 {
root * /usr/share/caddy
file_server
}
# ============== 内网服务反代 ==============
nas.ishenwei.online {
reverse_proxy 127.0.0.1:15000
}
n8n.ishenwei.online {
reverse_proxy 127.0.0.1:15679
}
transmission.ishenwei.online {
reverse_proxy 127.0.0.1:19091
}
grafana.ishenwei.online {
reverse_proxy 127.0.0.1:13000
}
navidrome.ishenwei.online {
reverse_proxy 127.0.0.1:14533
}
calibre.ishenwei.online {
reverse_proxy 127.0.0.1:18083
}
dashboard.ishenwei.online {
reverse_proxy 127.0.0.1:17575
}
miniflux.ishenwei.online {
reverse_proxy 127.0.0.1:18080
}
zipline.ishenwei.online {
reverse_proxy 127.0.0.1:13333
}
superset.ishenwei.online {
reverse_proxy 127.0.0.1:18777
}
tk.ishenwei.online {
reverse_proxy 127.0.0.1:18888
}
tk-dev.ishenwei.online {
reverse_proxy 127.0.0.1:18889
}
jellyfin.ishenwei.online {
reverse_proxy 127.0.0.1:18096
}
vaultwarden.ishenwei.online {
reverse_proxy 127.0.0.1:15151
}
it-tools.ishenwei.online {
reverse_proxy 127.0.0.1:18999
}
drawio.ishenwei.online {
reverse_proxy 127.0.0.1:18085
}
# Gitea (需大文件支持以支持 git push)
gitea.ishenwei.online {
reverse_proxy 127.0.0.1:13001
request_body {
max_size 5GB
}
}
web.ishenwei.online {
reverse_proxy 127.0.0.1:10080
}
验证 Caddyfile 语法
sudo caddy validate --config /etc/caddy/Caddyfile
返回 Valid configuration 即成功;否则会指出具体行号。
重启 / 重载 Caddy
# 优雅重载(推荐)
sudo systemctl reload caddy
sudo systemctl status caddy
# 强制重启
sudo systemctl restart caddy
# Caddy 卡死时的强制清理
sudo systemctl stop caddy
sudo pkill -9 caddy
sudo systemctl start caddy
Caddy 会自动申请并续期 Let's Encrypt 证书,无需人工干预。
第 5 步:验证测试
1. 在 VPS 上验证 frp 隧道
# 测试本地端口连通
curl http://127.0.0.1:15679 # n8n
curl http://127.0.0.1:15000 # nas
curl http://127.0.0.1:19091 # transmission
curl http://127.0.0.1:13000 # grafana
# 查看 frps 是否在监听对应端口
ss -ltnp | egrep '15679|19091|13000|7000|60022'
预期:
LISTEN 0 4096 *:19091 *:* users:(("frps",pid=59421,fd=10))
LISTEN 0 4096 *:13000 *:* users:(("frps",pid=59421,fd=8))
LISTEN 0 4096 *:15679 *:* users:(("frps",pid=59421,fd=9))
LISTEN 0 4096 *:7000 *:* users:(("frps",pid=59421,fd=6))
2. 浏览器验证 HTTPS
访问:
- https://nas.ishenwei.online
- https://n8n.ishenwei.online
- https://transmission.ishenwei.online
- https://grafana.ishenwei.online
应能通过 HTTPS 正常打开,证书自动签发。
第 6 步:SSH 穿透(特殊场景)
重要:SSH 不经 Caddy
⚠️ SSH 是纯 TCP 流量,Caddy 不参与代理(Caddy 只处理 HTTP/HTTPS)。SSH 穿透仅由 frps + frpc 完成,Caddyfile 无需修改。
SSH 拓扑
外部 SSH 客户端
│
▼
ubuntu1.ishenwei.online:60022 ← VPS 公网入口
│
▼
frps(VPS)
│
▼
frpc(192.168.3.47)
│
▼
本地 SSH (192.168.3.47:22)
配置步骤
1. frpc.toml 中已包含 SSH 映射段:
[[proxies]]
name = "ubuntu1-ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 60022
2. 重启 frpc 并验证:
sudo systemctl restart frpc
sudo systemctl status frpc
sudo journalctl -u frpc -n 50 | grep "start proxy success"
成功日志:
[ubuntu1-ssh] start proxy success
3. 外部 SSH 连接:
ssh -p 60022 user@ubuntu1.ishenwei.online
注意:DNS 只解析 IP,必须显式指定端口
-p 60022。
4. 推荐:配置 SSH config 简化连接
~/.ssh/config:
Host ubuntu1
HostName ubuntu1.ishenwei.online
Port 60022
User ishenwei
IdentityFile ~/.ssh/id_ed25519
之后直接 ssh ubuntu1 即可。
第 7 步:frp Dashboard(可选)
浏览器访问:
http://192.227.222.142:7500
用户名:admin
密码:StrongPassword123!
可实时查看:
- 各 frpc 客户端的连接状态
- 每个代理隧道的流量统计
- 在线/离线状态
🔒 可选安全加固
1. Caddy 基础认证
在某个站点段中加入:
n8n.ishenwei.online {
basicauth /* {
admin JDJhJDE0JDN3ZXVhV2YyZG9SY2hvYzVmZ2h3QUlVblpOMU4vS1ptcENrSlhySElMb3l5dytOMkh0Tk93
}
reverse_proxy 127.0.0.1:15679
}
生成密码 hash:
caddy hash-password
2. SSH 安全加固
(1) 不使用 22 等常见端口(已用 60022/60023/60024/60026)。
(2) 限制来源 IP:
sudo ufw allow from <your_home_ip> to any port 60022 proto tcp
(3) 禁用密码登录,仅允许公钥认证:
编辑内网机器 /etc/ssh/sshd_config:
PasswordAuthentication no
PubkeyAuthentication yes
重启 SSH:
sudo systemctl restart ssh
3. frps 端口限制
通过 allowPorts 限制 frpc 可注册的端口范围,避免恶意 client 抢占低端口:
allowPorts = [
{ start = 10000, end = 65535 }
]
✅ 配置改动速查表
| 组件 | 是否需要修改 | 说明 |
|---|---|---|
| DNS | ✅ 每个子域名添加 A 记录 → VPS 公网 IP | Cloudflare 必须 DNS only |
| Caddy | ✅ HTTP/HTTPS 服务需添加站点段;❌ SSH 不需要 | 不处理 TCP 非 HTTP 流量 |
| frps (VPS) | ✅ 一次性配置 bindPort + auth.token |
后续新增映射无需改 frps |
| frpc (内网) | ✅ 每个新服务新增一个 [[proxies]] 块 |
修改后 systemctl restart frpc |
| VPS 防火墙 | ✅ 放行所有 remotePort |
UFW 同时配置 IPv4/IPv6 |
🛠 错误排查 #troubleshooting
✔ 检查代理软件冲突
NAS 上安装的 V2RayA / Clash 等代理软件可能劫持 frp 流量。
排查:停止代理软件 → 重启 frpc → 观察日志。
# 停止代理(V2RayA 示例)
sudo systemctl stop v2raya
sudo systemctl restart frpc
sudo journalctl -u frpc -f
✔ 第 1 步:确认 frps 在监听端口
ss -lntup | grep 7000
ss -lntup | grep frps
预期:
tcp LISTEN 0 4096 *:7000 *:* users:(("frps",pid=413014,fd=6))
tcp LISTEN 0 4096 *:7500 *:* users:(("frps",pid=413014,fd=3))
如果端口未监听,可能是:
- ❌ 端口被 Caddy/Nginx 占用
- ❌ frps 未绑定
0.0.0.0 - ❌ frps 在跑但配置不对
✔ 第 2 步:确认 frps 进程加载的配置文件
ps -ef | grep frps
预期:
root 413014 1 0 02:23 ? /opt/frp/frp_0.65.0_linux_amd64/frps -c /opt/frp/frp_0.65.0_linux_amd64/frps.toml
常见坑:
- 编辑了
frps.toml,但 systemd 加载的是frps.ini(旧配置遗留) - 编辑了
/opt/frp/frps.toml,但 systemd 实际加载/opt/frp/frp_0.65.0_linux_amd64/frps.toml - 确认 systemd unit 的
ExecStart路径完全匹配
特别注意 token 完全一致(包括无多余空格/换行/编码差异)。
✔ 第 3 步:确认防火墙未阻塞 7000
sudo iptables -L -n
sudo ufw status
sudo firewall-cmd --list-all # 如果用 firewalld
需要确保:
- TCP 7000 在 ACCEPT 列表
- 没有 One-key 脚本擅自修改 nftables
- 直连 IP 不受 Cloudflare 影响
✔ 第 4 步:确认 Caddy 没误代理 7000
sudo grep -n "7000" /etc/caddy/Caddyfile
如存在 :7000 { reverse_proxy ... } → 必须删除,否则 frps 无法占用 7000。
✔ 第 5 步:检查 frps 日志 token 错误
sudo journalctl -u frps -n 100 --no-pager
tail -f /var/log/frps.log
如出现:
authentication failed
token mismatch
invalid login
→ token 不一致。重点检查 frps.toml 和 frpc.toml 的 auth.token 是否字符级相同。
✔ 第 6 步:telnet + journalctl 联合诊断
从 frpc 客户端:
telnet 192.227.222.142 7000
同时在 VPS 上:
sudo journalctl -u frps -f
- frps 有日志 → 网络通畅,问题在认证/配置层
- frps 完全无反应 → 请求未到达进程,问题在端口占用 / iptables / SELinux / Caddy 抢端口
✔ 第 7 步:强制重启 + 看错误码
VPS:
sudo systemctl restart frps
sudo systemctl status frps
内网:
sudo systemctl restart frpc
sudo systemctl status frpc
sudo journalctl -u frpc -n 50
frpc 错误对照表:
| 错误日志 | 原因 |
|---|---|
dial tcp 192.227.222.142:7000: connection reset |
防火墙拦截 |
authentication failed |
token 不一致 |
wait until server ready |
frps 端口被劫持 |
unmarshal config error |
TOML 语法错误(缩进、引号、[[proxies]] 双方括号) |
✔ 第 8 步:TOML 配置语法快速校验
frp 支持直接校验配置:
/opt/frp/frp_0.65.0_linux_amd64/frpc verify -c /opt/frp/frp_0.65.0_linux_amd64/frpc.toml
/opt/frp/frp_0.65.0_linux_amd64/frps verify -c /opt/frp/frp_0.65.0_linux_amd64/frps.toml
输出 success 即语法正确。
🔄 INI → TOML 迁移对照表
如果你有旧的 frpc.ini,按下表对照迁移到 frpc.toml:
| INI 写法 | TOML 写法 |
|---|---|
[common] |
(顶层,无需 section) |
server_addr = 1.2.3.4 |
serverAddr = "1.2.3.4" |
server_port = 7000 |
serverPort = 7000 |
token = xxx |
auth.method = "token"auth.token = "xxx" |
[nas] |
[[proxies]]name = "nas" |
type = tcp |
type = "tcp" |
local_ip = 127.0.0.1 |
localIP = "127.0.0.1" |
local_port = 5000 |
localPort = 5000 |
remote_port = 15000 |
remotePort = 15000 |
dashboard_addr = 0.0.0.0 |
webServer.addr = "0.0.0.0" |
dashboard_port = 7500 |
webServer.port = 7500 |
dashboard_user = admin |
webServer.user = "admin" |
dashboard_pwd = xxx |
webServer.password = "xxx" |
log_file = /var/log/frps.log |
log.to = "/var/log/frps.log" |
log_level = info |
log.level = "info" |
log_max_days = 7 |
log.maxDays = 7 |
关键差异:
- TOML 字符串必须用双引号
- TOML 字段名驼峰命名(
serverAddr,不是server_addr) - 每个代理用
[[proxies]](双方括号,TOML 数组语法),不是[name] - 代理的
name现在是字段,不是 section 名 - 同名字段使用点号:
auth.token、log.level、webServer.port - 数字、布尔值不加引号;字符串必须加双引号
迁移完整示例
旧版 frpc.ini:
[common]
server_addr = 192.227.222.142
server_port = 7000
token = MyToken123
[nas]
type = tcp
local_ip = 127.0.0.1
local_port = 5000
remote_port = 15000
[ssh]
type = tcp
local_ip = 127.0.0.1
local_port = 22
remote_port = 60022
新版 frpc.toml:
serverAddr = "192.227.222.142"
serverPort = 7000
auth.method = "token"
auth.token = "MyToken123"
[[proxies]]
name = "nas"
type = "tcp"
localIP = "127.0.0.1"
localPort = 5000
remotePort = 15000
[[proxies]]
name = "ssh"
type = "tcp"
localIP = "127.0.0.1"
localPort = 22
remotePort = 60022
迁移后必做事项
- 更新 systemd 服务文件:把
ExecStart里的frpc.ini改成frpc.toml - 执行
daemon-reload让 systemd 识别新路径:sudo systemctl daemon-reload sudo systemctl restart frpc - 校验配置:
/opt/frp/frp_0.65.0_linux_amd64/frpc verify -c /opt/frp/frp_0.65.0_linux_amd64/frpc.toml - 观察日志确认所有 proxy 启动成功:
sudo journalctl -u frpc -n 100 | grep "start proxy success" - 可选:备份并删除旧的
.ini文件,避免下次误改:sudo mv /opt/frp/frpc.ini /opt/frp/frpc.ini.bak
📚 端口映射总表
详细参考 FRP 配置详细笔记 中的端口汇总。
| 内网主机 | 内网端口 | VPS 公网端口 | 域名 | 服务 |
|---|---|---|---|---|
| NAS | 5000 | 15000 | nas.ishenwei.online | DSM |
| NAS | 4533 | 14533 | navidrome.ishenwei.online | Navidrome |
| NAS | 8083 | 18083 | calibre.ishenwei.online | Calibre |
| NAS | 5005 | 65005 | — | WebDAV |
| NAS | 8080 | 18080 | miniflux.ishenwei.online | Miniflux |
| NAS | 3333 | 13333 | zipline.ishenwei.online | Zipline |
| NAS | 22 | 60023 | — | SSH |
| NAS | 3307 | 63307 | — | MySQL |
| NAS | 80 | 10080 | web.ishenwei.online | Web |
| NAS | 8096 | 18096 | jellyfin.ishenwei.online | Jellyfin |
| NAS | 3000 | 13001 | gitea.ishenwei.online | Gitea Web |
| NAS | 2222 | 12222 | — | Gitea SSH |
| MacMini | 22 | 60026 | — | SSH |
| MacMini | 5678 | 15679 | n8n.ishenwei.online | n8n |
| MacMini | 5151 | 15151 | vaultwarden.ishenwei.online | Vaultwarden |
| MacMini | 8999 | 18999 | it-tools.ishenwei.online | IT-Tools |
| MacMini | 8085 | 18085 | drawio.ishenwei.online | Drawio |
| Ubuntu1 | 22 | 60022 | — | SSH |
| Ubuntu1 | 9091 | 19091 | transmission.ishenwei.online | Transmission |
| Ubuntu1 | 3000 | 13000 | grafana.ishenwei.online | Grafana |
| Ubuntu1 | 7575 | 17575 | dashboard.ishenwei.online | Homarr |
| Ubuntu1 | 8777 | 18777 | superset.ishenwei.online | Superset |
| Ubuntu1 | 8888 | 18888 | tk.ishenwei.online | TK |
| Ubuntu1 | 9000 | 19443 | — | Portainer |
| Ubuntu1 | 5173 | 15173 | — | STQ |
| Ubuntu1 | 7000 | 17000 | — | STQ Admin |
| Ubuntu1 | 62000 | 15678 | — | STQ n8n |
| Ubuntu2 | 22 | 60024 | — | SSH |
| Ubuntu2 | 8888 | 18889 | tk-dev.ishenwei.online | TK Dev |