对话笔记直发:8.21 Open WRT OpenClash中cloudflared隧道修复记录。分类:AI工程。

jp NAS Cloudflare 隧道故障修复记录

  • 设备:jp(局域网 NAS,IP 局域网IP(已脱敏),aarch64 Linux)
  • 现象:某天所有经 Cloudflare 隧道映射的外网域名(ha / pan / notes / vikunja / komari / openclaw / radicale / freshrss / 3566 等 *.unixcs.eu.org)集体无法访问。
  • 时间:2026-08-22
  • 结论:根因在路由器 OpenClash,不在 NAS 本机;修复靠把 cloudflared 协议从 quic 改为 http2。

一、排查过程(逐步定位)

1. 隧道进程还活着,但连不上边缘

  • cloudflared 进程(systemd 服务)在运行,但日志满屏报错:
    failed to dial to edge with quic: timeout: no recent network activity
    
  • 日志里 edge IP 是 198.18.x.x —— 这是 fake-ip 测试网段,绝不是 Cloudflare 真实边缘 IP(真实段如 198.41.192.x)。

2. 确定 fake-ip 的来源

在 NAS 上用 Python 直连 4 个不同 DNS 服务器解析 region1.v2.argotunnel.com,全部返回 198.18.0.24:

  • 局域网IP(已脱敏)(OpenWRT/OpenClash)
  • 100.100.100.100(Tailscale)
  • 8.8.8.8
  • 1.1.1.1

连公共 DNS 都被劫持成 fake-ip,说明 DNS 劫持发生在路由器这一层(OpenClash 拦截了所有出网 UDP 53)。

佐证:

  • NAS 本机没有任何进程监听 53;
  • NAS 的 iptables nat 表没有把 DNS/流量 redirect 到本机 sing-box;
  • 子代理登进路由器确认 OpenClash 配置:operation_mode=fake-ip、en_mode=fake-ip-mix、redirect_dns=1、disable_udp_quic='1'。

注意:NAS 的 /etc/resolv.conf 被 Tailscale 改成了 100.100.100.100,并不是 OpenWRT。但 OpenClash 是”拦截所有出网 53”的做法,所以无论 resolv.conf 写谁,最终都被它劫成 fake-ip。

3. 根因机制

  • OpenClash 对 CF 隧道域名返回 fake-ip 198.18.x.x;
  • cloudflared 默认用 quic(UDP) 连 Cloudflare 边缘;
  • OpenClash 配置里 disable_udp_quic='1',显式丢弃 QUIC(UDP);
  • 于是 cloudflared 发出的 UDP 包目的地址是死地址 198.18.x.x,永远超时 → 隧道全断。

4. 一个被推翻的误判

最初一度以为 fake-ip 来自 NAS 本机的 sing-box 代理,并加了 HTTPS_PROXY=http://127.0.0.1:7890 让 cloudflared 走本机 sing-box。后来经子代理复核证明:该环境变量根本没进数据通路——ss 显示 cloudflared 边缘连接只连 198.18.x.x:7844(由 OpenClash 还原),没有任何连接指向 127.0.0.1:7890。所以”走本机 sing-box”是多余的,已移除。


二、如何修复(最终方案)

真正起作用的只有一处改动:把 cloudflared 协议从 quic 改成 http2(TCP),绕开 OpenClash 对 QUIC 的封杀,由 OpenClash 还原 fake-ip 后正常建连。

修改 1:/etc/cloudflared/config.yml 顶层加一行

protocol: http2

(文件原有 tunnel: / credentials-file: / ingress: 段,在顶层追加即可。)

修改 2:systemd 服务里不要加 HTTPS_PROXY

/etc/systemd/system/cloudflared.service 的 [Service] 段保持干净,不要加 Environment=HTTPS_PROXY=...(那一层 sing-box 代理是多余的,且会引入”sing-box 挂 → cloudflared 跟着挂”的连锁故障)。

重启并验证

systemctl daemon-reload
systemctl restart cloudflared

日志出现即成功:

INF Registered tunnel connection connIndex=0 ... protocol=http2
INF Registered tunnel connection connIndex=1 ... protocol=http2

三、测试验收

  • 服务状态:systemctl is-active cloudflared → active
  • 隧道连接数:cloudflared tunnel list → vaultwarden-3566 有 2 个连接(如 1xicn01, 1xnrt01)
  • 对外连接:ss -tnp | grep cloudflared 只连 198.18.x.x:7844(经 OpenClash 还原),无 127.0.0.1:7890
  • 端到端回路(NAS 本地 curl 各域名):ha/pan/vikunja/komari → 200;notes/radicale/freshrss → 302(正常重定向)

唯一例外 openclaw.unixcs.eu.org 返回 502,与隧道无关——是其本地后端 127.0.0.1:18789 没启动(端口无监听、容器未运行)。见下文”附带清理”。


四、后续如何避免(运维建议)

  1. 保住 protocol: http2:以后这台 NAS 的 cloudflared 若重装/重置配置,记得把 config.yml 的 protocol: http2 加回来,否则默认 quic 又会撞上 OpenClash 禁 QUIC 而全断。
  2. 别用 pkill -f cloudflared 启停服务:该命令会匹配到正在执行命令的 shell 自身(命令行含 “cloudflared”),导致当前 shell 被误杀、后续命令全不执行。统一用 systemctl stop/start/restart cloudflared。
  3. 快速判断故障:再遇 CF 域名全挂,先看 cloudflared 日志是不是 quic timeout + edge IP 198.18.x.x。是的话就是这套老问题,确认 protocol: http2 在即可;日志出现 Registered tunnel connection 即恢复。
  4. 可选加固(不建议做):去路由器 OpenClash 把 *.argotunnel.com 加进 fake-ip 绕过/直连名单,让 DNS 返回真实 CF IP,cloudflared 就能改回 quic。但当前 http2 已完全正常,收益可忽略、且动全局代理配置有风险,维持现状即可。
  5. OpenClash 侧风险:本机所有出网 DNS 被 OpenClash 劫持成 fake-ip,任何”默认走 UDP/quic 且依赖真实 IP”的软件都可能中招。遇到类似”连不上”的软件,优先怀疑是否被 fake-ip + 禁 QUIC 影响。

五、附带清理(openclaw / picoclaw 尾巴)

用户曾安装 openclaw 与 picoclaw(容器名 picoclaw-launcher),后来已清掉 docker 部分。本次顺手清掉残留尾巴:

  • 已不在:docker 容器、镜像、卷、网络、systemd 服务(之前就清干净了)
  • 本次删除的尾巴:
    • /root/openclaw-backup 目录
    • /root/picoclaw 目录
    • /root/picoclaw_deploy_note.md 文件
    • cloudflared config.yml 里 openclaw.unixcs.eu.org 的 ingress 死规则(指向已亡的 127.0.0.1:18789)
  • 删除 ingress 后重启隧道验证:服务仍 active、连接数 2、ha/pan 仍 200,未影响其他域名。
  • 现状:openclaw.unixcs.eu.org 访问会走 cloudflared 的 404 兜底(不再指向死后端)。若要该域名彻底消失,需去 Cloudflare 后台删 DNS 记录(不在 NAS 侧)。

六、本次排障踩的坑(备忘)

  • pkill -f cloudflared 会自杀式杀掉执行命令的 shell,导致后续命令无输出(多次”空输出”的元凶)。改用 systemctl。
  • cloudflared 2026.3.0 没有 --proxy 命令行参数(只有 --proxy-dns),想让它走代理要用 HTTPS_PROXY 环境变量——但本例最终证明根本不需要走。
  • 直连 CF 边缘 IP 用 curl 测会显示 000/TLS 握手失败,容易误判为”网络不通”;实际 TCP 层可能已连接,只 IP 当 SNI 导致 TLS 失败。判断连通性要看 TCP 层而非 HTTPS 应用层。

附加(2026-08-22 晚上):http2 依旧失败的第二次故障 + /etc/hosts pin 修复

白天把 protocol 改为 http2 修好;当晚隧道再次全断。日志不再是 quic,而是:

ERR TLS handshake with edge error="EOF"
ERR Connection terminated error="there are no free edge addresses left to resolve to"

连接的仍是 fake-ip 198.18.x.x。此时 http2 也救不回:DNS 层 fake-ip 已把 region1.v2.argotunnel.com 毒化,cloudflared 解析不到真实 CF 边缘。

根因:cloudflared 解析 region1.v2.argotunnel.com 被 OpenClash fake-ip 毒化返回 198.18.x;本环境所有出网 DNS 都被 OpenClash 劫持(连 1.1.1.1 / Tailscale 100.100.100.100 直问都返回 fake-ip)。

本次新增且有效的修复(在 NAS 自身,无需动路由器)——把 argotunnel 边缘 host 钉到真实 CF anycast IP:

# /etc/hosts 追加(先备份)
cp /etc/hosts /etc/hosts.bak-$(date +%Y%m%d-%H%M%S)
printf "`你的服务器IP(已脱敏)` region1.v2.argotunnel.com\n198.41.192.27 region1.v2.argotunnel.com\n" >> /etc/hosts
systemctl restart cloudflared
# 验证:日志出现 Registered tunnel connection ... location=icn06 ... protocol=http2

真实 IP 通过 CF DoH 获取(绕过 fake-ip):

curl -s "https://1.1.1.1/dns-query?name=region1.v2.argotunnel.com&type=A" -H "accept: application/dns-json"

备忘:真实 CF 边缘 anycast IP 出自 198.41.192.x,较稳定;若日后又断先按上面刷新 hosts。

顺带本次改动

  • 在 cloudflared 已添加公网路由:n8n.unixcs.eu.org -> http://127.0.0.1:5678(Cloudflare 边缘终结 TLS,NAS 侧纯内网 HTTP);DNS CNAME 由 cloudflared tunnel route dns 74dd8243-... n8n.unixcs.eu.org 建立。

注:本文涉及的服务器公网 IP / Tailnet / 局域网 IP 已脱敏,请替换为你自己的地址。


相关: 00-索引-AI工程索引 8.16 路由器OpenClash代理与hindsight单层化