SSH越しにWiresharkでパケットキャプチャ
はじめに
network namespace間を流れるパケットをキャプチャしたいときにどうすればいいでしょうか?
試してみます。
tcpdumpで取得
前の記事でやっているようにip netns execコマンドを使うことでnetwork namespace内のパケットをtcpdumpで取得することができます。
以下は"router1" network namespaceの"e1"インターフェイスのパケットをコンソールに出力する方法。
ip netns exec router1 tcpdump -nl -i e1
- -iはインターフェイス名を指定(必要)
- -l(小文字のエル)は出力を1行ごとにフラッシュ(必要)
普通にtcpdumpする時(ip netns execなしの時)はコンソールに出力するのでline buffered(1行ごとに出力)になりパケットが1個届くたびに画面に出力されるのですが、ip netns exec内でtcpdumpするとバッファリングされるので、ある程度の量が溜まるかCtrl-Cで終了するまで画面に出てきません。
-lすることで1パケットごとに画面出力されます。
というか長々説明しましたが-lあり、なしで実験してみるのが一番分かりやすいです。 - -nはIPアドレス、ポート番号を名前解決しない(付けなくてもいいのでお好みで)
当たり前ですが、これをファイルに出力して、Windows等のWiresharkがインストールされているPCにscpすることでWiresharkで見ることができます。
ip netns exec router1 tcpdump -w /tmp/hoge.cap -i e1
- -iはインターフェイス名を指定(必要)
- -wは出力ファイル名を指定(必要)
でもリアルタイムに見ることができないし、毎回scpとかめちゃくちゃ面倒くさいですよね。
sshdumpを使用
Wiresharkの追加コンポネントにsshdumpというものがあり、これを使うことでwiresharkでキャプチャするインターフェイスを選択するときにSSHするホスト、実行コマンド(≒キャプチャするインターフェイス)を指定できます。
こちらに詳しく書いてらっしゃる方がいるので詳しくはこちらをどうぞ。
簡単に書くと、
- Wiresharkインストール時に「Sshdump and Ciscodump」を選択する
- SSHでパスワードなしでリモートにログインできるようにしておく
- Wiresharkのキャプチャインターフェイス指定時に「SSH remote capture」を選択する
- Serverタブ
- Captureタブ
tcpdumpの引数は
- -w -でファイル名をハイフンにすることで標準出力に書き出す(&それをWiresharkが読み込む)
- -Uは-lと似ていますが、バイナリ形式で書き出すのでline-bufferedじゃなくてpacket-bufferedにします。
sshdumpで取得すると非常に快適です。
リアルタイムでSSH越しのLinuxの特定のNICのパケットをWiresharkで見ることができます。
ちょっとパケットを見るだけであればこれで十分かなと思うのですが、
- インストール時に追加コンポーネントが必要
- 違うインターフェイスをキャプチャしたいときに毎回SSH remote captureをクリックしてCaptureタブをクリックして、NIC名をクリックして変更して…
というのが面倒くさいんですよね…
WiresharkのコマンドラインオプションでSSH dumpの引数を指定できればいいのですが、どうすればいいのだろう??(知っている方いたら教えてください)
SSHとWiresharkをパイプで繋ぐ
ところで最近のWindowsだとputtyやteratermインストールしなくても標準でssh使えるのと、Wiresharkでは標準入力からパケットを読むことができるので、これを組み合わせればいいのでは?と思いやってみました。
コマンドプロンプトで以下を打ちます。
sshはパスワードなしでログインできるように事前にしておいてください。
start cmd /c ssh 192.168.10.160 ip netns exec router1 tcpdump -w - -U -i e1 ^| "c:\Program Files\Wireshark\Wireshark.exe" -k -i -
start cmd /c ~でssh以降のコマンドをバックグラウンドで実行します。なんでバックグラウンドにしているかというと、キーボードの上キーを押してnetwork namespace名とかインターフェイス名をちょちょっと修正して複数のWiresharkを同時に立ち上げるのを容易にするためです。
ssh [リモートサーバのIP] ip netns exec [network namespace名] tcpdump -w - -U -i [インターフェイス名]でリモートサーバでtcpdumpして結果を標準出力に出しています。
^|はパイプ、^でエスケープしないとstartコマンドの結果をWiresharkに渡してしまい想定通りの動きにならないです。
(実はコマンドプロンプトの構文は良くわかっていないので説明間違っているかも)
wireshark.exeの-kは即時キャプチャ開始、-i -は標準入力からの読み込みです。
いい感じにパケットキャプチャできるようになりました。
sshdumpはインストールしなくても大丈夫です。
まとめ
- リアルタイムに見たい。長いコマンドを覚えられない。→sshdumpをインストールする
- リアルタイムに見たい。多数のインターフェイスキャプチャを同時に立ち上げたい。→コマンドプロンプトでsshとwiresharkをパイプで繋ぐ
Discussion