1169 lines
28 KiB
Markdown
1169 lines
28 KiB
Markdown
---
|
||
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 <your_home_ip> 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"`<br>`auth.token = "xxx"` |
|
||
| `[nas]` | `[[proxies]]`<br>`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)
|