# Cloudflare Tunnel 内网穿透完全指南（Windows / macOS / Linux）

> **适用平台**: Windows · macOS · Linux（含 ARM64）  
> **难度**: ⭐⭐ 入门（零配置临时穿透）→ ⭐⭐⭐ 中级（自有域名 + 系统服务）→ ⭐⭐⭐⭐ 进阶（Relay 全协议穿透）  
> **前置要求**: 终端基础操作能力；自有域名模式需 Cloudflare 免费账户  
> **协议**: 本 SOP 为开源资料整合，引用工具均为 MIT/Apache 协议  
> **最后更新**: 2026-05-02

---

## 一、概述与方案选型

### 1.1 内网穿透要解决什么问题？

内网穿透（NAT Traversal / Reverse Tunnel）将运行在局域网内（无公网 IP）的服务暴露到互联网，让外部用户通过公网地址访问。典型刚需场景：

| 场景 | 示例 |
|------|------|
| 本地开发预览 | 前端跑在 `localhost:3000`，要发给客户/同事在线查看 |
| API 联调 | 后端跑在本机，远程同事需要调用接口 |
| Webhook 回调 | GitHub / 支付平台需要推送通知到本地服务 |
| 远程访问 | 出差时访问家中的 NAS / 管理后台 / 监控面板 |
| 游戏服务器 | Minecraft / Terraria 等联机游戏需要公网端口 |
| SSH 远程管理 | 没有公网 IP 的家用机器需要远程 SSH |
| AI 工具产物分享 | AI 在本地生成的网页需要远程演示 |

### 1.2 方案对比表

| 对比项 | Cloudflare Tunnel (Cloud) | 自建中继 (Relay/frp) | ngrok 免费版 | 商业付费方案 |
|--------|--------------------------|----------------------|-------------|-------------|
| 协议支持 | HTTP / HTTPS / WebSocket | TCP / UDP / 全协议 | HTTP/TCP(付费) | 因产品而异 |
| 费用 | **完全免费** | 服务器费用（最低 $3/月） | 限速 + 时长限制 | $5–20+/月 |
| 域名 | 随机 `*.trycloudflare.com` 或自有域名 | IP + 端口 | 随机子域名 | 因产品而异 |
| 加密 | 全程 HTTPS + Cloudflare CDN | 需自行配置 TLS | 内置 TLS | 因产品而异 |
| 速度 | Cloudflare 全球边缘节点加速 | 取决于服务器位置 | 海外节点为主 | 因产品而异 |
| 适合场景 | Web / API / 前端预览 / Webhook | 游戏 / 数据库 / SSH / 远程桌面 | 临时分享 | 商业生产 |
| 需要公网 IP | 否 | 是（自备 VPS） | 否 | 否 |

**本 SOP 推荐方案**：

- **HTTP / WebSocket 场景** → Cloudflare Tunnel **Cloud 模式**（免费、安全、全球加速）
- **TCP / UDP 全协议场景** → **Relay 模式**（基于 frp 自建中继，需公网服务器）
- **追求极简 CLI 体验** → 使用 `cftunnel` 封装工具，集成 Cloud + Relay 双引擎

### 1.3 架构原理

**Cloud 模式**——流量经 Cloudflare 全球 CDN，自带 HTTPS，无需公网 IP：

```
localhost:3000  →  cloudflared  →  Cloudflare Edge (全球 CDN)  →  公网用户
  (本地服务)     (本地守护进程)      (自动 HTTPS 加密)            (域名访问)
```

**Relay 模式**——流量经你的公网服务器，支持全协议：

```
localhost:25565 →  frpc  →  你的公网服务器(frps)  →  远程访问
   (本地服务)   (客户端)         (中继服务端)          (IP:端口)
```---

## 二、方案 A：原生 cloudflared（官方工具）

> 适合追求稳定、只需 HTTP/WS 穿透、不想装第三方包装工具的用户。

### 2.1 安装 cloudflared

#### Windows

```powershell
# 方式1：winget（推荐，需 Win10 1809+）
winget install --id Cloudflare.cloudflared

# 方式2：手动下载
# 浏览器访问 https://github.com/cloudflare/cloudflared/releases/latest
# 下载 cloudflared-windows-amd64.exe，重命名为 cloudflared.exe
# 放入 PATH 目录（如 C:\Windows\System32\），或自定义目录后将该目录加入 PATH

# 验证
cloudflared --version
```

#### macOS

```bash
# 方式1：Homebrew（推荐）
brew install cloudflared

# 方式2：手动下载
# Intel:        https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-darwin-amd64.tgz
# Apple Silicon: https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-darwin-arm64.tgz
curl -L -o cloudflared.tgz <上述URL>
tar -xzf cloudflared.tgz
sudo mv cloudflared /usr/local/bin/
chmod +x /usr/local/bin/cloudflared

# 若被 Gatekeeper 拦截
xattr -d com.apple.quarantine /usr/local/bin/cloudflared

# 验证
cloudflared --version
```

#### Linux

```bash
# 方式1：官方 APT 源（Debian / Ubuntu，推荐生产环境）
curl -L https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-archive-keyring.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update && sudo apt install cloudflared

# 方式2：直接下载二进制（任意发行版）
curl -L -o cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64
chmod +x cloudflared
sudo mv cloudflared /usr/local/bin/

# ARM64 / 树莓派
curl -L -o cloudflared https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64
# ...同上

# 验证
cloudflared --version
```

### 2.2 快速穿透：零配置临时隧道

最简单的方式，**不需要 Cloudflare 账号、不需要域名**：

```bash
# 将本地 3000 端口暴露到公网
cloudflared tunnel --url http://localhost:3000
```

输出类似：

```
+--------------------------------------------------------------------------------+
|  Your quick Tunnel has been created! Visit it at (it may take some time to be  |
|  reachable):                                                                   |
|  https://random-words-here.trycloudflare.com                                   |
+--------------------------------------------------------------------------------+
```

> ⚠️ **临时隧道特性**：域名每次启动都会变化，Ctrl+C 退出后立即失效。仅适合临时调试 / 一次性分享。固定域名请使用下文 2.3 流程。

### 2.3 自有域名持久隧道（完整配置流程）

#### 步骤 1：创建 Cloudflare API Token

1. 访问 [Cloudflare API Tokens 页面](https://dash.cloudflare.com/profile/api-tokens)
2. 点击 **「创建令牌」 → 「创建自定义令牌」 → 「开始使用」**
3. 令牌名称随便填，如 `cf-tunnel-token`
4. 添加 **3 条权限**（点「+ 添加更多」逐条添加）：

| 范围 | 权限项 | 级别 |
|------|--------|------|
| **帐户** | Cloudflare Tunnel | 编辑 |
| **区域** | DNS | 编辑 |
| **区域** | 区域设置 | 读取 |

5. 「区域资源」选择 **「包括 → 特定区域 → 你的域名」**
6. 创建后**立即复制令牌**（只显示一次！）

> ⚠️ **典型踩坑**：
> - 第 2、3 行权限要将左侧下拉框从「帐户」切换为「**区域**」，默认是「帐户」会无效。
> - DNS 权限要选「**DNS**」而非「**DNS 设置**」——Cloudflare 中文界面中两者名字相似但完全不同，选错会在调用 `CreateDNSRecord` API 时报 403。

#### 步骤 2：获取账户 ID

- 登录 [Cloudflare Dashboard](https://dash.cloudflare.com/)
- 点击你的域名 → 右侧栏下方「**API**」区域可看到 **Account ID**
- 或首页账户名旁的「⋯」菜单可直接复制

#### 步骤 3：登录认证

```bash
cloudflared tunnel login
# 浏览器会自动弹出 Cloudflare 授权页
# 选择对应域名 → 授权
# 完成后会在 ~/.cloudflared/ 下生成 cert.pem
```

> Windows 路径：`%USERPROFILE%\.cloudflared\cert.pem`

#### 步骤 4：创建隧道

```bash
cloudflared tunnel create my-tunnel
# 输出包含隧道 UUID，如:
# Created tunnel my-tunnel with id abc12345-...
# 同时生成凭证文件 ~/.cloudflared/<UUID>.json
```

#### 步骤 5：编写配置文件

创建 `~/.cloudflared/config.yml`（Windows 为 `%USERPROFILE%\.cloudflared\config.yml`）：

```yaml
tunnel: <你的隧道 UUID>
credentials-file: /home/youruser/.cloudflared/<你的隧道 UUID>.json

ingress:
  # 将 app.example.com 转发到本地 3000 端口
  - hostname: app.example.com
    service: http://localhost:3000

  # 将 api.example.com 转发到本地 8080 端口
  - hostname: api.example.com
    service: http://localhost:8080

  # WebSocket 服务示例（cloudflared 默认支持 WS 升级）
  - hostname: ws.example.com
    service: http://localhost:9000

  # 兜底规则（必须有！未匹配的请求返回 404）
  - service: http_status:404
```

> 💡 `credentials-file` 必须是绝对路径，不要写 `~`。Windows 写 `C:\Users\YourName\.cloudflared\<UUID>.json`。

#### 步骤 6：自动配置 DNS CNAME

```bash
cloudflared tunnel route dns my-tunnel app.example.com
cloudflared tunnel route dns my-tunnel api.example.com
cloudflared tunnel route dns my-tunnel ws.example.com
```

每条命令会自动在 Cloudflare DNS 创建一条 CNAME 记录指向 `<UUID>.cfargotunnel.com`。

#### 步骤 7：前台启动验证

```bash
cloudflared tunnel run my-tunnel
# 看到 Connection 注册成功（4 个连接）即代表正常
# 此时 https://app.example.com 应可访问
```

#### 步骤 8：注册为系统服务（开机自启）

**Linux (systemd)：**

```bash
sudo cloudflared service install
sudo systemctl enable --now cloudflared
sudo systemctl status cloudflared    # 检查状态
sudo journalctl -u cloudflared -f    # 实时日志
```

**macOS (launchd)：**

```bash
sudo cloudflared service install
# 服务文件位于 /Library/LaunchDaemons/com.cloudflare.cloudflared.plist
# 重启
sudo launchctl unload /Library/LaunchDaemons/com.cloudflare.cloudflared.plist
sudo launchctl load   /Library/LaunchDaemons/com.cloudflare.cloudflared.plist
```

**Windows (管理员 PowerShell)：**

```powershell
cloudflared.exe service install
# 在「服务」管理器中可看到 "Cloudflared agent"
Start-Service Cloudflared
Get-Service Cloudflared
```

> ⚠️ Windows 上 `cloudflared service install` 必须**管理员权限**运行，否则会静默失败。

### 2.4 常用维护命令

```bash
# 列出所有隧道
cloudflared tunnel list

# 查看特定隧道详情（含连接器、活跃连接数）
cloudflared tunnel info my-tunnel

# 查看隧道路由
cloudflared tunnel route ip show

# 删除隧道（需先停止服务）
cloudflared tunnel delete my-tunnel

# Debug 模式启动
cloudflared tunnel --loglevel debug run my-tunnel
```---

## 三、方案 B：cftunnel CLI（推荐，封装 cloudflared + frp 双引擎）

> `cftunnel` 是对 `cloudflared` 与 `frp` 的 Go 封装，提供统一、友好的 CLI 体验。  
> 项目地址：https://github.com/qingchencloud/cftunnel ｜ MIT 协议  
> 主要特性：自动 DNS 同步、一键开机自启、Cloud + Relay 双引擎、便携模式、自更新。

### 3.1 安装 cftunnel

#### macOS / Linux 一键安装

```bash
curl -fsSL https://raw.githubusercontent.com/qingchencloud/cftunnel/main/install.sh | bash
```

> 脚本会自动检测架构（amd64 / arm64）下载对应二进制到 `/usr/local/bin/`，并把首次启动需要的 `cloudflared` 引擎下载到 `~/.cftunnel/bin/`。

#### Windows 一键安装（PowerShell，建议管理员）

```powershell
irm https://raw.githubusercontent.com/qingchencloud/cftunnel/main/install.ps1 | iex
```

#### 手动安装

从 [Releases](https://github.com/qingchencloud/cftunnel/releases) 下载对应平台二进制：

| 平台 | 架构 | 文件名 |
|------|------|--------|
| Windows | x64 | `cftunnel_windows_amd64.exe` |
| Windows | ARM64 | `cftunnel_windows_arm64.exe` |
| macOS | Intel | `cftunnel_darwin_amd64.tar.gz` |
| macOS | Apple Silicon | `cftunnel_darwin_arm64.tar.gz` |
| Linux | x64 | `cftunnel_linux_amd64.tar.gz` |
| Linux | ARM64 | `cftunnel_linux_arm64.tar.gz` |

解压后将二进制放入 PATH 即可。

#### 从源码构建（需要 Go 1.21+）

```bash
git clone https://github.com/qingchencloud/cftunnel.git
cd cftunnel
make build      # 输出到 ./bin/cftunnel
sudo install bin/cftunnel /usr/local/bin/
```

#### 验证

```bash
cftunnel version
cftunnel version --check    # 检查是否有新版本
```

### 3.2 Cloud 模式：免费 HTTP / WebSocket 穿透

#### 3.2.1 免域名模式（零配置，一条命令）

**完全不需要** Cloudflare 账户、API Token、域名。装好就能用：

```bash
# 暴露本地 3000 端口到公网
cftunnel quick 3000
# ✔ 隧道已启动: https://xxx-yyy-zzz.trycloudflare.com
```

加上密码保护：

```bash
cftunnel quick 3000 --auth admin:Sup3rStr0ng!
# 访问时浏览器会弹出 HTTP Basic Auth 登录框
```

> 💡 与原生 `cloudflared tunnel --url` 的差别：`cftunnel quick` 多了 `--auth` 密码、`--relay` 切到 Relay 引擎、自动重连、彩色日志等。

#### 3.2.2 自有域名模式（固定域名，长期稳定）

**前提**：已完成 §2.3 步骤 1–2 准备好 API Token 和 Account ID。

```bash
# === Step 1: 一次性初始化 ===
cftunnel init --token <your-api-token> --account <your-account-id>
# 也可以直接 cftunnel init 进入交互式向导

# === Step 2: 一次性创建隧道 ===
cftunnel create my-tunnel

# === Step 3: 添加路由（自动创建 DNS CNAME 记录！） ===
cftunnel add app 3000 --domain app.example.com
cftunnel add api 8080 --domain api.example.com

# === Step 4: 启动 ===
cftunnel up

# 至此：
#   https://app.example.com  →  localhost:3000
#   https://api.example.com  →  localhost:8080
```

#### 3.2.3 路由维护

```bash
# 查看所有路由
cftunnel list

# 删除路由（自动清理对应 DNS 记录）
cftunnel remove app

# 查看隧道状态
cftunnel status

# 实时日志
cftunnel logs -f

# 停止
cftunnel down
```

#### 3.2.4 注册为系统服务（开机自启）

```bash
# 一条命令自动适配 launchd / systemd / Windows Service
cftunnel install

# 查看服务状态
cftunnel status

# 卸载服务
cftunnel uninstall
```

> Windows 上 `cftunnel install` 同样需要管理员权限（PowerShell 右键「以管理员身份运行」）。

#### 3.2.5 完全清理

```bash
# 删除隧道 + 所有路由的 DNS 记录（CF 侧也清理干净）
cftunnel destroy

# 在 destroy 基础上，再清掉本地配置文件（彻底重置）
cftunnel reset --force
```

### 3.3 Relay 模式：全协议穿透（TCP / UDP）

> 适合游戏服务器、数据库远程访问、SSH、远程桌面等非 HTTP 场景。  
> **前提**：需要一台有公网 IP 的服务器（VPS）。

#### 3.3.1 服务端部署

**方式 1：一键脚本**（在你的公网服务器上执行）

```bash
curl -fsSL https://raw.githubusercontent.com/qingchencloud/cftunnel/main/install-relay.sh | bash
```

脚本完成后会输出 **客户端连接命令**，包含 `--server` 和 `--token` 两个关键参数，请妥善保存。

**方式 2：Docker Compose 部署**

```bash
mkdir -p ~/cftunnel-relay && cd ~/cftunnel-relay

cat > docker-compose.yml << 'EOF'
version: '3'
services:
  frps:
    image: snowdreamtech/frps:latest
    container_name: frps
    restart: always
    network_mode: host
    volumes:
      - ./frps.toml:/etc/frp/frps.toml
EOF

cat > frps.toml << 'EOF'
bindPort = 7000
auth.method = "token"
auth.token = "请替换为高强度随机字符串"
# 可选：开启 dashboard
webServer.addr = "0.0.0.0"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "请替换为强密码"
EOF

docker compose up -d
```

> ⚠️ **防火墙必须放行**：`7000`（frps 通信端口）+ 你计划映射的所有业务端口；以及 `7500`（如果开了 dashboard）。  
> 阿里云/腾讯云用户记得同时配置安全组，不只是系统防火墙。

#### 3.3.2 客户端配置

```bash
# === Step 1: 用服务端输出的连接信息初始化 ===
cftunnel relay init --server <公网IP>:7000 --token <your-token>

# === Step 2: 添加穿透规则 ===
# Minecraft 服务器（TCP）
cftunnel relay add minecraft --local 25565 --remote 25565 --proto tcp

# SSH 远程登录（把内网 22 端口映射到公网 6022）
cftunnel relay add ssh --local 22 --remote 6022 --proto tcp

# 游戏服务器（UDP）
cftunnel relay add game --local 27015 --remote 27015 --proto udp

# 远程桌面 RDP
cftunnel relay add rdp --local 3389 --remote 13389 --proto tcp

# === Step 3: 启动 ===
cftunnel relay up

# === Step 4: 注册系统服务 ===
cftunnel relay install
```

#### 3.3.3 链路检测与维护

```bash
# 检测与中继服务器的连通性、延迟、带宽
cftunnel relay check

# 列出所有 Relay 规则
cftunnel relay list

# 删除规则
cftunnel relay remove ssh

# 查看实时日志
cftunnel relay logs -f

# 停止 / 卸载服务
cftunnel relay down
cftunnel relay uninstall
```

### 3.4 cftunnel 命令速查表

| 命令 | 说明 |
|------|------|
| `quick <port>` | 免域名临时穿透（零配置） |
| `quick <port> --auth user:pass` | 临时穿透 + HTTP Basic Auth |
| `quick <port> --relay` | 走 Relay 引擎做临时穿透 |
| `init` | 配置 API Token + Account ID |
| `create <name>` | 创建隧道 |
| `add <name> <port> --domain <fqdn>` | 添加路由（自动创建 DNS） |
| `remove <name>` | 删除路由（自动清理 DNS） |
| `list` / `status` | 列出路由 / 查看状态 |
| `up` / `down` | 启动 / 停止隧道 |
| `logs [-f]` | 查看日志（`-f` 实时跟踪） |
| `install` / `uninstall` | 注册 / 卸载系统服务 |
| `destroy [--force]` | 删隧道 + 清空 DNS |
| `reset [--force]` | 完全重置（含本地配置） |
| `version [--check]` | 版本信息 / 检查更新 |
| `update` | 自动升级到最新版 |
| `relay init` | Relay 模式初始化 |
| `relay add/remove/list` | 管理 Relay 穿透规则 |
| `relay up/down` | 启停 Relay 客户端 |
| `relay install/uninstall` | Relay 系统服务管理 |
| `relay check` | 检测中继链路连通性 |---

## 四、实战场景示例

### 4.1 场景：前端预览分享（最高频）

```bash
# 终端1：启动本地开发服务器
npm run dev          # 假设跑在 localhost:3000

# 终端2：一键穿透
cftunnel quick 3000
# 把输出的 https://xxx.trycloudflare.com 发给同事/客户即可
```

### 4.2 场景：接收 Webhook 回调

```bash
# 本地服务监听 9801
cftunnel add webhook 9801 --domain webhook.example.com
cftunnel up

# 将 https://webhook.example.com 配置为 GitHub / Stripe / 飞书机器人 等回调地址
```

### 4.3 场景：多服务一站式暴露

```bash
# 一个隧道可挂多条路由（一次 cftunnel up 启动全部）
cftunnel add frontend 3000 --domain app.example.com
cftunnel add backend  8080 --domain api.example.com
cftunnel add grafana  3001 --domain monitor.example.com
cftunnel list             # 检查所有路由映射
cftunnel up
cftunnel install          # 注册系统服务，开机自启
```

### 4.4 场景：Minecraft 联机服务器（TCP）

```bash
cftunnel relay add mc --local 25565 --remote 25565 --proto tcp
cftunnel relay up
# 朋友连接 <你的公网IP>:25565
```

### 4.5 场景：SSH 远程管理内网机器

```bash
# 内网机器上
cftunnel relay add ssh --local 22 --remote 6022 --proto tcp
cftunnel relay install     # 开机自启

# 外部连接
ssh -p 6022 user@<你的公网IP>
```

### 4.6 场景：远程访问家中 NAS 管理界面

```bash
# 家中机器
cftunnel add nas 5000 --domain nas.example.com
cftunnel up
cftunnel install

# 强烈建议在 Cloudflare Zero Trust 配置 Access Policy（见 §5.2）
```

### 4.7 场景：配合 AI 编程工具

```bash
# AI 在本地生成网页 / 启动了 Vite / Next.js dev server
# 远程预览只需一条命令
cftunnel quick 5173
# 复制 URL 即可分享 AI 生成的成果
```

---

## 五、进阶配置

### 5.1 便携模式

在 `cftunnel` 可执行文件**同级目录**放一个名为 `portable` 的空文件，所有配置、日志、引擎二进制都会存放在该目录下，适合 U 盘随身或多机隔离配置：

```bash
# Linux / macOS
touch /opt/cftunnel/portable

# Windows PowerShell
New-Item -Path .\portable -ItemType File
```

### 5.2 Cloudflare Access 保护（生产推荐）

对长期暴露的敏感服务，强烈建议在 Cloudflare Zero Trust 配置 **Access Policy**，相当于在你的隧道前加了一道企业级 SSO：

1. 登录 [Cloudflare Zero Trust](https://one.dash.cloudflare.com/)
2. **Access → Applications → Add an application → Self-hosted**
3. Application domain 填你的隧道域名（如 `nas.example.com`）
4. 设置 Identity provider：Email OTP / GitHub / Google Workspace 等
5. 配置 Policy：邮箱白名单 / 邮箱后缀 / IP 段
6. 保存。下次访问该域名将先要求登录认证。

> 💡 个人/家庭用户用 **Email OTP** 即可，免费且无需第三方 SSO。

### 5.3 配置文件位置

| 工具 | 配置目录 |
|------|----------|
| cloudflared | `~/.cloudflared/`（含 `config.yml` + `cert.pem` + `<UUID>.json`） |
| cftunnel | `~/.cftunnel/`（含 `config.yml` + `bin/` 引擎二进制 + `state/`） |

Windows 上对应 `%USERPROFILE%\.cloudflared\` 和 `%USERPROFILE%\.cftunnel\`。

### 5.4 自定义引擎超时

在 `~/.cloudflared/config.yml` 的 ingress 项下可配置每条路由的转发参数：

```yaml
ingress:
  - hostname: app.example.com
    service: http://localhost:3000
    originRequest:
      connectTimeout: 30s
      noTLSVerify: true            # 后端是 https 自签名证书时使用
      httpHostHeader: app.local    # 强制改写 Host 头
      disableChunkedEncoding: false
      keepAliveConnections: 100
  - service: http_status:404
```

### 5.5 日志与监控

```bash
# cloudflared 调试模式
cloudflared tunnel --loglevel debug run my-tunnel

# cftunnel 实时日志
cftunnel logs -f

# Linux systemd 日志
journalctl -u cloudflared -f
journalctl -u cftunnel -f --since "1 hour ago"

# Windows 事件查看器中也可以查看 cloudflared 服务日志
```

---

## 六、故障排查

### 6.1 常见问题速查表

| 症状 | 原因 | 解决方案 |
|------|------|----------|
| `failed to sufficiently increase receive buffer size` | Linux UDP 缓冲区过小 | `sudo sysctl -w net.core.rmem_max=2500000`（持久化写入 `/etc/sysctl.conf`） |
| `error parsing tunnel ID` | 隧道 UUID 错误 | `cloudflared tunnel list` 确认正确 ID |
| `DNS record already exists` | CNAME 冲突 | CF Dashboard 删除旧记录；或 `cftunnel add` 自动处理 |
| `403 Forbidden`（API 调用） | Token 权限不足 | 检查是否选了「DNS」而非「DNS 设置」 |
| `connection refused` | 本地服务未启动 | 确认目标端口服务在运行 |
| 502 Bad Gateway | 本地服务崩溃 / 响应超时 | 检查本地服务；调大 `connectTimeout` |
| 隧道启动后外网无法访问 | DNS 未生效 / 防火墙 | 等待 DNS 传播（1-5 分钟）；检查本地防火墙；用 `nslookup` 验证 |
| Relay 连不上 | 服务器防火墙未放行 | 放行 7000 端口和映射端口；检查云厂商安全组 |
| Windows 服务注册失败 | 非管理员 | 以管理员身份运行 PowerShell |
| macOS 二进制无法执行 | Gatekeeper 拦截 | `xattr -d com.apple.quarantine /path/to/cloudflared` |
| `tunnel credentials file not found` | 凭证文件路径错误 | 检查 `config.yml` 中绝对路径正确性 |
| `websocket: bad handshake` | 反代未升级 WS | cloudflared 默认支持 WS，检查后端是否正常响应 Upgrade 头 |
| 间歇性断连 | 网络抖动 / Cloudflare 边缘切换 | cftunnel 自带重连；cloudflared 加 `--retries 5` 参数 |

### 6.2 链路诊断步骤（标准排查顺序）

```bash
# 步骤 1：确认本地服务可达
curl -v http://localhost:<端口>

# 步骤 2：确认隧道进程存活
# Linux / macOS
ps aux | grep -E 'cloudflared|cftunnel'
# Windows
Get-Process | Where-Object { $_.Name -match 'cloudflared|cftunnel' }

# 步骤 3：检查隧道状态
cftunnel status
# 或
cloudflared tunnel info <隧道名>

# 步骤 4：DNS 解析检查（应返回 *.cfargotunnel.com）
nslookup app.example.com
dig +short app.example.com CNAME

# 步骤 5：从外部 curl 测试
curl -I https://app.example.com

# 步骤 6：Relay 模式额外检测
cftunnel relay check

# 步骤 7：实时日志定位问题
cftunnel logs -f
# 或 cloudflared tunnel --loglevel debug run my-tunnel
```

### 6.3 重置与清理

当配置混乱、需要从头开始：

```bash
# cftunnel 一键重置
cftunnel destroy --force      # 删隧道 + 清 DNS
cftunnel reset --force        # 在上面基础上清本地配置

# cloudflared 手动清理
sudo systemctl stop cloudflared
cloudflared tunnel delete my-tunnel
rm -rf ~/.cloudflared/        # Linux / macOS
# Windows: Remove-Item $env:USERPROFILE\.cloudflared -Recurse -Force
```

---

## 七、安全最佳实践

1. **最小权限原则**：API Token 只授予必要权限（Tunnel 编辑 + DNS 编辑），并限定到具体区域。
2. **密码保护**：临时分享用 `cftunnel quick <port> --auth user:pass` 加 HTTP Basic。
3. **Cloudflare Access**：生产/敏感服务用 Zero Trust Access Policy 而非简单密码。
4. **Token 保管**：API Token 写入 `~/.cftunnel/config.yml` 后，文件权限设为 `chmod 600`；**不要**提交到 Git。
5. **Relay token 强度**：自建 Relay 时 `auth.token` 至少 24 位随机字符串，定期轮换。
6. **来源 IP 限制**：Relay 服务器配合 `iptables` / `ufw` 仅放行需要的来源段。
7. **及时清理**：用完即删（`cftunnel destroy`），避免残留隧道暴露面。
8. **监控告警**：在 Cloudflare Analytics 设置异常流量告警。
9. **不要暴露管理面板**：`/admin`、`/api/internal` 等敏感路径建议加 IP 白名单或 Access。
10. **HTTPS 自动**：CF Tunnel 默认提供 HTTPS，**不要**在公网暴露纯 HTTP。

---

## 八、cloudflared vs cftunnel 速查对照

| 操作 | 原生 cloudflared | cftunnel |
|------|-----------------|----------|
| 免域名穿透 | `cloudflared tunnel --url http://localhost:3000` | `cftunnel quick 3000` |
| 免域名 + 密码 | 不支持，需自配 | `cftunnel quick 3000 --auth u:p` |
| 创建隧道 | `tunnel login` + `tunnel create` | `cftunnel init` + `cftunnel create` |
| 添加路由 | 编辑 `config.yml` + `tunnel route dns` | `cftunnel add <name> <port> --domain` |
| 多域名管理 | 手编 YAML | `cftunnel list / remove` |
| 开机自启 | 自写 systemd / launchd | `cftunnel install` 一条命令 |
| 清理删除 | 手删隧道 + DNS + 配置 | `cftunnel destroy --force` |
| 自更新 | 手动下新版 | `cftunnel update` |
| TCP / UDP 全协议 | 不原生支持 | `cftunnel relay`（集成 frp） |
| 链路检测 | 自行 ping / mtr | `cftunnel relay check` |

---

## 九、附录

### 附录 A：cloudflared 完整配置模板

`~/.cloudflared/config.yml`：

```yaml
tunnel: <YOUR-TUNNEL-UUID>
credentials-file: /home/youruser/.cloudflared/<YOUR-TUNNEL-UUID>.json

# 全局参数（可选）
loglevel: info
no-autoupdate: false
metrics: localhost:9099       # Prometheus 指标暴露端口

ingress:
  # 路由 1：前端
  - hostname: app.example.com
    service: http://localhost:3000

  # 路由 2：后端 API
  - hostname: api.example.com
    service: http://localhost:8080
    originRequest:
      connectTimeout: 30s
      noHappyEyeballs: false

  # 路由 3：WebSocket
  - hostname: ws.example.com
    service: http://localhost:9000

  # 路由 4：路径分流
  - hostname: shared.example.com
    path: ^/api/.*
    service: http://localhost:8080
  - hostname: shared.example.com
    service: http://localhost:3000

  # 兜底（必须）
  - service: http_status:404
```

### 附录 B：frps 完整配置模板（Relay 服务端）

`/etc/frp/frps.toml`：

```toml
bindPort = 7000

# 鉴权
auth.method = "token"
auth.token = "请替换为高强度随机字符串-至少24位"

# 日志
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 = "请替换为强密码"

# TLS（强烈推荐启用）
transport.tls.force = true

# 端口白名单（限制客户端能映射的远程端口范围）
allowPorts = [
  { start = 6000, end = 7999 },
  { start = 13000, end = 13999 }
]

# 单客户端最大端口数
maxPortsPerClient = 16
```

### 附录 C：环境变量速查

| 变量 | 作用 | 示例 |
|------|------|------|
| `CLOUDFLARE_API_TOKEN` | cloudflared API 调用 | `export CLOUDFLARE_API_TOKEN=xxx` |
| `CLOUDFLARE_ACCOUNT_ID` | 账户 ID | `export CLOUDFLARE_ACCOUNT_ID=xxx` |
| `TUNNEL_TOKEN` | cloudflared 隧道令牌（替代 cert.pem） | `cloudflared tunnel run --token $TUNNEL_TOKEN` |
| `CFTUNNEL_HOME` | 自定义 cftunnel 配置目录 | `export CFTUNNEL_HOME=/opt/cftunnel` |

### 附录 D：参考链接

- Cloudflare 官方文档：https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/
- cloudflared GitHub：https://github.com/cloudflare/cloudflared
- cftunnel GitHub：https://github.com/qingchencloud/cftunnel
- frp GitHub：https://github.com/fatedier/frp
- Cloudflare Zero Trust 文档：https://developers.cloudflare.com/cloudflare-one/

---

## 十、写在最后

**为什么推荐 Cloudflare Tunnel？**

- 🆓 **完全免费**：无流量限制、无并发限制、无时长限制
- 🌍 **全球加速**：流量经 Cloudflare 200+ 边缘节点
- 🔒 **自动 HTTPS**：无需自己折腾证书
- 🛡️ **DDoS 防护**：享受 Cloudflare 免费 DDoS 防护
- 🔐 **Zero Trust**：可叠加企业级访问控制
- 🚀 **稳定可靠**：CF 自家基础设施，可用性极高

**何时不要用 Cloudflare Tunnel？**

- ❌ 协议非 HTTP/WS（用 Relay 模式或专门的 TCP 穿透方案）
- ❌ 不希望流量经过 Cloudflare（合规/隐私要求）
- ❌ 国内某些地区直连 CF 边缘有抖动（可叠加 ARGO / 优选 IP）

希望本 SOP 能帮助你快速搭建可靠的内网穿透方案。如有问题欢迎 PR / Issue 完善。