Files
nexus/knowledgebase/通过VPS+FRP+Caddy实现内网穿透域名访问.md
2026-06-04 15:43:50 +08:00

28 KiB
Raw Blame History

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
cloudflare
aliyun
ubuntu
troubleshooting
toml

#vps #caddy #frp #reverse-proxy #troubleshooting #cloudflare #aliyun #ubuntu #toml #frpc #frps

概述

核心思路: 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 正常打开,证书自动签发。


第 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

关键差异:

  1. TOML 字符串必须用双引号
  2. TOML 字段名驼峰命名(serverAddr,不是 server_addr)
  3. 每个代理用 [[proxies]](双方括号,TOML 数组语法),不是 [name]
  4. 代理的 name 现在是字段,不是 section 名
  5. 同名字段使用点号:auth.token、log.level、webServer.port
  6. 数字、布尔值不加引号;字符串必须加双引号

迁移完整示例

旧版 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

迁移后必做事项

  1. 更新 systemd 服务文件:把 ExecStart 里的 frpc.ini 改成 frpc.toml
  2. 执行 daemon-reload 让 systemd 识别新路径:
    sudo systemctl daemon-reload
    sudo systemctl restart frpc
    
  3. 校验配置:
    /opt/frp/frp_0.65.0_linux_amd64/frpc verify -c /opt/frp/frp_0.65.0_linux_amd64/frpc.toml
    
  4. 观察日志确认所有 proxy 启动成功:
    sudo journalctl -u frpc -n 100 | grep "start proxy success"
    
  5. 可选:备份并删除旧的 .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

📎 References