リモートホスト上のパケットキャプチャをリアルタイムに手元のマシンの Wireshark で見る方法

ワンライナーで行けちゃいます😁

wireshark -k -i <(ssh user@host "tcpdump -U -n -w - -i eth0 'not port 22'")

しかもリモートホスト側で何かしら特別な準備とかが不要なので非常にお気楽・お手軽です。

前提条件

解説

上記ワンライナーを実行すると、以下の図のように ssh で接続したホスト上で tcpdump コマンドを実行してパケットをキャプチャし、そのパケットキャプチャを手元の Wireshark でリアルタイムに見ることができるようになります。

f:id:bearmini:20170216154859p:plain Icons for a laptop and a server are designed by Gregor Cresnar from Flaticon

ワンライナーは比較的短いので難しくないと思いますが念のため解説します。

まず wireshark コマンドで Wireshark を起動しています。

オプションの -k はすぐにキャプチャを開始する、という意味です。 -i は入力インターフェースの指定ですね。この場合は <( ... ) で指定されるコマンドの出力を Wireshark が読み込むという動きになります。 <( ... )bash の記法です。bash を用いていない場合は -i - と pipe を組み合わせて

ssh user@host "tcpdump -U -n -w - -i eth0 'not port 22'" | wireshark -k -i -

という感じにすればよいでしょう。(末尾の - に注意)

続いて ssh 部分に入っていきます。

user@host はキャプチャを取りたい目的のリモートホスト(とそれにログインするためのユーザー)の指定です。 公開鍵認証をする場合や踏み台サーバー経由でのログインをする場合などはここに引数を追加するか、~/.ssh/config に指定しておくとよいでしょう。

"" で囲まれた部分がリモートホスト上で実行されます。 つまり、tcpdump がいろいろ引数を指定された状態で起動されます。

tcpdump コマンドに渡されている引数を一つずつ見てみましょう。

-U は 1 パケットごとに出力ファイルに出力するように指定するオプションです。(これを指定しないと tcpdump にバッファリングされてしまい、リアルタイム性が損なわれると思われます。)

-n は IP アドレスをホスト名に逆引きする処理を抑制するオプションです。リモートホスト側で名前解決をしてしまうとパケットキャプチャにそれが混じってしまうので DNS クエリをしないようにこれを指定しています。

-w - は標準出力へ出力することを指定するオプションです。リモートホスト上で tcpdump が標準出力にパケットの情報を出力すると、それが ssh 経由でローカルホストの標準出力に出力されます。そしてその標準出力を wireshark に食わせているというわけです。

-i eth0tcpdump がパケットをキャプチャするインターフェース名の指定です。適宜他の名前に変えましょう。

'not port 22'tcpdump でキャプチャするパケットを選別するためのフィルタの指定。ここでは、パケットキャプチャの転送に使われている 22 番ポートのパケットはキャプチャしないように指定しています。