基础工具与工作流 · daymade/claude-code-skills

tunnel-doctor

Diagnoses concrete tunnel and proxy-path failures across macOS and Windows/WSL: Tailscale routing, proxy env/system bypass, SSH double tunneling, VM/container propagation, stalled DNS, TUN DIRECT split-brain, Windows-host TUN cascades, and single-hop or chained proxy node/exit throughput. Use when Tailscale ping works but SSH/HTTP fails, browser returns 503 while curl works, Git SSH closes through the proxy, Docker pull/build fails behind TUN, getaddrinfo stalls while nslookup is fast, raw probes report physically impossible results, domestic DIRECT-routed sites fail while proxied sites work, a blocked port could be your tunnel or the destination's firewall, or the proxy is reachable but real downloads and full Git clones crawl. Also use when Git reports "failed to begin relaying via HTTP", ssh -vvv freezes at "debug2: resolving", ping works but dig times out, or setting up Tailscale SSH to WSL. Use debugging-network-issues only when the root cause remains unknown or belongs to an application/protocol layer.

风险提醒:橙色 · 评估后使用AI 侦查报告
作者 daymadeGitHub daymade/claude-code-skills ↗Stars 1392许可 MIT(仓库根 LICENSE,Copyright (c) 2025 daymade;GitHub API spdx MIT)commit d5c4678cb5
agent 宿主通常会约束 skill 执行权限;风险提醒为 AI 侦查观点,不构成质量或安全保证。第三方 skill 仅作拆解与展示,安装使用风险自负,版权归原作者。

1实现原理 · 为什么它能做到

它把「Tailscale 与代理/VPN 共存」的冲突按网络栈层级拆成 5 层,每层标注「什么坏了 / 什么还好 / 根因」,用「谁还在工作」反推故障层——这是整个 skill 的诊断骨架。

tunnel-doctor/SKILL.md
| Layer | What breaks | What still works | Root cause | |-------|-------------|------------------|------------| | 1. Route table | Everything (SSH, curl, browser) | `tailscale ping` | `tun-excluded-routes` adds `en0` route overriding Tailscale utun |
注:配套的关键判据:'SSH does NOT use `http_proxy`/`NO_PROXY` env vars. If SSH works but HTTP doesn't → Layer 2.' 与 '`curl` uses `http_proxy` env var, NOT the system proxy.'

它的核心方法论是「先验证组件自己的健康端点,别从旁证下结论」——因为多层可以产生重叠症状,先跳到最具体的验证可以避免钻进错误的一层。

tunnel-doctor/SKILL.md
When symptoms point at a component (proxy, VPN, route table, DNS), **don't commit to a hypothesis from circumstantial evidence — verify with that component's own health endpoint first.**
注:同节的因果说明:'A symptom that matches the description of Step 2X does not, by itself, prove component X is the problem.' 并给出组件→健康检查对照表(proxy 用 curl -x、Tailscale 用 tailscale status、DNS 用 dig @ns)。

针对 TUN 全局模式下「探针会撒谎」这一现象,它给出可判定的证伪标准:0.00s 的跨洋连接、亚毫秒 ping 在物理上不可能,因此测到的是本地 TUN 而非网络。

tunnel-doctor/SKILL.md
**Counter-move**: before citing any latency / reachability number while a TUN is up, ask *"would this number be physically possible if the packet really traversed to the destination?"* A `0.00s` connect or a `0.2ms` ping to another continent is the tell that you measured the TUN, not the network.
注:它同时列出「在 TUN 下可以信的东西」:curl 的 time_appconnect/time_starttransfer、境内 IP-geo 源、以及从磁盘解出的代理配置 + 工具自身 GUI。

对同一句错误信息给出两套互斥解释并要求先做区分实验:198.18.x.x 只证明有 TUN,不证明 fake-IP 导致了失败;(A) 协议误判与 (B) 转发路径间歇性抖动需要相反的修法。

tunnel-doctor/SKILL.md
**First, a warning about this symptom**: the `198.18.x.x` in the error message is **not evidence that fake-IP caused the failure**. Under TUN, *every* hostname resolves to a fake IP, so that address appears in the error whether the connection failed for this reason or any other.
注:区分手段是「同一代理路径跑 40 次普通 HTTPS 统计失败率」的循环,并给了量化数据点:'ssh -T [email protected]` succeeded 20/20 in a good window and failed roughly 15–20% of attempts in a bad one'。

它把「端口探测在 TUN 下全不可信」变成了一条必须先做的校准实验:探一个目标肯定不服务的端口,若也报开,则该机器上所有端口探测零信息量。

tunnel-doctor/SKILL.md
**First: stop trusting `nc -z`.** Under a TUN the local stack completes the TCP handshake on the destination's behalf, so `nc -z` succeeds for **every** port, including ports the destination has closed.
注:校准命令原文:nc -z -G 5 -w 5 <destination-ip> 65001 与对照组 203.0.113.199(RFC 5737 TEST-NET-3)。

「隧道还是对端防火墙」这个在客户端无法区分的问题,被要求走带外通道(云厂商 guest-agent)进入目标机取证,并给出「journalctl 而非 auth.log」的实测反例。

tunnel-doctor/SKILL.md
**Then ask the destination out-of-band.** The only way to settle "did my packets arrive?" is a channel that does not traverse the failing data path. On a cloud VM that is the provider's guest-agent control plane
注:配套实测警告:'On Ubuntu 24.04 the file still exists and still receives `CRON` and `sudo` lines, but `rsyslog` is not installed by default and **`sshd` writes nothing to it** — measured on a live 24.04 host: 90 lines in `auth.log`, 0 of them from `sshd`'

自带的快速诊断脚本把最常见的四类 macOS 冲突(env 代理、系统代理例外、直连/代理路径分裂、本地 TLS 信任)压成一条命令,并给出可判读的三行结论。

tunnel-doctor/SKILL.md
python3 scripts/quick_diagnose.py --host local.example.com --url https://local.example.com/health
注:判读规则原文:'- `direct=PASS` + `forced_proxy=FAIL` = host must bypass proxy (`skip-proxy` + `NO_PROXY`).' 与 '- `strict_tls=FAIL` + `direct=PASS` = path is reachable; trust issue only'。

对「破坏性网络变更」设了前置门:动 VPN/路由/服务之前必须先读 recovery 参考、先验证前置条件、先布好有界恢复手段,并明确「停成功/进程脱离/脚本末尾重启」都不算恢复证据。

tunnel-doctor/SKILL.md
Before any authorized VPN disconnect, app termination, route cutover, or service restart, read [network_change_recovery.md](references/network_change_recovery.md). Validate prerequisites before interruption, arm bounded recovery before the first disruptive action, and verify both the repaired path and the user's original network use. A successful stop command, a detached process, or a restart placed at the end of a script is not recovery evidence.
注:该 reference 的三段结构为 Before interruption / Execute and recover / Verify and finish。

2核心能力

01路由层冲突诊断与修复(proxy 抢占 Tailscale CGNAT 网段)
02NO_PROXY / skip-proxy 环境变量与系统代理例外修复(含 Go net/http 不支持 CIDR 的坑)
03TUN DIRECT split-brain 诊断(域名连接死、真实 IP + 正确 SNI 通)
04DNS getaddrinfo 链停滞的逐 nameserver 二分定位(nslookup 快但系统解析挂 60s)
05VM/容器代理传播修复(OrbStack/Docker Desktop 透明代理与 TUN 冲突、buildkit 直连、v2rayN 端口分裂)
06SSH 双隧道与 git over SSH 间歇失败处理(含只重试 key exchange 前失败的 wrapper 契约)
07Tailscale SSH 在 WSL 上的静默拦截修复(kex_exchange_identification + tcpdump 0 包判据)
08代理节点/出口/链路的容量诊断(单跳与多跳链,串行对比、真实客户端复测、原始工作负载重放)
09Windows 主机 TUN 级联故障(WSL + 其 Tailscale 一起掉)与事件日志时间线取证
10Tailscale 远程开发 SOP(proxy 安全的 Makefile、SSH 隧道目标、多端口转发、non-login shell 环境)

3外部依赖

类型依赖
clitailscale(status / ssh / up / version)
climacOS 网络诊断工具族(ifconfig / netstat / route / scutil / lsof / dscacheutil)
clicurl(含 -x 显式代理、--noproxy '*'、-w 计时模板)
clidig / nslookup(逐 nameserver 二分 DNS)
clinc / tcpdump / ss(端口探测与到达性取证,含 sudo tcpdump)
clissh / ssh -vvv / ssh -T(连通性与 git over SSH 诊断)
clidocker / docker build / docker run(VM 与容器代理传播诊断)
clipnpm(SOP 示例,含 npmmirror 镜像参数)
cli阿里云 CLI(aliyun ecs …,带外命令执行取证)
clijournalctl / grep(目标机日志取证;经带外通道执行)
apiShadowrocket 配置编辑器 API(读/写整份代理配置,LAN 内 HTTP)
network通用可达性目标(Google generate_204、api.github.com、alpine CDN)用于路径健康与容量测量
networkTailscale 官方站点(ACL 管理页与独立版安装包)
network本地/内网服务与 vanity 域名(文档中的占位目标,非固定端点)

4风险提醒 风险提醒:橙色 · 评估后使用

风险提醒:橙色 · 评估后使用
  • 会在用户的网络栈上做真实变更,误判可导致断网 — 改路由、改 skip-proxy/tun-excluded-routes、重启 Tailscale、WSL 侧 sudo snap remove/服务开关都在其能力范围内。文档要求先读 recovery 参考并布置有界恢复,但这是流程约束;在远程/无人值守机器上执行有失联风险。
  • 代理配置的读取与写回是高风险动作 — Shadowrocket 的 LAN HTTP 配置 API 可读整份配置(含节点凭据),写回时若用 -d 而非 --data-binary 会因 URL 编码**彻底破坏**全部规则与代理组(文档原话)。且 8080 端口可能属于别的服务,误发请求可能打到无关服务上。
  • 跨机操作的授权边界靠人工判断 — skill 会 SSH 到 Tailscale 主机、并用云厂商 RunCommand 在目标机执行 shell。文档划了 scope 门并强调『保存过的 SSH 访问不等于长期使用许可』,但实际是否越界取决于当次执行者的判断。
  • 一处安全降级表述:Step 6 验证命令关闭主机密钥校验 — `ssh -o StrictHostKeyChecking=no` 写进了推荐的端到端验证命令,而 Step 2H 又反对为省事放宽该检查。影响有限(命令只跑 echo/hostname/whoami),但使用者可能照抄到其他场景。建议去掉该选项或改用 known_hosts 预置。
  • 代理节点凭据可能进入会话记录 — 读取整份代理配置后,内容会作为工具输出进入 agent 上下文与日志;若被整段回显,节点地址与凭据会留在会话/转录里。建议只提取需要的规则片段。
  • 门槛偏高且强依赖完整阅读 — SKILL.md 80KB / 1290 行 + 5 份 reference,含大量前序版本修正与边界条件;只读片段容易漏掉「先校准 nc」「先查故障线」「先读 recovery」这类关键前置,从而复现文档记录过的误判。
风险提醒:橙色,评估后使用。判橙的三条硬依据:①【凭据接触】references/proxy_conflict_reference.md 教用户/agent 从局域网明文 HTTP 读取整份 Shadowrocket 配置(含代理节点与凭据)并写回该配置;这是对代理凭据的直接读取路径。②【系统级改动】skill 的核心动作就是改路由表、改系统代理例外、重启/重装 Tailscale(含 sudo route delete、sudo killall -HUP mDNSResponder、sudo snap remove tailscale、sudo tailscale up --ssh),属于会改变用户网络状态的高影响操作。③【跨机取证】会 SSH 到 Tailscale 内主机、并经云厂商 guest-agent 通道在目标云主机上执行 shell(aliyun ecs RunCommand)。为什么不是红:没有安全降级作为主路径(Step 6 出现一处 StrictHostKeyChecking=no,但那是连通性验证命令而非数据通道,且文档在 2H 节明确反对为省事而放宽该检查),没有反爬/绕过/批量采集意图,所有外发目标都是诊断必需的通用可达性站点与用户自己的代理/云控制台。为什么不是黄:涉及凭据读取、系统配置变更与他机操作的组合面,影响半径明显超过「常规 API 调用」。使用建议:只在你自己(或有明确授权)的机器上运行;涉及 VPN 断开/路由切换前先按 network_change_recovery.md 布置恢复;读取代理配置时避免把整份配置内容回显到会话或日志里。

5第二遍独立确认

  • [discrepancy] 每条外部依赖的调用点是否真实存在(13 个 CLI/API/network 条目) — 【本项在第二遍自查时曾误判为 ok,后经磁盘级校验工具抓出并已修正】。逐条回查后确认:tailscale 调用点见 Step 2D 的 `tailscale status` 与诊断纪律表的 `| Tailscale daemon | \`tailscale status\` returns peer list (not connection error) |`、Step 5 的 `sudo tailscale up --ssh` / `--ssh=false` / `tailscale ssh` / `tailscale version`;其余依赖亦各有真实调用点(env/ifconfig/route/scutil 见 2A/2B、curl 见 2A/2C/2E 与容量参考、dig 见 2I/2J/2K、nc/tcpdump/ss 见 2K 与 Step 6、ssh 见 Step 6 与 SSH 双隧道、docker 见 2G、pnpm 见 SOP 第 5 节、aliyun ecs 与 journalctl 见 2K、Shadowrocket config API 见 proxy_conflict_reference.md、google/github/alpine CDN 见 2H/2K/2G、Tailscale 官方站点见 Step 4/5B、localhost/local.<domain> 见 Step 1 症状清单)。**纠正的具体错误**:首稿有两条 evidence 的 quote 被误取自同批另一份源码(windows-remote-desktop-connection-doctor/SKILL.md)——`tailscale status` / `tailscale netcheck` 与 `ifconfig | grep -E "^[a-z]|inet |utun"` / `netstat -rn | head -40` / `scutil --proxy` 均属该文件而非本 skill;本 skill 内 tailscale 的实际命令是 `tailscale status`、`tailscale ssh`、`sudo tailscale up --ssh`、`tailscale version`(**不含 netcheck**),macOS 工具的实际命令是 `ifconfig | grep -A2 'inet 100\.'`。两条 quote 已按 pin 源码逐字替换,`netcheck` 相关表述已从 name/scripts_executed 中清除。教训记录:跨文件批量取证时,同批并行读取的相邻源码极易被错误归属,evidence 必须在写入前逐条回到目标文件复核。
  • [ok] 自带脚本是否与文档声明一致(是否只做诊断、不写盘、无 shell 注入) — quick_diagnose.py 的 docstring 自述只做五类冲突检测(env+NO_PROXY、系统代理例外、代理路径 vs 直连、本地 TLS 信任、可选路由归属);其 subprocess.run 全部传参数列表(无 shell=True);os.environ.copy() 后仅 pop 代理变量以做对照请求;无文件写入、无 subprocess 之外的网络栈。结论成立。
  • [ok] 是否漏记外发目标(把每个域名回查调用点) — 全目录域名提取:api.github.com、www.google.com、dl-cdn.alpinelinux.org、registry.npmmirror.com、login.tailscale.com、pkgs.tailscale.com、docs.python.org、docs.ansible.com、tailscale.com、local.example.com、localhost(多端口)、127.0.0.1:1082、host.internal:1082、192.168.31.110:8080(Shadowrocket IP 占位)、100.101.102.103:8002、203.0.113.199(RFC 5737 对照)、198.18.x.x(fake-IP 段)。均已归入 external_deps 或注入面说明;无未记载的隐蔽外发。
  • [discrepancy] 『安全降级』检索是否有命中 — 命中并构成文档内部张力:Step 6 的端到端验证命令为 `ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no <user>@<tailscale-ip> 'echo SSH_OK && hostname && whoami'`,即关闭主机密钥校验;而 Step 2H 在讨论『不要硬编码 GitHub IP』时明确把『pressure you into loosening `StrictHostKeyChecking`』列为真实成本,并称「That is a real cost paid for an uncertain benefit.」。同一文档一处反对放宽该检查、另一处把它写进推荐验证命令,属于未消解的表述张力(实际影响有限:该命令只执行 echo/hostname/whoami,无数据外发)。按分级范式这不足以把本 skill 判红,但应作为使用提醒记录下来。
  • [ok] 『读取代理配置』这一凭据接触面是否被文档自己披露 — 披露且被谨慎处理:proxy_conflict_reference.md 明确要求不要硬编码设备 IP('The device IP changes with DHCP. Do not hardcode it.')、给出端口 8080 可能被别的服务占用的 lsof 检查、并用粗体警告 -d 会 URL 编码从而『destroys the entire configuration』。即作者意识到了该接口的高风险性。此事以「凭据读取 + 配置写入」双重性质记入 security,不构成隐蔽行为。
  • [ok] 是否存在混淆或隐蔽脚本 — 全目录扫描 >200 字符无空格长行零命中;无 base64 大块(仅 2K 节的 aliyun --ContentEncoding Base64 说明与 RFC 引述);唯一可执行文件 quick_diagnose.py 全文可读、无动态代码加载。
  • [ok] 文档内部是否另有自相矛盾(除 StrictHostKeyChecking 外) — 抽查了 nc -z 的表述:Step 1 的关键区分里曾以 nc -z 成功作为判据,Step 2K 则明确『This supersedes the plain `nc -z` reading in the bullet above whenever a TUN — not just Tailscale — is in the path』——即作者主动标注了覆盖关系而非留矛盾,属已消解的张力。其余抽查(utun MTU 判据、TUN 可信探针清单)内部一致。
  • [ok] pin commit 与 skill.path 是否与任务书表格一致 — git rev-parse HEAD = d5c4678cb5d4fd6acc9c922690df035dbd33d247,与任务书表格『库内 HEAD』一致;目录位于仓库根,相对路径 tunnel-doctor;本目录最后一次提交 829d9758(2026-09-08 22:22)。GitHub API 复核 MIT / stars 1392 / pushed 2026-09-15T09:30:04Z。

6结论

  • 分层诊断骨架(5 层 + 症状→步骤索引)让「Tailscale 能用但 SSH/HTTP 不通」这类模糊症状能快速收敛到具体层,而不是靠试。
  • 「测量污染」这一节在同类网络排错文档里很少见:明确指出 TUN 下哪些探针会给出伪造数字,并给出可信替代与物理常识判据。
  • 对「同一错误信息的多重成因」不做过早归因,而是先设计区分实验(HTTPS 失败率循环、nc 校准、带外取证),并明确承认有一类问题无法在客户端判定。
  • 破坏性操作有明确的恢复契约,且否定假证据(停成功、进程脱离、脚本末尾重启都不算恢复)。
  • 对他机操作有边界意识并写成强制规则(不得因测试需要登入同事机器、已有授权不扩展到新环境、即使经 peer 交接也适用)。
  • 会自我修正:明确撤回早期版本推荐的『在 ~/.ssh/config 硬编码 GitHub IP』并给出三条理由,属罕见的可追溯工程记录。
  • 适合:适合:在用 Tailscale/VPN/代理工具并与本地网络冲突缠斗的 macOS 开发者与运维(尤其中国大陆网络环境:Shadowrocket/Clash/Surge + 国内 DIRECT 规则 + 需要 SSH 到 WSL 或云主机);也适合遇到「SSH 不通但 ping 通」「浏览器 503 但 curl 通」「nslookup 快但 ssh 卡 60 秒」「docker pull 慢/失败」这类具体症状、想要一份可执行判据而非泛泛建议的人。
    不适合:不适合:根因未知或属应用/协议层(SSE/CDN/HTTP2 行为)的排错——文档明确要求回退到 debugging-network-issues;不适合不愿在本机改路由/代理配置的人;不适合只是想知道「网络是不是断了」的轻量场景(成本远高于直接看状态)。在他人机器或生产网络设备上使用前,需先取得明确且范围限定的授权。
    安装 agent 直装可复制
    ① 本站镜像 更新 2026-09-15
    方式 A · 人下载镜像包下载 tunnel-doctor.tar.gz
    sha256: a9f26e4f66655f0e…
    方式 B · JSON 格式安装指南,复制给 agent
    安装指南
    agent 读 JSON 指南后会自动从本站下载安装,无需更多说明。
    ② 上游 GitHub · 原始来源
    能访问 GitHub?直接去上游安装(实时版,可能已更新)GitHub 原始 ↗
    本页镜像锁定 commit d5c4678cb5;上游为实时仓库。
    来源信息 GitHub 原始
    作者 / 仓库daymade / daymade/claude-code-skills
    Stars1392
    最近推送2026-09-15
    本 skill commitd5c4678cb5
    许可MIT(仓库根 LICENSE,Copyright (c) 2025 daymade;GitHub API spdx MIT)
    本站信息
    收录日期2026-09-06
    分类基础工具与工作流
    侦查报告AI 侦查 · 2 遍 · 2026-09-06
    本站镜像与 GitHub 原始是不同来源:本站锁定 commit 快照经 /r2 分发;GitHub 为实时上游,内容可能已更新。
    同分类邻近