内网穿透失败?Cloudflare Tunnel 常见问题汇总

内网穿透失败?Cloudflare Tunnel 常见问题汇总

背景

我上个月写了《如何使用 Cloudflare Tunnel 暴露本地 AI 服务》的教程,后台收到二十几条私信,问题惊人地一致——不是配置错,而是同样的报错背后有完全不同的根因。这篇把我自己和读者踩过的坑汇总成 6 个高频问题,按「现象 → 排查 → 解决」三段式整理,附带可以直接复制粘贴的命令。如果你正在隧道里挣扎,建议先对照这篇做一遍自检,大概率能省掉两小时翻 GitHub issue 的时间。

问题一:502 Bad Gateway,但隧道显示 Connected

现象:浏览器访问域名返回 502,cloudflared tunnel run 日志里却明明白白写着 Connected to tunnel

排查

# 1. 确认 ingress 规则是否匹配到 hostname
sudo -u cf-tunnel cloudflared tunnel ingress validate \
  /home/cf-tunnel/.cloudflared/<tunnel-id>.yml
# 如果输出 "No ingress rules matched",说明 hostname 写错了

# 2. 检查 DNS 记录是否绑定到隧道
cloudflared tunnel route dns list | grep <你的域名>
# 应该看到 CNAME 指向 <tunnel-id>.cfargotunnel.com

# 3. 确认目标服务是否真的在监听
curl -I http://127.0.0.1:8000/health
# 如果这里也连不上,问题在 vLLM/本地服务,不在隧道

解决:90% 的 502 是因为 DNS 控制台的 CNAME「代理状态」设成了灰色 OFF(直连模式)。必须改成橙色 ON(经过 Cloudflare 边缘节点 + 隧道)。改完后等 30 秒到 2 分钟,别急着刷新。

问题二:隧道启动后过一会儿自动断开

现象:刚启动时正常,10 分钟到 2 小时后日志出现 connection closed by remote,服务不可访问。

排查

# 查看系统日志找线索
journalctl -u cloudflared -n 50 --no-pager
# 或看 cloudflared 自己的日志
tail -n 100 /var/log/cloudflared.log | grep -i "error\|fail\|close"

# 检查是否被系统自动杀掉(OOM)
dmesg | grep -i "killed process.*cloudflared"
# 或者
cat /var/log/syslog | grep "Out of memory"

解决:我遇到的三个根因:

  1. cloudflared 自动更新导致重启:默认每 24 小时检查更新,更新过程会断开 3-5 秒。解法:启动时加 --no-autoupdate,或者用 systemd 服务配 Restart=always
  2. 系统 OOM Killer 介入:cloudflared 本身不占多少内存,但如果同一台机器还跑着 vLLM + GPUStack,系统内存紧张时会优先杀「看起来不重要」的隧道进程。解法:给 cloudflared 进程加 OOM 分数保护 echo -1000 | sudo tee /proc/$(pgrep cloudflared)/oom_score_adj
  3. 路由器 NAT 会话超时:某些家用路由器(尤其是小米、TP-LINK 老固件)的 UDP 会话 15 分钟无活动就断开,而 cloudflared 默认 keepalive 是 30 秒——但如果网络瞬间抖动,keepalive 包丢了,路由器直接清会话。解法:在路由器里找「NAT 会话超时」设成 3600 秒,或改 cloudflared 配置加 heartbeat-interval: 15s

问题三:HTTPS 证书错误(ERR_SSL_VERSION_OR_CIPHER_MISMATCH)

现象:电脑浏览器正常,手机 Safari 或旧安卓设备打不开,提示证书相关错误。

排查

# 检查服务器支持的 TLS 版本
openssl s_client -connect 你的域名:443 -tls1_2
# 如果握手失败,说明服务器强制 TLS 1.3

# 检查证书链是否完整
openssl s_client -connect 你的域名:443 -showcerts | openssl x509 -noout -text | grep -A2 "Subject Alternative Name"
# 应该看到你的域名在 SAN 列表里

解决:Cloudflare 默认强制 TLS 1.3,但 iOS 12 以下和部分国产安卓浏览器只支持到 1.2。登录 Cloudflare 控制台 → SSL/TLS → Overview → 把「Minimum TLS Version」从 1.3 改成 1.2。改完 30 秒内生效,不用重启隧道。

问题四:DNS 记录添加后一直不生效

现象:在 Cloudflare DNS 控制台加了 CNAME,但 dignslookup 查不到,或者指向旧的 IP。

排查

# 直接用 Cloudflare 的 DNS 查
dig @1.1.1.1 你的域名 CNAME +short
# 应该返回 <tunnel-id>.cfargotunnel.com

# 如果返回空,检查记录类型是不是 A 而不是 CNAME
# 很多人手滑选了 A 记录,填了 tunnel ID,这肯定不行

# 检查域名 NS 是否指向 Cloudflare
whois 你的域名 | grep "Name Server"
# 必须看到 *.cloudflare.com,否则 DNS 请求根本没到 CF

解决:如果域名 NS 不在 Cloudflare,你需要去域名注册商(阿里云、GoDaddy 等)把 NS 改成 Cloudflare 提供的两个地址。NS 切换全球生效需要 1-48 小时,但通常 10 分钟内就能看到变化。切换期间服务会中断,建议低峰期操作。

问题五:内网能 curl 通,外网返回 404

现象:服务器上 curl http://localhost:8000/v1/chat/completions 正常,但通过隧道域名访问返回 404。

排查

# 1. 确认 ingress 里的 service 地址不是 localhost
# 错误:service: http://localhost:8000
# 正确:service: http://127.0.0.1:8000
# cloudflared 以 cf-tunnel 用户运行,localhost 可能解析到 ::1(IPv6)而你的服务只绑了 0.0.0.0

# 2. 检查 vLLM 是否绑定了正确的接口
netstat -tlnp | grep 8000
# 应该看到 0.0.0.0:8000 或 127.0.0.1:8000
# 如果只看到 :::8000(IPv6),隧道可能连不上

解决:把 ingress 配置里的 localhost 全部换成 127.0.0.1,同时确保本地服务监听 0.0.0.0127.0.0.1(而不是 192.168.x.x 这种内网 IP,隧道进程看不到)。重启隧道后测试。

问题六:日志一切正常,但某些地区访问超时

现象:你自己访问没问题,北京的朋友能打开,但上海和深圳的同事超时。

排查

# 用多地 ping 工具检查(比如 boce.com 或 ping.chinaz.com)
# 如果某些节点超时,说明 Cloudflare 边缘节点到隧道的路由有问题

# 检查隧道连接的是哪个 CF 数据中心
cloudflared tunnel info <tunnel-name>
# 看 "Connections" 列表里的 colo 字段
# 如果你在中国内地,隧道大概率连的是 HKG(香港)或 NRT(东京)节点

解决:这不是你配置的问题,是 Cloudflare 免费版在中国大陆的网络质量不稳定(国际出口拥塞)。三个缓解方案:

  1. 升级 Cloudflare Pro($20/月),走更优质的骨干网路由;
  2. 在隧道配置里加 max-fetch-size: 100MBtimeout: 600s,给长连接更多容错时间;
  3. 如果主要用户在国内,考虑用国产替代方案(如花生壳、natapp)做备份线路,Cloudflare Tunnel 做海外访问。

我的排错清单(建议保存)

每次隧道出问题,按这个顺序查:

  1. 本地服务还在跑吗?curl http://127.0.0.1:8000/health
  2. 隧道进程还在吗?ps aux | grep cloudflared
  3. DNS 解析对吗?dig @1.1.1.1 你的域名 CNAME +short
  4. CNAME 代理状态是 ON 吗?Cloudflare 控制台 → DNS → 橙色云
  5. ingress 规则匹配吗?cloudflared tunnel ingress validate
  6. 证书有问题吗?openssl s_client -connect 你的域名:443
  7. 换个网络试试(手机 4G),排除本地缓存干扰

这七步走完,99% 的隧道问题都能找到根因。如果还是不行,把 cloudflared tunnel run 的完整日志(加 --loglevel debug)贴到 Cloudflare Community,一般 24 小时内有人回。