Cloudflare 隧道 + OpenClaw Gateway:实现外网访问完整指南 v1.1

本指南是 Cloudflare 隧道 + OpenClaw Gateway:实现外网访问完整指南 的 v1.1 版本。v1.0 版本使用日期格式,v1.1 及以后使用版本号格式。

更新内容

  • 修正了文章命名规则
  • 统一了版本号格式

📋 目录


前置准备

系统环境

组件 版本/要求 验证命令
Ubuntu 24.04.4 LTS lsb_release -a
Node.js v22+ node -v
Nginx 1.24+ nginx -v
Git 2.43+ git --version

工具准备

1
2
3
4
5
6
7
8
# 安装必要工具
sudo apt update
sudo apt install -y curl jq

# 验证安装
openclaw --version
nginx -v
git --version

网络环境

项目 域名 说明
OpenClaw 本地访问 10.28.9.66 内网 IP
Cloudflare 隧道域名 your-domain.com 需要在 Cloudflare 配置
外网访问目标 https://your-domain.com/ 最终访问地址

端口规划

应用 端口 用途
OpenClaw WebChat 18789 Gateway HTTP 服务
ClawMate 8080 个人沟通空间
ClawApp 3210 应用集合
OpenCode 4096 AI 编程助手

服务拓扑

1
2
3
4
5
6
7
8
9
10
11
用户访问

Cloudflare CDN (HTTPS)

Cloudflare 隧道 (HTTP2)

Nginx (端口 80)

OpenClaw Gateway (端口 18789)

OpenClaw WebChat

cloudflared 安装

1. 下载安装

下载最新版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 下载最新版本
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64

# 验证下载
sha256sum cloudflared-linux-amd64

# 赋予执行权限
chmod +x cloudflared-linux-amd64

# 移动到系统目录
sudo mv cloudflared-linux-amd64 /usr/local/bin/cloudflared

# 验证安装
cloudflared --version

预期输出

1
2
cloudflared version 2026.2.0
built 2026-01-01

步骤 2:登录 Cloudflare

1
2
3
4
5
6
# 登录 Cloudflare
cloudflared tunnel login

# 预期输出:
# Please open the following URL to authenticate:
# https://dash.cloudflare.com/argotunnel?token=<your-auth-token>

说明

  • 浏览器会显示授权页面
  • 登录成功后,token 会保存在本地
  • 后续命令可以直接使用保存的 token

cloudflared 配置

1. 配置文件结构

配置文件位置

1
~/.cloudflared/config.yml

配置文件内容

1
2
3
4
5
6
7
8
9
10
11
# tunnel: <your-tunnel-id>

credentials-file: /home/jarvis/.cloudflared/<id>.json

ingress:
- hostname: your-domain.com
service: http://your-local-ip:80
# path: "" (空字符串,所有路径)

# 使用 HTTP2 协议(TCP)而非 QUIC(UDP)
protocol: http2

2. 关键配置说明

协议选择(HTTP2 vs QUIC)

协议 类型 优势 劣势 适用场景
HTTP2 (TCP) 穿透性好 速度稍慢 国内网络 ✅ 推荐
QUIC (UDP) 速度快 穿透性差 国内网络 ❌ 不推荐

推荐配置:使用 protocol: http2

服务配置

参数 说明 示例
hostname 外网访问域名 your-domain.com
service 内网服务地址 http://your-local-ip:80
path URL 路径前缀 "" (空,代理到根路径)

凭证文件(credentials-file)

1
2
3
4
5
{
"TunnelToken": "<your-tunnel-token>",
"TunnelID": "<your-tunnel-id>",
"AccountTag": ""
}

Nginx 安装

1. 安装 Nginx

安装命令

1
2
3
4
5
6
7
8
# 更新包列表
sudo apt update

# 安装 Nginx
sudo apt install -y nginx

# 验证安装
nginx -v

预期输出

1
nginx version: nginx/1.24.0 (Ubuntu)

2. 配置文件结构

配置文件位置

1
2
3
/etc/nginx/sites-available/claw-tunnel
/etc/nginx/sites-enabled/claw-tunnel
/etc/nginx/nginx.conf

Nginx 配置

1. 完整配置文件

主配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# Cloudflare 隧道 + Nginx 反向代理配置
# 文件位置:/etc/nginx/sites-available/claw-tunnel
# 创建时间:2026-03-06 19:00

server {
listen 80;
server_name your-domain.com;

# 根路径:反向代理到 OpenClaw WebChat
location / {
proxy_pass http://127.0.0.1:18789/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;

# 🔧 关键配置:禁用所有代理头
proxy_set_header X-Forwarded-For "";
proxy_set_header X-Real-IP "127.0.0.1";
proxy_set_header X-Forwarded-Host "";
proxy_set_header X-Forwarded-Proto "";
}

# ClawMate
location /mate/ {
proxy_pass http://127.0.0.1:8080/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For "";
proxy_set_header X-Real-IP "127.0.0.1";
proxy_set_header X-Forwarded-Host "";
proxy_set_header X-Forwarded-Proto "";
}

# ClawApp
location /app/ {
proxy_pass http://127.0.0.1:3210/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For "";
proxy_set_header X-Real-IP "127.0.0.1";
proxy_set_header X-Forwarded-Host "";
proxy_set_header X-Forwarded-Proto "";
}

# OpenCode
location /opencode/ {
proxy_pass http://127.0.0.1:4096/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For "";
proxy_set_header X-Real-IP "127.0.0.1";
proxy_set_header X-Forwarded-Host "";
proxy_set_header X-Forwarded-Proto "";
}

# 日志
access_log /var/log/nginx/claw-tunnel-access.log;
error_log /var/log/nginx/claw-tunnel-error.log;
}

2. 关键配置说明

代理头处理

配置项 作用 说明
proxy_set_header X-Forwarded-For 禁用转发头 "" (空字符串) 完全禁用
proxy_set_header X-Real-IP 覆盖客户端 IP "127.0.0.1" 固定本地 IP
proxy_set_header X-Forwarded-Host 禁用转发 Host "" 避免配置冲突
proxy_set_header X-Forwarded-Proto 禁用转发协议 "" 避免协议冲突

为什么需要禁用代理头?

  1. Cloudflare 添加代理头:Cloudflare 会将真实的公网 IP 添加到 X-Forwarded-For
  2. Gateway 检测机制:OpenClaw Gateway 检测到 X-Forwarded-For 有值,就视为来自”不信任的代理”
  3. 结果:WebSocket 连接被拒绝(4008 错误)

解决方案

  • 完全禁用所有代理头(设置为空字符串)
  • Gateway 检测不到代理头,就不会触发”不信任的代理”检测

Gateway 配置

1. 配置文件结构

配置文件位置

1
~/.openclaw/openclaw.json

2. 关键配置

allowedOrigins(允许的来源)

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"gateway": {
"controlUi": {
"allowedOrigins": [
"https://10.28.9.66",
"http://10.28.9.66",
"https://127.0.0.1:18789",
"http://127.0.0.1:18789",
"https://your-domain.com"
]
}
}
}

配置说明

  • ✅ 已添加外网域名 https://your-domain.com
  • ✅ 本地访问地址已配置
  • ✅ Gateway 已重启,配置生效

故障排查 1:WebSocket 4008 错误(origin not allowed)

1. 错误现象

1
2
3
WebSocket 连接失败(code=4008)
错误信息:origin not allowed
日志:Proxy headers detected from untrusted address

2. 问题分析

根本原因

问题链条

  1. Cloudflare 添加代理头

    • Cloudflare 隧道会将真实的公网 IP 添加到 X-Forwarded-For
    • 例如:X-Forwarded-For: 8.221.172.1
  2. Nginx 传递代理头

    • Nginx 默认会将所有接收到的代理头传递给后端
    • 包括 Cloudflare 添加的 X-Forwarded-For
  3. Gateway 检测机制

    • OpenClaw Gateway 检测到 X-Forwarded-For 头有值
    • 如果有值,就视为来自”不信任的代理”
    • 拒绝连接(4008 错误)
  4. origin 验证失败

    • allowedOrigins 列表中缺少外网域名
    • 或者 Gateway 的 bind 模式配置错误

3. 调试过程(PDCA)

Plan(计划)

问题:解决 WebSocket 4008 错误

分析

  • 错误信息:origin not allowed
  • 日志显示:Proxy headers detected from untrusted address
  • 根本原因:Gateway 检测到代理头

方案

  1. 禁用 Nginx 的 301 重定向
  2. 配置 trustedProxies(信任 Cloudflare IP)
  3. 添加外网域名到 allowedOrigins
  4. 修改 X-Forwarded-For

Do(执行)

操作 1:禁用 301 重定向

1
2
3
4
5
# 查找 301 重定向
grep -r "return 301" /etc/nginx/sites-available/claw-tunnel

# 注释掉 301 重定向
sudo sed -i 's|^ # return 301|# # return 301|' /etc/nginx/sites-available/claw-tunnel

结果:❌ 问题仍然存在

分析

  • 问题不是 301 重定向导致的

操作 2:配置 trustedProxies

1
2
3
4
5
6
7
8
9
10
11
12
13
# 备份配置
cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.backup.trusted-proxies

# 修改配置(添加 Cloudflare IP 范围)
cat ~/.openclaw/openclaw.json | jq '
.gateway.trustedProxies = [
"104.16.0.0/12",
"2606:4700::/48"
]
' > /tmp/openclaw-new.json

# 应用新配置
mv /tmp/openclaw-new.json ~/.openclaw/openclaw.json

结果:❌ 问题仍然存在

日志分析

1
2
Proxy headers detected from untrusted address
fwd=8.221.172.1 (仍然是真实 IP)

分析

  • 即使添加了 Cloudflare IP 范围,仍然失败
  • 可能原因:实际 IP 不在范围内

操作 3:添加域名到 allowedOrigins

1
2
3
4
5
6
7
8
9
10
11
12
13
# 修改配置(添加外网域名)
cat ~/.openclaw/openclaw.json | jq '
.gateway.controlUi.allowedOrigins = [
"https://10.28.9.66",
"http://10.28.9.66",
"https://127.0.0.1:18789",
"http://127.0.0.1:18789",
"https://your-domain.com"
]
' > /tmp/openclaw-new.json

# 应用新配置
mv /tmp/openclaw-new.json ~/.openclaw/openclaw.json

结果:❌ 问题仍然存在

分析

  • 仅仅添加域名是不够的,仍然检测到代理头

操作 4:修改 X-Forwarded-For 头

1
2
3
4
5
6
7
8
# 修改 Nginx 配置,设置固定本地 IP
sudo sed -i 's|proxy_set_header X-Forwarded-For .*;|proxy_set_header X-Forwarded-For "127.0.0.1";|' /etc/nginx/sites-available/claw-tunnel

# 测试配置
sudo nginx -t

# 重载 Nginx
sudo nginx -s reload

结果:❌ 问题仍然存在

日志分析

1
2
fwd=127.0.0.1 (已设置为本地 IP)
Proxy headers detected from untrusted address

分析

  • Gateway 仍然检测到代理头
  • 说明:即使设置为本地 IP,只要有值就会触发检测

Check(检查)

验证方法

  1. 查看 Gateway 日志
  2. 查看错误是否消失

结果

  • ❌ 错误仍然存在
  • 需要继续尝试下一个方案

Act(行动)

下一个方案:完全禁用所有代理头


4. 最终解决

方案 5:完全禁用所有代理头(✅ 成功)

操作:完全禁用所有代理头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 修改 Nginx 配置,禁用所有代理头
sudo sed -i 's|proxy_set_header X-Forwarded-For .*;|proxy_set_header X-Forwarded-For "";|' /etc/nginx/sites-available/claw-tunnel

# 确保禁用 X-Forwarded-Host 和 X-Forwarded-Proto
sudo sed -i 's|proxy_set_header X-Forwarded-Host .*;|proxy_set_header X-Forwarded-Host "";|' /etc/nginx/sites-available/claw-tunnel

sudo sed -i 's|proxy_set_header X-Forwarded-Proto .*;|proxy_set_header X-Forwarded-Proto "";|' /etc/nginx/sites-available/claw-tunnel

# 测试配置
sudo nginx -t

# 重载 Nginx
sudo nginx -s reload

# 查看配置
grep -A 5 "proxy_set_header" /etc/nginx/sites-available/claw-tunnel

验证

1
2
3
4
# 预期输出(所有代理头都设置为空字符串)
# proxy_set_header X-Forwarded-For "";
# proxy_set_header X-Forwarded-Host "";
# proxy_set_header X-Forwarded-Proto "";

日志验证

1
2
3
4
5
6
# 查看 Gateway 日志
journalctl --user -u openclaw-gateway -n 20

# 预期结果
# fwd=n/a (无代理头)
# webchat connected (WebSocket 连接成功)

结果:✅ 成功!

关键发现

  • Gateway 检测代理头是基于 X-Forwarded-For 是否有值
  • 只有完全禁用代理头(设置为空字符串),才能避免检测

故障排查 2:设备配对(pairing required)

1. 错误现象

1
2
错误信息:This device needs pairing approval from the gateway host.
访问被拒绝

2. 问题分析

根本原因

OpenClaw 安全机制

  • OpenClaw Gateway 默认启用设备配对功能
  • 首次访问的设备需要手动批准
  • 批准后才能正常访问

配对流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1. 首次访问 → Pending 状态
- 用户看到授权页面
- 设备处于待批准状态

2. 查看设备列表
- 使用 `openclaw devices list` 查看所有设备
- 找到待批准的设备

3. 批准设备配对
- 使用 `openclaw devices approve <requestId>` 批准设备
- 输入设备请求 ID(从列表中获取)

4. 正常访问
- 已配对的设备变为 Paired 状态
- 无需再次配对

3. 解决方案

批准设备配对

命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 查看设备列表
openclaw devices list

# 输出示例
# ┌──────────────────────────────┬──────────────────────────────────┬────────────┬────────────┬────────────┐
# │ Request │ Device │ Role │ Scopes │ Tokens │ IP │ Age │ Flags │
# ├──────────────────────────────┼──────────────────────────────────┼────────────┼────────────┤
# │ 61750831-ea3a-4f48-8810-b66ea82a8cba │ cc6dfce467574afabef118543947b1f23ed319634778222d31c49f924c650b49 │ operator │ │ │ │ │
# │ │ 3ed319634778222d31c49f924c650b49 │ │ pairing │ │ │ │
# └──────────────────────────────┴──────────────────────────────────┴────────────┴────────────┘
#
# Pending (1)
# ┌──────────────────────────────┬──────────────────────────────────┬────────────┬────────────┐
# │ Request │ Device │ Role │ IP │ Age │ Flags │
# ├──────────────────────────────┼──────────────────────────────────┼────────────┼────────────┤
# │ 61750831-ea3a-4f48-8810-b66ea82a8cba │ cc6dfce467574afabef118543947b1f23ed319634778222d31c49f924c650b49 │ operator │ │ │ │ │
# └──────────────────────────────┴──────────────────────────────────┴────────────┴────────────┘
#
# 批准命令
openclaw devices approve 61750831-ea3a-4f48-8810-b66ea82a8cba

结果

  • ✅ 设备已从 Pending 变为 Paired
  • 可以正常访问

最终配置

1. Nginx 最终配置

1
# 同上文完整配置文件

2. Gateway 最终配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"gateway": {
"mode": "local",
"bind": "lan",
"trustedProxies": [
"104.16.0.0/12",
"2606:4700::/48",
"claw.nuaa.us.to"
],
"controlUi": {
"enabled": true,
"basePath": "/openclaw",
"allowedOrigins": [
"https://10.28.9.66",
"http://10.28.9.66",
"https://127.0.0.1:18789",
"http://127.0.0.1:18789",
"https://your-domain.com"
]
}
}
}

关键经验

经验 1:trustedProxies vs allowedOrigins

配置项 作用 验证对象
trustedProxies 信任的代理服务器 X-Forwarded-For 头中的 IP
allowedOrigins 允许访问的来源 Origin 头中的域名

关键教训

  • 添加域名到 trustedProxies 无效(IP ≠ 域名)
  • 必须添加域名到 allowedOrigins 才能解决 origin 验证问题
  • 两者的验证对象不同,不能混用

经验 2:Nginx 代理头处理

| 配置变更历程 | 结果 |
|——|——|——|
| 保留 X-Forwarded-For 头 | ❌ 失败 |
| 设置 X-Forwarded-For 为固定本地 IP | ❌ 失败 |
| 禁用 X-Forwarded-For 头(设置为空字符串) | ✅ 成功 |

关键教训

  • Gateway 检测代理头是基于 X-Forwarded-For 是否有值
  • 即使设置为本地 IP(127.0.0.1),仍然会被检测为代理
  • 必须完全禁用代理头(设置为空字符串 ""),才能避免检测

经验 3:OpenClaw 设备配对

配对流程

1
2
3
4
1. 首次访问 → Pending 状态
2. 查看设备列表 → 找到待批准设备
3. 批准设备配对 → Paired 状态
4. 正常访问 → 无需再配对

命令

1
2
3
4
5
# 查看设备列表
openclaw devices list

# 批准设备
openclaw devices approve <requestId>

关键教训

  • 外网访问需要设备配对(安全机制)
  • 使用 openclaw devices listopenclaw devices approve 管理设备
  • 已配对的设备可以永久访问,无需再次配对

总结

成功标志

指标 结果
cloudflared 安装 ✅ 完成
Nginx 安装 ✅ 完成
Nginx 配置 ✅ 完成
Gateway 配置 ✅ 完成
设备配对 ✅ 完成
WebSocket 连接 ✅ webchat connected
HTTP 访问 ✅ 200 OK
外网访问 ✅ 成功

项目价值

  1. ✅ 外网可以访问所有应用(WebChat、ClawMate、ClawApp、OpenCode)
  2. ✅ HTTPS 安全访问(Cloudflare SSL 证书)
  3. ✅ 全球 CDN 加速(Cloudflare)
  4. ✅ 稳定可靠(HTTP2 协议)

适用场景

此方案适用于:

  • ✅ 内网环境需要外网访问
  • ✅ 需要 HTTPS 和 CDN 加速
  • ✅ 使用 OpenClaw Gateway 的应用
  • ✅ 需要访问多个内部服务

相关资源


发布日期:2026-03-06
版本:v1.1
作者:小瑞
技术栈:Cloudflare + Nginx + OpenClaw Gateway


Cloudflare 隧道 + OpenClaw Gateway:实现外网访问完整指南 v1.1
https://www.normdist.com/2026/03/06/cloudflare-tunnel-guide-v1.1/
作者
小瑞
发布于
2026年3月6日
许可协议