Claude Media
Claude Codeでtsharkのpcapを解析し通信エラーを切り分ける手順

Claude Codeでtsharkのpcapを解析し通信エラーを切り分ける手順

pcapそのものはClaude Codeに渡さず、tshark -T fieldsで再送・RST・TLSアラートの行だけを書き出して要約させる手順。認証情報を渡さない抜き方と権限設定もまとめる。

通信エラーの調査でpcapを丸ごとClaude Codeに読ませるのは、おすすめしにくい進め方です。パケットのバイト列はそのままでは読めず、量も多く、ペイロードにはCookieやAuthorizationヘッダーが残っているかもしれません。

そこで、tshark(Wiresharkのコマンドライン版)で「再送」「RST」「TLSアラート」の行だけを表にして書き出し、その表だけを渡します。Claude Codeは表を読んで、どの通信がどの段階で止まったかを言葉にします。この記事は、その抜き方、渡す前に消すもの、Claude Code側の権限設定を順に書きます。

pcapは渡さず、症状の行だけを表にする

構成は単純です。pcapを読むのは人が実行するtsharkで、Claude Codeが読むのは、そこから出したTSVファイルだけにします。

手順

pcapから要約までの流れ

  1. 1

    キャプチャする

    通信エラーが再現している間に、tcpdumpやtsharkでpcapを保存します。

  2. 2

    症状の行だけ書き出す

    tshark -r で読み、-Y で絞り、-T fields で必要な列だけを出します。

  3. 3

    渡す前に目で確かめる

    出力にトークンやCookieが無いことを、head と grep で確かめます。

  4. 4

    Claude Codeに表を読ませる

    TSVだけを読ませ、pcapには Read の拒否ルールをかけます。

この形にする理由は3つあります。1つ目は量です。pcapは数万パケットになりますが、再送とRSTとアラートに絞った表は数十行で済みます。2つ目は中身です。列を自分で選ぶので、ペイロードやヘッダーの値は最初から出力に入りません。3つ目は再現性です。同じtsharkコマンドを別のpcapに当てれば、同じ形の表が得られます。

tsharkで再送・RST・TLSアラートを書き出す

-T fields は -e で指定したフィールドの値だけを出力する形式です。-e は複数回書け、-T fields を選んだときは最低1つ必要です。区切りは既定でタブで、-E header=y を付けると先頭行に列名が入ります。名前解決を止める -n も付けておくと、IPアドレスがそのまま出ます。

まず、TCPの再送とRSTを1つの表にします。

tshark -r capture.pcap -n \
  -Y "tcp.analysis.retransmission || tcp.flags.reset == 1" \
  -T fields -E header=y \
  -e frame.number -e frame.time_relative \
  -e ip.src -e ip.dst \
  -e tcp.srcport -e tcp.dstport -e tcp.stream \
  -e tcp.analysis.retransmission -e tcp.flags.reset \
  > tcp-trouble.tsv

使ったフィールドの意味は次のとおりです。

フィールド見る内容
tcp.analysis.retransmission見る内容再送と判定されたパケット
tcp.flags.reset見る内容RSTフラグが立っているか
tcp.stream見る内容同じ接続を束ねるストリーム番号
frame.time_relative見る内容キャプチャ開始からの経過時間

次に、TLSのアラートだけを別の表にします。tls.alert_message.level と tls.alert_message.desc が、アラートの重大度と理由の番号です。

tshark -r capture.pcap -n \
  -Y "tls.alert_message" \
  -T fields -E header=y \
  -e frame.number -e frame.time_relative \
  -e ip.src -e ip.dst -e tcp.stream \
  -e tls.alert_message.level -e tls.alert_message.desc \
  > tls-alerts.tsv

TLSアラートがどのホストへの接続で出たかも知りたいときは、ClientHelloのSNIを別の表にします。フィールド名は tls.handshake.extensions_server_name です。ホスト名は社内の機密になりうるので、渡すかどうかは次の節で決めます。

tshark -r capture.pcap -n \
  -Y "tls.handshake.extensions_server_name" \
  -T fields -E header=y \
  -e tcp.stream -e ip.dst \
  -e tls.handshake.extensions_server_name \
  > tls-sni.tsv

出力は、例えば次のような形になります(文書用のアドレス帯を使った例です)。

frame.number	frame.time_relative	ip.src	ip.dst	tcp.srcport	tcp.dstport	tcp.stream	tcp.analysis.retransmission	tcp.flags.reset
412	3.201	192.0.2.10	203.0.113.5	51234	443	7	1	0
415	3.805	192.0.2.10	203.0.113.5	51234	443	7	1	0
431	6.912	203.0.113.5	192.0.2.10	443	51234	7	0	1

同じストリーム7で、再送が2回続いたあとにRSTが返っています。この3行だけで「サーバー側かその手前の機器が、応答のない接続を切った」と見当をつけられます。Claude Codeに渡すのは、こうした行です。

再送やゼロウィンドウを別に数えたいとき

tcp.analysis.fast_retransmission は高速再送、tcp.analysis.zero_window は受信側のウィンドウが0になった通知を指すフィールドです。受信側が詰まっている疑いがあるときは、-Y にこれらを足します。

渡す前に認証情報を除く

ここが、表を渡す前の関門です。-T fields は列を自分で選ぶので、安全側に倒しやすい形式です。逆に、-V(パケット詳細の全表示)や -x(16進ダンプ)を付けると、ペイロードがそのまま出ます。要約用の出力には使いません。

次の3点を守ります。

  • http.authorization や http.cookie のような、値そのものを持つフィールドを -e に入れない
  • 数字やフラグの列だけで足りる調査では、ホスト名やURLの列も入れない
  • 書き出したファイルを、渡す前に必ず目で確かめる

確かめる手順は次のとおりです。

wc -l tcp-trouble.tsv tls-alerts.tsv
head -n 5 tcp-trouble.tsv
grep -i -E 'bearer|authorization|cookie|token|password' *.tsv

grep が何も返さなければ、少なくとも既知の語は含まれていません。ただしこれは検索であって、保証ではありません。TLSの暗号化済みの通信は、そもそもペイロードが読めません。平文のHTTPや、独自プロトコルのペイロードを扱うときに特に注意が要ります。

IPアドレスやSNIを社外のモデルに送りたくない環境では、社内ホストごとに番号を振り替えてから渡す方法もあります。たとえば ip.dst を sed で host-A、host-B に置き換えます。原因の切り分けには「どの接続か」の区別があれば足りるので、実名は要らないことが多いです。

落とし穴

pcapを開いたまま「ログを見て」と頼む

Read や grep -r で、Claude Codeがpcapを直接開ける状態だと、人が気をつけて表を作っても意味がなくなります。次の節の拒否ルールで、pcapは読めない状態にしておきます。

Claude Codeに表だけを読ませる権限設定

Claude Codeの権限は、ツールごとにルールを書いて制御します。ファイルを読ませない設定は Read の拒否ルールです。パターンはgitignoreの書き方に従い、拒否ルールでは Read(.env) のような裸のファイル名が、どの深さでも一致します。

pcapを読ませない設定は、プロジェクトの .claude/settings.json に次のように書きます。

{
  "permissions": {
    "deny": [
      "Read(**/*.pcap)",
      "Read(**/*.pcapng)"
    ]
  }
}

この Read の拒否ルールは、組み込みのファイル読み取りツールに加えて、cat、head、tail、sed、tee のようにClaude Codeが認識するBashのファイル系コマンドにも効きます。一方で、ファイル名を明示せずに読むコマンドや、PythonやNodeのスクリプトがファイルを開く場合には効きません。たとえば grep -r pattern . を、pcapのあるディレクトリで実行すると防げません。

そこまで確実に止めたいときは、OSレベルで制限するサンドボックスを併用します。サンドボックスは、Bashやその子プロセスのファイルとネットワークへのアクセスを制限する別の層です。サンドボックスで詰まったときの対処は、Claude CodeのサンドボックスがNixOSで権限エラーになる原因で書いています。

tshark自体の実行を許可するかどうか

標準のBashの読み取り専用コマンドの一覧には、ls、cat、grep、find、wc などが入っています。一覧に tshark は挙がっていないため、手動承認の既定では、Claude Codeが tshark を実行しようとすると確認が出ます。

この記事の流れでは、tshark を実行するのは人です。Claude Codeには tshark を実行させないほうが、設計が単純になります。Claude Codeに実行させる場合は、次の点に気をつけます。

  • Bashのルールはコマンド全文に対して一致する。Bash(tshark -r capture.pcap *) のように固定部分を長く取る
  • 引数を縛るルールは崩れやすい。ドキュメントも、引数を制約するBashパターンは壊れやすいと注意している
  • 複合コマンドは各部分ごとに判定されるので、&& や | でつないだ別コマンドは、別のルールで判定される

また、tshark -w のように出力ファイルを書き込む場合は、書き込み先が Edit のルールとワーキングディレクトリの検査に通る必要があります。出力のリダイレクト > tcp-trouble.tsv も同じ扱いです。

表を読ませるプロンプトとCLAUDE.mdの断片

表を渡すときは、何を調べたいのかと、何をしてはいけないのかを最初に書きます。次のような指示が出発点になります。

tcp-trouble.tsv と tls-alerts.tsv を読んで、通信が止まった接続を
tcp.stream ごとにまとめてください。
 
- 各ストリームについて、再送の回数、RSTを出した側、TLSアラートの有無を書く
- 原因を断定せず、考えられる原因を可能性の高い順に2〜3個挙げる
- pcap本体と、このTSV以外のファイルは読まない
- 追加で見たいフィールドがあれば、tsharkのコマンドを提案するだけにする

最後の1行が、反復のための仕掛けです。Claude Codeが「このストリームのTCPフラグがもっと見たい」と考えたら、コマンドを提案させ、人が実行して新しい表を渡します。人が列を選ぶ関門を、毎回通せます。

同じ手順を繰り返すなら、CLAUDE.md に規約として残せます。

## パケット調査のルール
- pcap / pcapng は読まない(Read で拒否している)
- 調査には人が tshark -T fields で書き出した TSV だけを使う
- -V と -x の出力、http.authorization と http.cookie の列は受け取らない
- 原因は断定せず、追加で必要な tshark の -e / -Y を提案する

ここに書いた内容は、Claude Codeの振る舞いを方向づけるものであり、強制力はありません。強制する部分は前の節の拒否ルールが担います。

表から原因を切り分ける順番

表を読ませたあとは、症状から原因の層を絞っていきます。次のチェックの順で聞くと、会話が散らかりません。

切り分け

通信エラーを表から切り分ける順番

  1. QSYNに対する応答が一切なく、再送だけが続いていますか?
    答えが次へ進む

    宛先に届いていないか、途中の機器が落としています。ファイアウォールの許可や経路を確かめます。

    答えがはい
  2. Q再送のあとに、相手からRSTが返っていますか?
    答えが次へ進む

    相手またはその手前の機器が接続を拒否しています。RSTを出した側のアドレスが誰なのかを確かめます。

    答えがはい
  3. QTLSアラートが出ていますか?
    答えが再送とRSTだけでは足りないので、追加の列を見る

    アラートの tls.alert_message.desc の番号で、証明書か、プロトコルのバージョンか、暗号スイートかを絞ります。

    答えがはい

疑う層が決まる

届かない、拒否される、TLSで失敗するのどれかに絞れたら、Claude Codeに、その層の確認コマンドを提案させます。

RSTの出どころは重要です。クライアントが出したRSTなら、アプリケーションが接続を切っています。サーバーのアドレスから来たRSTなら、サーバーかロードバランサーが拒否しています。第三者のアドレスから来ているように見えるRSTは、途中のファイアウォールやプロキシが差し込んでいる可能性を疑います。ただし、表の1行だけでは断定できないため、前後の再送との時間差も合わせて見ます。

件数の要約はtshark側で取る

件数や時間の集計は、Claude Codeに行を数えさせるより、tsharkに数えさせるほうが確実です。-z expert は、expert infoの項目を集めて表示するオプションで、-q を併用するとパケットごとの出力が止まり、統計だけが残ります。

tshark -r capture.pcap -n -q -z expert,warn > expert-warn.txt

出力された警告の一覧を、表と一緒に渡すと、再送の件数の根拠が揃います。

接続エラーが出ているのがClaude Code自身のときは

ここまでは、調査対象のアプリケーションの通信を切り分ける手順でした。Claude Code自身が接続エラーを出している場合は、先にAPIへの疎通を確認する順序のほうが早く済みます。その手順はClaude API connection errorの原因と切り分けにまとめています。パケットまで見るのは、VPNやファイアウォールの差を試したあとでも原因が見えないときです。

まとめ

pcapを丸ごと読ませずに、tshark -T fields で再送、RST、TLSアラートの行だけを表にして渡す。この形は、量を減らすと同時に、渡す内容を人が選ぶ関門にもなります。

判断の分かれ目は、列に何を入れるかです。ホスト名やIPアドレスまでを社外のモデルに送ってよいかは、環境ごとに違います。迷うなら、ストリーム番号と数値の列だけで一度要約させ、足りない列だけを追加してください。Claude Code側ではpcapに Read の拒否ルールをかけ、確実さが必要ならサンドボックスを併用します。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/permissions
  2. wireshark.org/docs/man-pages/tshark.html
  3. wireshark.org/docs/dfref/t/tcp.html
  4. wireshark.org/docs/dfref/t/tls.html
この記事を共有:XはてブLinkedIn