ワークフロー&基本ツール · daymade/claude-code-skills

tunnel-doctor

macOSおよびWindows/WSLにおける具体的なトンネルおよびプロキシ経路の障害を診断します: Tailscaleのルーティング、プロキシ環境変数/システムバイパス、SSH多重トンネリング、VM/コンテナへの伝播、 DNSのハング、TUN DIRECTスプリットブレイン、WindowsホストTUNのカスケード、および シングルホップまたはチェーンプロキシノード/出口のスループット。Tailscale pingは通るがSSH/HTTPが失敗する、 curlは動くがブラウザが503を返す、プロキシ経由のGit SSHが切断される、TUN配下でDocker pull/buildが失敗する、 nslookupは速いのにgetaddrinfoがハングする、生プローブが物理的に不可能な結果を報告する、 プロキシ経由サイトは機能するのに国内DIRECTルートサイトが失敗する、ブロックされたポートの原因が自環境のトンネルか相手先ファイアウォールか判断できない、 またはプロキシには接続できるが実際のダウンロードや完全なGit cloneが極端に遅い場合に使用します。 また、Gitが「failed to begin relaying via HTTP」と出力する、ssh -vvvが「debug2: resolving」で停止する、 pingは通るがdigがタイムアウトする、WSLへのTailscale SSHを設定する場合にも利用します。 根本原因が不明である場合や、アプリケーション/プロトコル層に起因する場合は、debugging-network-issuesのみを使用してください。

L4 高権限 · 段階的認可と監査V1 コミット固定コマンド実行ネットワーク通信ファイル書き込みDual-pass Audit
Author daymadeGitHub daymade/claude-code-skills ↗Stars 1392License MIT(仓库根 LICENSE,Copyright (c) 2025 daymade;GitHub API spdx MIT)Commit d5c4678cb5
管理レベルは Skill の能力と推奨統制措置を示すものであり、品質や安全性の認証、利用可否の判定ではありません。使用の可否はユーザーおよび管理者が決定します。Agent 環境によって制約が異なるため、自動保護を仮定しないでください。第三者製 Skill の著作権は原著作者に帰属し、利用リスクは利用者が負います。

1仕組みと動作原理

「Tailscaleとプロキシ/VPNの共存」による衝突をネットワークスタックの5つのレイヤーに分解し、各層に「何が壊れているか / 何が正常か / 根本原因」を明記した上で、「何がまだ動いているか」から障害層を逆引きする手法を採用しており、これがスキル全体の診断骨格となっています。

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.」およびコンポーネント→ヘルスチェック対応表(プロキシはcurl -x、Tailscaleはtailscale status、DNSはdig @ns)。

TUNグローバルモードにおける「プローブが嘘をつく」現象に対し、反証可能な判定基準を提示しています。0.00秒の海外接続や1ミリ秒未満の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。

同一のエラーメッセージに対して2つの背反する解釈を提示し、事前の切り分け実験を義務付けています。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.
切り分け手段は「同一プロキシ経路で通常HTTPSを40回実行し失敗率を計測する」ループであり、定量的なデータポイントを提示:「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)経由で対象マシンに入って証拠収集するよう要求し、「auth.logではなくjournalctl」という実測の反例を提示しています。

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で最も一般的な4つの衝突パターン(環境変数プロキシ、システムプロキシ例外、直連/プロキシ経路の分裂、ローカルTLS信頼)を1つのコマンドに集約し、判読しやすい3行の結論を出力します。

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/ルーティング/サービスを変更する前に、必ずリカバリ参照を読み、前提条件を検証し、制限付きのリカバリ手段を配備することを要求し、「停止成功/プロセス分離/スクリプト末尾の再起動」は復旧の証拠とみなさないことを明記しています。

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.
該当リファレンスの3段階構成:Before interruption / Execute and recover / Verify and finish。

2コア機能

01ルーティング層の競合診断および修復(プロキシによるTailscale CGNATサブネットの占有)
02NO_PROXY / skip-proxy 環境変数およびシステムプロキシ例外の修復(Go net/http がCIDRを非対応とする落とし穴を含む)
03TUN DIRECT スプリットブレインの診断(ドメイン接続は不通だが、実IP+正しいSNIなら導通する事象)
04DNS getaddrinfo チェーン遅延のネームサーバ単位バイナリサーチ特定(nslookupは高速だがシステム解決が60秒フリーズする問題)
05VM/コンテナのプロキシ伝播修復(OrbStack/Docker Desktopの透過型プロキシとTUNの競合、buildkit直連、v2rayNポート分割)
06SSH多重トンネルおよびgit over SSHの間欠的障害の処理(鍵交換前の失敗のみを再試行するラッパー契約を含む)
07WSLにおけるTailscale SSHのサイレント遮断の修復(kex_exchange_identification + tcpdump 0パケット判定基準)
08プロキシノード/出口/リンクのキャパシティおよびスループット診断(単一ホップおよび多段チェーン、シリアル比較、実クライアント再テスト、生ワークロードのリプレイ)
09WindowsホストTUNのカスケード障害(WSLとそのTailscaleが同時にダウン)およびイベントログのタイムラインフォレンジック
10Tailscaleリモート開発SOP(プロキシセーフなMakefile、SSHトンネルターゲット、マルチポート転送、non-login shell環境)

3外部依存関係

KindDependency / Endpoint
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推奨統制措置と判定根拠

安全運用のための推奨統制措置
Agent 向け
段階的・都度認可、サンドボックス推奨
管理者向け
承認フロー、ロールバック可能、全履歴監査
判定根拠(ファイルパスと抜粋)
  • scripts/: ローカルスクリプトまたはコマンドの実行: python3 scripts/quick_diagnose.py --host … --url … [--tailscale-ip …](リポジトリ同梱)
  • 网络端点: 外部ネットワークアクセスの宣言: ローカル/LANプロキシポート(127.0.0.1:1082、host.internal:1082など)経由および直連による外部エンドポイントへのcurl実行(パスの健全性およびキャパシティ測定)
  • 本地工作目录: ファイル読み書きおよび成果物出力: Shadowrocket設定の書き戻し:POST /api/save --data-binary @config.txt によるエディタバッファの置換(リファレンス)
監査ノート: オレンジ判定とする3つの明確な根拠:①【認証情報の接触】references/proxy_conflict_reference.md にて、LAN内の平文HTTPを介してShadowrocketの全設定(プロキシノードおよび認証情報を含む)を読み取り、書き戻す手順が示されており、プロキシ認証情報への直接的な読み取り経路が存在します。②【システムレベルの変更】スキルのコアアクションがルーティングテーブルの変更、システムプロキシ例外の変更、Tailscaleの再起動/再インストール(sudo route delete、sudo killall -HUP mDNSResponder、sudo snap remove tailscale、sudo tailscale up --ssh を含む)であり、ユーザーのネットワーク状態を変更する影響度の高い操作に該当します。③【複数マシンにまたがる調査】Tailscale内のホストへのSSH接続や、クラウド業者のguest-agentチャネル経由でターゲットクラウドホスト上でシェルを実行(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校正、帯外フォレンジック)を設計し、クライアント側では判断不可能な問題が存在することを明確に認めています。
  • 破壊的な操作に対して明確なリカバリ契約を定め、偽の復旧証拠(正常停止、プロセスの切り離し、スクリプト末尾の再起動など)を否定しています。
  • 他ホストに対する操作の境界を強く意識し、必須ルールとして明文化しています(テスト目的で同僚のマシンにログインしない、既存の権限を新しい環境へ拡大適用しない、同僚からの引き継ぎ時でも適用)。
  • 自己修正能力:初期バージョンで推奨していた「~/.ssh/config へのGitHub IPのハードコード」を3つの理由を挙げて明確に撤回しており、追跡可能な優れたエンジニアリング実践が示されています。
  • 最適な用途: 対象者:Tailscale/VPN/プロキシツールを利用し、ローカルネットワーク競合に直面しているmacOSの開発者およびインフラ運用担当者(特に中国本土ネットワーク環境:Shadowrocket/Clash/Surge + 国内DIRECTルール + WSLやクラウドホストへのSSHが必要なケース)。また、「SSHは繋がらないがpingは通る」「ブラウザは503だがcurlは通る」「nslookupは速いがsshが60秒止まる」「docker pullが遅い/失敗する」といった具体的な症状に対し、一般的な助言ではなく実行可能な判定基準を求めているユーザーに適しています。
    不向きな用途: 非対象:根本原因が不明、またはアプリケーション/プロトコル層(SSE/CDN/HTTP2の挙動など)に起因するトラブルシューティング(ドキュメントではdebugging-network-issuesへのフォールバックを明記)。ローカルのルーティングやプロキシ設定を変更したくないユーザーや、単に「ネットが落ちているか」を知りたいだけの軽量ユースケース(診断コストが状態確認を大幅に上回るため)には不向きです。他人のマシンや本番ネットワーク機器で実行する前に、明確かつ範囲が限定された承認を得る必要があります。
    Install Agent-Ready
    ① Verified Mirror 2026-09-15
    Option A · Direct DownloadDownload tunnel-doctor.tar.gz
    sha256: a9f26e4f66655f0e…
    Option B · Copy Guide for Agent
    install.json
    Agent はこの JSON ガイドから自動的にダウンロードして検証します。
    ② Upstream GitHub
    GitHub Repo ↗
    Pinned to commit d5c4678cb5.