皆さん、こんにちは!
大規模データセンターのど真ん中で、日夜ネットワークの異音に耳を傾けているNOCシニアエンジニアの○○です。
「パケットはネットワークの血液」――私はいつもそう言っています。どんなトラブルも、この血液の流れを正確に追うことで、必ずその原因を突き止めることができます。そして、そのための最強の道具が、そう、tcpdump ですよね!
しかし、ただ闇雲に tcpdump を使っているだけでは、かえって深みにハマってしまうことも少なくありません。「全部パケットをキャプチャしてやる!」と意気込んでみても、高トラフィック環境では、肝心なパケットが手元に届く前に消えてしまう……なんて悲しい経験、ありませんか?
今回は、そんな tcpdump をもっと賢く、もっと確実に使いこなすための2つの秘訣をご紹介します。キーワードは、「スナップショット長(-s オプション)」 と 「バッファサイズ(-B オプション)」 です。
小難しいパケット構造の話は最小限にして、皆さんの身近な例え話で、一歩ずつ理解していきましょう!
—
目次
1. パケット調査、本当に「全部」必要ですか? 〜スナップショット長 -s の魔法〜
2. 頼む、取りこぼさないでくれ! 〜バッファあふれ対策 -B の極意〜
3. 現場での知恵と落とし穴:賢い組み合わせ方
4. まとめ:tcpdump を「最強の味方」にするために
—
1. パケット調査、本当に「全部」必要ですか? 〜スナップショット長 -s の魔法〜
皆さんは郵便物を送るとき、何を確認しますか? ほとんどの場合、封筒に書かれた「送り主」「宛先」「切手」などですよね。中身の手紙を隅々まで読むのは、それが自分宛てだったり、特別な事情があるときくらいでしょう。
ネットワークの世界の「パケット」も、これと全く同じなんです。
パケットは大きく分けて2つの部分で構成されています。
- ヘッダー(封筒): 送り主(送信元IPアドレス)、宛先(宛先IPアドレス)、郵便の種類(TCP/UDPプロトコル)、ポート番号、切手の情報(TTLなど)といった、通信を成立させるための「お約束事」が詰まっている部分です。
- データペイロード(手紙の中身): 実際に送りたいデータ(WebページのHTMLデータ、メール本文、ファイルの中身など)が入っている部分です。
なぜ「ヘッダーだけ」で十分なことが多いのか?
私たちがネットワークトラブルに遭遇したとき、多くの場合、知りたいのは「この通信はどこからどこへ向かっているのか?」「どのポートを使っているのか?」「そもそも通信が始まっているのか?」といった、まさに「封筒」の情報なんです。
例えば、Webサーバーにアクセスできない時、
- クライアントから
SYNパケットが飛んでいるか? - サーバーから
SYN/ACKが返ってきているか? - 途中で
RSTパケットが送られて通信が切られていないか?
といった確認は、パケットの「ヘッダー」さえ見れば十分ですよね。中身のWebページデータがどうこう、という話は、もっと後の段階で考えることが多いはずです。
パケット全体をキャプチャするデメリット
パケット全体をキャプチャすることは、もちろん詳細な解析には役立ちます。しかし、デメリットも無視できません。
- データ量が膨大になる: 高トラフィック環境では、あっという間にディスク容量を食いつぶします。
- 処理負荷が増える:
tcpdumpがキャプチャしたパケットを処理し、保存するのに時間がかかります。 - 解析に時間がかかる: 不要なデータペイロードの中から、本当に必要な情報を見つけるのが大変になります。
-s オプションで「封筒だけ」をキャプチャする
ここで登場するのが、tcpdump の -s オプション(スナップショット長、snaplen) です。
このオプションは、「パケットの先頭から何バイトまでをキャプチャするか」を指定します。
デフォルトの tcpdump は、ほとんどの場合、65535 バイト、つまり「ほぼパケット全体」をキャプチャするように設定されています(0 を指定した場合も「全部」という意味になります)。
私たちが「封筒だけ」を見たい場合、この -s オプションに適切なバイト数を指定してあげれば良いのです。
じゃあ、具体的に何バイトを指定すればいいの? となりますよね。
一般的なネットワークのヘッダー情報は以下のようになっています。
- イーサネットヘッダー: 14バイト(MACアドレスなど)
- IPヘッダー: 20〜60バイト(送信元/宛先IPアドレスなど)
- TCPヘッダー: 20〜60バイト(送信元/宛先ポート番号、シーケンス番号など)
- UDPヘッダー: 8バイト(送信元/宛先ポート番号など)
これらを合計すると、一般的なTCP/IP通信であれば、54バイト(イーサネット14 + IP20 + TCP20) あれば主要なヘッダー情報は確認できます。しかし、オプション付きのヘッダーや、少し余裕を持たせることを考えると、以下の値がよく使われます。
96バイト: 主要なヘッダー情報をカバーするのに十分な最小限のサイズとしてよく推奨されます。128バイト: 少し余裕を持たせたい場合に。多くのトラブルシューティングでこれくらいあれば十分でしょう。
これらの値を指定することで、キャプチャするデータ量を大幅に削減し、tcpdump の処理効率を向上させることができます。
-s オプションを使った実践例
それでは、実際にコマンドを見てみましょう。
# 例1: eth0インターフェースで、IPアドレス192.168.1.100とポート80の通信のヘッダー(128バイト)のみを100パケットキャプチャし、詳細表示する
# -i eth0 : キャプチャするネットワークインターフェースを指定します
# -s 128 : スナップショット長を128バイトに設定します(パケットの先頭128バイトのみを記録)
# -c 100 : 100パケットキャプチャしたら停止します
# -vvv : 詳細な情報を表示します(vの数で詳細度が変わります)
# -X : パケットのヘッダー部分をASCIIと16進数で表示します
# -n : ホスト名やポート番号を名前解決せずに数値(IPアドレスやポート番号)で表示します
# host 192.168.1.100 : フィルタリング条件。対象のIPアドレスを指定します
# and port 80 : フィルタリング条件。ポート番号80の通信に限定します
# -w /tmp/http_header_only.pcap : キャプチャ結果をファイルに保存します(保存しない場合は画面に表示されます)
sudo tcpdump -i eth0 -s 128 -c 100 -vvv -X -n host 192.168.1.100 and port 80 -w /tmp/http_header_only.pcap
# 例2: 厳密にヘッダー部分のみに絞り込みたい場合(96バイト)
# -s 96 : スナップショット長を96バイトに設定し、さらにデータ量を削減します
sudo tcpdump -i eth0 -s 96 -c 100 -vvv -X -n host 192.168.1.100 and port 80
このように -s オプションを活用することで、無駄なく、そして効率的に必要な情報だけをキャプチャできるようになるんです。まるで、郵便物の配達状況をチェックするために、封筒の表書きだけをスピーディーに確認するようなものですね!
2. 頼む、取りこぼさないでくれ! 〜バッファあふれ対策 -B の極意〜
さて、賢く「封筒だけ」を見る方法を覚えたところで、次に考えるべきは「見たい封筒を確実に取りこぼさない」ことです。
想像してみてください。あなたは郵便配達員で、大量の郵便物が次から次へと届きます。手元のバッグ(バッファ)に入れられる量には限りがありますよね? もし、郵便物が届くスピードが、あなたがバッグに入れて仕分けするスピードを上回ってしまったらどうなるでしょう? そう、郵便物はバッグに入りきらず、地面に落ちてしまい、最悪の場合、誰にも届かずに紛失してしまいます。
ネットワークの世界でも、これと全く同じことが起こりうるんです。
tcpdump とパケットバッファ
tcpdump は、ネットワークインターフェースカード(NIC)からパケットを受け取ると、すぐに処理できるわけではありません。一度、メモリ上の一時的な領域、いわゆる「バッファ」にパケットを格納します。そして、このバッファから順番にパケットを取り出して、画面に表示したり、ファイルに書き込んだりするんです。
もし、ネットワークのトラフィックが非常に多く、パケットがバッファに流れ込むスピードが、tcpdump がバッファからパケットを取り出して処理するスピードを上回ってしまうと…?
そう、バッファがいっぱいになり、新しいパケットを格納できなくなり、貴重なパケットが「ドロップ(取りこぼし)」されてしまうんです。
特に高負荷なサーバーやネットワーク機器で tcpdump を実行する場合、この「パケットドロップ」は非常に厄介な問題になります。肝心なエラーパケットや、特定の通信の開始・終了を示すパケットがドロップしてしまい、「あれ?見たいパケットがログにないぞ…」なんてことになりかねません。これは、障害解析の精度を著しく低下させ、誤った結論を導き出す原因にもなり得ます。
-B オプションで「バッグ」を大きくする
ここで登場するのが、tcpdump の -B オプション(バッファサイズ、buffer-size) です。
このオプションは、「tcpdump が使用するカーネルバッファのサイズをキロバイト(KB)単位で指定する」ものです。
デフォルトのバッファサイズは、OSや環境によって異なりますが、一般的には数MB(例えば2MBや8MB)程度と、そこまで大きくありません。高トラフィック環境では、このデフォルトサイズではすぐに飽和してしまい、ドロップが発生しやすくなります。
-B オプションを使ってバッファサイズを大きくすることで、より多くのパケットを一時的にメモリに保持できるようになり、パケットドロップのリスクを減らすことができるのです。郵便配達員が、もっと大きなバッグや、予備のバッグをいくつか持っていくようなイメージですね。
-B オプションを使った実践例
では、具体的にコマンドで見てみましょう。
# 例1: eth0インターフェースで、バッファサイズを16MBに増やしてキャプチャする
# -B 16384 : バッファサイズを16384KB(=16MB)に設定します
# デフォルトの数MBから大きく増やすことで、高トラフィック時のドロップを抑制します
# システムの空きメモリと相談しながら、適切な値を設定しましょう
# 今回は-s 128と組み合わせることで、より多くのパケットをバッファに保持できます
sudo tcpdump -i eth0 -s 128 -B 16384 -c 10000 -vvv -X -n host 192.168.1.100 -w /tmp/high_traffic_capture.pcap
# 例2: さらにバッファサイズを大きくする例(32MB)
# -B 32768 : バッファサイズを32768KB(=32MB)に設定します
# 非常に高トラフィックな環境や、一時的に多くのパケットをキャプチャしたい場合に有効です
# ただし、メモリ消費量が増えるため、サーバーのメモリリソースと相談が必要です
sudo tcpdump -i eth0 -s 96 -B 32768 -c 10000 -vvv -X -n port 80 or port 443 -w /tmp/web_traffic.pcap
パケットドロップの確認方法
tcpdump の実行終了時、以下のような統計情報が表示されます。
10000 packets captured
10000 packets received by filter
0 packets dropped by kernel
0 packets dropped by userland
ここで注目すべきは dropped by kernel と dropped by userland の値です。
dropped by kernel: NICのリングバッファからカーネルがパケットを取り出す際に、リングバッファがいっぱいになり、カーネルによってドロップされたパケット数です。これはtcpdump側のバッファサイズ (-B) では直接改善しにくい問題で、NICのリングバッファサイズをOSレベルで調整するか、NIC自体がパケットを処理しきれていない可能性を示唆します。dropped by userland:tcpdumpが使用するバッファ(-Bオプションで調整する部分)がいっぱいになり、tcpdumpプロセスによってドロップされたパケット数です。この値が多い場合は、-Bオプションでバッファサイズを増やすことで改善が期待できます。
もし dropped by userland に0以外の数字が表示されたら、それはパケットを取りこぼしてしまった証拠です。次からは -B オプションでバッファサイズを増やして、再チャレンジしてみてくださいね!
3. 現場での知恵と落とし穴:賢い組み合わせ方
さて、ここまでで -s オプションで「必要な情報だけ」を効率的に見る方法と、-B オプションで「取りこぼしを防ぐ」方法を学びました。この2つは、まさに tcpdump を最強のツールに変えるための黄金コンビなんです!
-s と -B の相乗効果
考えてみてください。バッファ(バッグ)のサイズが同じでも、中に入れるパケット(郵便物)のサイズが小さければ、より多くのパケットをバッグに入れることができますよね?
つまり、-s オプションでキャプチャするパケットのサイズを小さくすれば、同じ -B オプションで指定したバッファサイズであっても、より多くのパケットをメモリに保持できるようになります。これは、高トラフィック環境でのパケットドロップを減らす上で、非常に強力な相乗効果を生み出します。
リソースとのバランス感覚
ただし、-B オプションでバッファサイズを無闇に大きくしすぎるのは禁物です。
- メモリ消費: バッファはシステムのメモリを消費します。あまりにも大きくしすぎると、他の重要なプロセスがメモリ不足に陥り、システム全体のパフォーマンスが低下する可能性があります。
- ディスクI/O:
-wオプションでファイルに書き出す場合、パケットの書き込み速度がディスクI/Oのボトルネックになることもあります。これは、バッファを大きくしても改善しない、別のボトルネックです。
まずは 16MB や 32MB 程度から試してみて、dropped by userland の値を見ながら、システムのメモリ状況と相談して徐々に調整していくのが賢いやり方です。
トラブルシューティングのシナリオ例
- Webサーバーのタイムアウト障害:
tcpdump -i eth0 -s 128 -B 32768 -w /tmp/web_timeout.pcap host your_web_server_ip and port 80 or port 443- ヘッダー情報(
s 128)に絞り、バッファを大きく(B 32768)して、SYN/ACKのやり取りやTCP RST、リトライの状況を確実にキャプチャします。 - DNS名前解決の遅延:
tcpdump -i eth0 -s 96 -B 16384 -w /tmp/dns_issue.pcap port 53- DNSはUDPを使うことが多く、ヘッダーサイズがさらに小さめなので
s 96でも十分。遅延の原因がサーバーからの応答遅れなのか、リクエストが届いていないのかなどを効率的に確認します。
「とりあえず全キャプチャ」は、まるで砂漠で砂金を探すように、大量のゴミの中からわずかな情報を探すようなものです。スマートに、そして確実に、必要なパケットを捉えることが、障害解決への近道になります。
4. まとめ:tcpdump を「最強の味方」にするために
tcpdump は、ネットワークエンジニアにとって魔法の杖のような存在です。しかし、その魔法を最大限に引き出すには、適切な呪文(オプション)を知っている必要があります。
-sオプション(スナップショット長): パケットの「封筒」だけを見ることで、無駄な情報を省き、効率的にトラブルの原因を探る「賢い選択」です。-Bオプション(バッファサイズ): 高トラフィックな環境でも、貴重なパケットを「確実に取りこぼさない」ための強力な保険です。
この2つのオプションを状況に応じて使いこなすことで、皆さんのトラブルシューティングの精度とスピードは格段に向上するはずです。
ネットワークの「声」を聞き取るために、tcpdump は常に私たちの傍らにいます。今回学んだ知識を活かして、ぜひ皆さんの現場で、パケットたちが織りなす壮大なドラマを解き明かしてくださいね。
これからも、一歩ずつ理解を深めて、一緒にネットワークのプロフェッショナルを目指していきましょう!
コメント