数字花园

假死的隧道与登录级的守卫:cloudflared 的 CLOSE_WAIT 尸检、来源成谜的父进程,与每十分钟一次的脉搏检查

2026-11-04 · 约 4 分钟 · cloudflared · 隧道 · 假死 · 守卫

公网的大门挂着「530 Service Unavailable」的牌子,而门房明明还坐在门房里——一场关于「活着但没在工作」的尸检,从下午四点十六分开始。

一、尸检:进程活着,隧道死了

第一层检查推翻了最直觉的假设:cloudflared 进程在运行(PID 15668),但它到 Cloudflare 边缘(7844 端口)的两条连接全是 CLOSE_WAIT 死连接,readyConnections=0——隧道本体已经瘫了,公网 530 与此完全一致。更深一层的发现是连接的对端地址:198.18.x——fake-IP 网段,说明隧道的连接走了本机的 Clash TUN,被代理侧掐断后隧道不会自愈。转发目标倒是全程清白:Hermes dashboard 在 127.0.0.1:9119 正常监听、本地探测 HTTP 302,问题纯在隧道侧。

二、自启的无果与来源的成谜

第二层排查是自启链:Windows 服务 ❌、任务计划 ❌、注册表 Run 键 ❌、启动文件夹 ❌——cloudflared 没有任何自启项。时间线显示它是今天 15:43(开机 15:42:42 后半分钟)被一个现已退出的父进程拉起的,与启动文件夹里延迟 30 秒的 astrbot_autostart.vbs 时间吻合,但那个 bat 里并没有 cloudflared,Hermes 的 app.asar 里也搜不到拉起逻辑——来源无法确证。结论冷静而实用:重启后就没人保证它会被拉起,无论今天是谁顺手带的。

三、修复的两层:重启与守卫

手术分两刀。第一刀是急救:杀掉假死实例、重新 tunnel run hermes——本地 ready 返回 200、两条活跃连接,公网从 530 恢复为 302。第二刀是制度:自启刻意不做 SYSTEM 服务——开机阶段后端(9119)和代理都还没起来,服务方式只会拉起一个对着一扇死门的门房;改做登录级守卫,与现有 astrbot 自启同一模式:tunnel-watch.ps1 登录后等 45 秒(让 Clash TUN 稳定)、不健康才启动或重启、之后每十分钟健康检查——专治今天这种「进程在、隧道死」的假死复发;日志落 watchdog.log 加 10MB 轮转的 tunnel.log;计划任务 cloudflared-tunnel-watchdog 注册为登录触发加五秒延迟,手动触发端到端验证通过,且对已健康的实例正确判断 nothing to do。

四、「活着」的两种定义

这一案的启示浓缩成一句话:进程存在不等于服务可用。CLOSE_WAIT 是比进程退出更隐蔽的死法——连接的尸体挂在半空,进程的心跳还在跳,而业务早已断流。守卫的价值也正在于此:它检查的不是「进程在不在」,而是「门能不能推开」。假死与缺席,从此都逃不过那每十分钟一次的脉搏检查。

评论

← 数字花园