--- title: 通过 VPS + FRP + Caddy 实现内网穿透域名访问 author: shenwei created: 2026-06-04 updated: 2026-06-04 tags: [vps, caddy, frp, reverse-proxy, cloudflare, aliyun, ubuntu, troubleshooting, toml] --- #vps #caddy #frp #reverse-proxy #troubleshooting #cloudflare #aliyun #ubuntu #toml #frpc #frps ```table-of-contents ``` # 概述 **核心思路:** 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 迁移对照表](#-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 任意机器执行: ```bash dig nas.ishenwei.online +short # 应返回 192.227.222.142 ``` --- # 第 2 步:VPS 安装 Caddy + frps ## 1. 安装 Caddy ```bash 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) ```bash 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 配置详细笔记](FRP%20配置详细笔记.md) 的约定,所有二进制和配置文件都放在 `/opt/frp/frp_0.65.0_linux_amd64/` 下。 ## 3. 创建 `/opt/frp/frp_0.65.0_linux_amd64/frps.toml` ```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` ```ini [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 ``` 启动并验证: ```bash sudo systemctl daemon-reload sudo systemctl enable --now frps sudo systemctl status frps ss -ltnp | grep 7000 journalctl -u frps -f ``` ## 5. VPS 防火墙配置 ```bash 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: > ```bash > ssh -L 7500:127.0.0.1:7500 ubuntu@192.227.222.142 > ``` > 然后浏览器打开 `http://127.0.0.1:7500`。 --- # 第 3 步:内网设备安装 frpc ## 1. 安装 frp 客户端(每台内网设备执行) ```bash 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`: ```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`: ```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`: ```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 配置详细笔记](FRP%20配置详细笔记.md)。 ## 5. 创建 frpc systemd 服务(Linux) 创建 `/etc/systemd/system/frpc.service`: ```ini [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 ``` 启动: ```bash sudo systemctl daemon-reload sudo systemctl enable --now frpc sudo systemctl status frpc ``` 修改配置后重启: ```bash sudo systemctl restart frpc sudo journalctl -u frpc -n 50 ``` --- # 第 4 步:VPS 上配置 Caddy 反向代理 编辑 `/etc/caddy/Caddyfile`: ```caddy # 默认 :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 语法 ```bash sudo caddy validate --config /etc/caddy/Caddyfile ``` 返回 `Valid configuration` 即成功;否则会指出具体行号。 ## 重启 / 重载 Caddy ```bash # 优雅重载(推荐) 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 隧道 ```bash # 测试本地端口连通 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 映射段:** ```toml [[proxies]] name = "ubuntu1-ssh" type = "tcp" localIP = "127.0.0.1" localPort = 22 remotePort = 60022 ``` **2. 重启 frpc 并验证:** ```bash 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 连接:** ```bash 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 基础认证 在某个站点段中加入: ```caddy n8n.ishenwei.online { basicauth /* { admin JDJhJDE0JDN3ZXVhV2YyZG9SY2hvYzVmZ2h3QUlVblpOMU4vS1ptcENrSlhySElMb3l5dytOMkh0Tk93 } reverse_proxy 127.0.0.1:15679 } ``` 生成密码 hash: ```bash caddy hash-password ``` ## 2. SSH 安全加固 **(1) 不使用 22 等常见端口**(已用 60022/60023/60024/60026)。 **(2) 限制来源 IP**: ```bash sudo ufw allow from to any port 60022 proto tcp ``` **(3) 禁用密码登录,仅允许公钥认证**: 编辑内网机器 `/etc/ssh/sshd_config`: ``` PasswordAuthentication no PubkeyAuthentication yes ``` 重启 SSH: ```bash sudo systemctl restart ssh ``` ## 3. frps 端口限制 通过 `allowPorts` 限制 frpc 可注册的端口范围,避免恶意 client 抢占低端口: ```toml 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 → 观察日志。 ```bash # 停止代理(V2RayA 示例) sudo systemctl stop v2raya sudo systemctl restart frpc sudo journalctl -u frpc -f ``` ## ✔ 第 1 步:确认 frps 在监听端口 ```bash 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 进程加载的配置文件 ```bash 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 ```bash sudo iptables -L -n sudo ufw status sudo firewall-cmd --list-all # 如果用 firewalld ``` 需要确保: - TCP 7000 在 **ACCEPT** 列表 - 没有 One-key 脚本擅自修改 nftables - 直连 IP 不受 Cloudflare 影响 ## ✔ 第 4 步:确认 Caddy 没误代理 7000 ```bash sudo grep -n "7000" /etc/caddy/Caddyfile ``` 如存在 `:7000 { reverse_proxy ... }` → 必须删除,否则 frps 无法占用 7000。 ## ✔ 第 5 步:检查 frps 日志 token 错误 ```bash 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 客户端: ```bash telnet 192.227.222.142 7000 ``` 同时在 VPS 上: ```bash sudo journalctl -u frps -f ``` - **frps 有日志** → 网络通畅,问题在认证/配置层 - **frps 完全无反应** → 请求未到达进程,问题在端口占用 / iptables / SELinux / Caddy 抢端口 ## ✔ 第 7 步:强制重启 + 看错误码 VPS: ```bash sudo systemctl restart frps sudo systemctl status frps ``` 内网: ```bash 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 支持直接校验配置: ```bash /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:** ```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:** ```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 识别新路径: ```bash sudo systemctl daemon-reload sudo systemctl restart frpc ``` 3. **校验配置**: ```bash /opt/frp/frp_0.65.0_linux_amd64/frpc verify -c /opt/frp/frp_0.65.0_linux_amd64/frpc.toml ``` 4. **观察日志确认所有 proxy 启动成功**: ```bash sudo journalctl -u frpc -n 100 | grep "start proxy success" ``` 5. **可选:备份并删除旧的 `.ini` 文件**,避免下次误改: ```bash sudo mv /opt/frp/frpc.ini /opt/frp/frpc.ini.bak ``` --- # 📚 端口映射总表 > 详细参考 [FRP 配置详细笔记](FRP%20配置详细笔记.md) 中的端口汇总。 | 内网主机 | 内网端口 | 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 - [frp 官方文档](https://github.com/fatedier/frp) - [frp TOML 配置示例](https://github.com/fatedier/frp/blob/dev/conf/frpc_full_example.toml) - [Caddy 官方文档](https://caddyserver.com/docs/) - [Let's Encrypt](https://letsencrypt.org/) - 内部文档:[FRP 配置详细笔记](FRP%20配置详细笔记.md) - 内部文档:[Gitea 完整配置指南(SSH + frp + Caddy)](Gitea%20完整配置指南(SSH%20+%20frp%20+%20Caddy).md)