ちょっと話題の記事

[Wireshark] sshdumpを使って手元のマシンからEC2インスタンスのパケットキャプチャーをしてみた

快適なWiresharkライフを
2023.03.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

tcpdumpではなくてWiresharkでパケットを確認したいな

こんにちは、のんピ(@non____97)です。

皆さんはリモートのLinuxマシンをtcpdumpではなくて手元のマシンのWiresharkでパケットを確認したいなと思ったことはありますか? 私はあります。

tcpdumpで上手にフィルタリングをすれば良いのでしょうが、そうでなければ高速目grepすることとなり大変です。

そういった時は慣れ親しんだWiresharkが恋しくなるものです。

実はWiresharkでsshdumpを使えば、SSH越しにリモートコンピューターのパケットキャプチャーをすることはご存知でしょうか。

NAME

sshdump - Provide interfaces to capture from a remote host through SSH using a remote capture binary.

. . (中略) . .

DESCRIPTION

Sshdump is an extcap tool that allows one to run a remote capture tool over a SSH connection. The requirement is that the capture executable must have the capabilities to capture from the wanted interface.

sshdump(1)

これにより簡単にLinux系のマシンのパケットキャプチャーも手元のマシン上のWiresharkで行うことができます。

以下記事で紹介しているような特別なスクリプトは必要ありません。

これはありがたいですね。

試してみたので紹介します。

いきなりまとめ

  • sshdumpを使えば手元のマシンからEC2インスタンスのパケットキャプチャーを簡単にできる
    • Amazon Linux 2であればEC2インスタンスの設定変更は不要
  • 適切なキャプチャーフィルターとディスプレイフィルターを設定しよう

検証環境

検証環境は以下の通りです。

sshdumpを使って手元のマシンからEC2インスタンスのパケットキャプチャーをしてみた検証環境構成図

Publicサブネット上にAmazon Linux 2のEC2インスタンスを起動させています。

EC2インスタンスにはキーペアを設定しており、インターネット越しにSSHで接続できるようにしています。また、インスタンスプロファイルのIAMロールにはAmazonSSMManagedInstanceCoreをアタッチしています。

手元のマシンのOSはMacです。WiresharkはHomebrewでインストールしました。その際にsshdumpも一緒にインストールされていました。

# macOSのバージョン
>  sw_vers
ProductName:		macOS
ProductVersion:		13.0.1
BuildVersion:		22A400

# HomebrewでWiresharkをインストールした際の情報
>  brew info wireshark
==> Downloading https://formulae.brew.sh/api/formula.jws.json
######################################################################## 100.0%
==> Downloading https://formulae.brew.sh/api/cask.jws.json
######################################################################## 100.0%
Warning: Treating wireshark as a formula. For the cask, use homebrew/cask/wireshark
==> wireshark: stable 4.0.4 (bottled), HEAD
Graphical network analyzer and capture tool
https://www.wireshark.org
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/wireshark.rb
License: GPL-2.0-or-later
==> Dependencies
Build: cmake ✘
Required: c-ares ✔, glib ✔, gnutls ✔, libgcrypt ✔, libmaxminddb ✔, libnghttp2 ✔, libsmi ✔, libssh ✔, lua ✔
==> Options
--HEAD
	Install HEAD version
==> Caveats
This formula only installs the command-line utilities by default.

Install Wireshark.app with Homebrew Cask:
  brew install --cask wireshark

If your list of available capture interfaces is empty
(default macOS behavior), install ChmodBPF:
  brew install --cask wireshark-chmodbpf
==> Analytics
install: 3,175 (30 days), 26,486 (90 days), 128,326 (365 days)
install-on-request: 3,699 (30 days), 27,160 (90 days), 127,422 (365 days)
build-error: 0 (30 days)

# Wiresharkのバージョンの確認
>  wireshark --version
 ** (wireshark:29217) 13:07:15.798439 [Epan WARNING] epan/prefs.c:4574 -- read_prefs_file(): Incomplete preference at line 25: of
<ホームディレクトリ>/.config/wireshark/recent_common (save preferences to remove this warning)
Wireshark 4.0.4 (v4.0.4-0-gea14d468d9ca).

Copyright 1998-2023 Gerald Combs <gerald@wireshark.org> and contributors.
Licensed under the terms of the GNU General Public License (version 2 or later).
This is free software; see the file named COPYING in the distribution. There is
NO WARRANTY; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Compiled (64-bit) using Clang 13.0.0 (clang-1300.0.29.30), with GLib 2.68.4,
with PCRE2, with zlib 1.2.11, with Qt 6.2.4, with libpcap, without POSIX
capabilities, with Lua 5.2.4, with GnuTLS 3.6.15 and PKCS #11 support, with
Gcrypt 1.8.7, with Kerberos (MIT), with MaxMind, with nghttp2 1.46.0, with
brotli, with LZ4, with Zstandard, with Snappy, with libxml2 2.9.9, with libsmi
0.4.8, with QtMultimedia, with automatic updates using Sparkle, with SpeexDSP
(using system library), with Minizip, with binary plugins.

Running on macOS 13.0.1, build 22A400 (Darwin 22.1.0), with Apple M1 Max, with
32768 MB of physical memory, with GLib 2.68.4, with PCRE2 10.39 2021-10-29, with
zlib 1.2.11, with Qt 6.2.4, with libpcap 1.10.1, with c-ares 1.15.0, with GnuTLS
3.6.15, with Gcrypt 1.8.7, with nghttp2 1.46.0, with brotli 1.0.9, with LZ4
1.9.2, with Zstandard 1.4.2, with libsmi 0.4.8, with LC_TYPE=ja_JP.UTF-8, binary
plugins supported.

# sshdumpのバージョン確認
>  sshdump --version
sshdump version 1.1.0
Compiled with libssh version 0.9.6
Running with libssh version 0.9.6/gnutls/zlib

やってみた

Wiresharkの設定変更

早速やってみましょう。

まずは設定変更です。

Wiresharkを起動して、SSH remote capture: sshdump横の歯車マークをクリックします。

sshdumpの設定

ServerタブからRemote SSH server addressでパケットキャプチャーしたいEC2インスタンスのグローバルIPアドレスを指定します。(Public DNS Nameでも良いです)

sshdump_Server

AuthenticationタブからRemote SSH server usernameでSSHする際のユーザー名を指定します。今回はAmazon Linux 2なのでec2-userを指定しました。また、Path to SSH private keyでEC2インスタンスに設定したキーペアの秘密鍵を指定します。

sshdump_Authentication

CaptureタブからRemote capture filterでキャプチャーフィルターを定義します。

sshdump_Capture

ローカルマシンとEC2インスタンス間のSSHのパケットがノイズになるので、今回は以下のようなキャプチャーフィルターとしました。

not (host <ローカルマシンのグローバルIPアドレス> and port 22)

Debugタブの設定値は特に変更しません。

sshdump_Debug

設定変更は以上です。

パケットキャプチャーの実施

実際にパケットキャプチャーをしてみます。

SSH remote capture: sshdumpをクリックします。

sshdumpの開始

すると、以下のように指定したEC2インスタンスのパケットキャプチャーができました。

sshdumpの結果1

非常に簡単ですね。

SSMセッションマネージャーのポートフォワーディングと連携してみた

EC2インスタンスがPublicサブネットにおらず、直接SSHできないこともあると思います。

その場合はSSMセッションマネージャーでSSHをポートフォワーディングしてから行います。

まず、以下のようにSSMセッションマネージャーでパケットキャプチャーをしたいEC2インスタンスのTCP/22を手元のマシンのTCP/10022にポートフォワーディングします。

>  aws ssm start-session --target <EC2インスタンスのID> \
           --document-name AWS-StartPortForwardingSession \
           --parameters '{"portNumber":["22"],"localPortNumber":["10022"]}'

Starting session with SessionId: botocore-session-1678685409-0458928fc23890866
Port 10022 opened for sessionId botocore-session-1678685409-0458928fc23890866.
Waiting for connections...

Waiting for connections...と表示されればOKです。

SSMポートフォワーディングができない場合は以下について確認をします。

  • EC2インスタンスにSSM Agentがインストールされていること
  • EC2インスタンスにSSM Agentが起動していること
  • EC2インスタンスから以下エンドポイントの名前解決ができること
    • ssm..amazonaws.com
    • ssmmessages..amazonaws.com
    • ec2messages..amazonaws.com
  • EC2インスタンスから上述のエンドポイントにHTTPSでアクセスできること
  • AmazonSSMManagedInstanceCoreなど適切なポリシーを持ったIAMロールがインスタンスプロファイルに割り当てられていること
  • ポートフォワーディング先のポートが別プロセスで使われていないこと

次にWiresharkの設定変更を行います。

SSH remote capture: sshdumpServerタブから接続先を変更します。TCP/22を手元のマシンのTCP/10022にポートフォワーディングしているので、Remote SSH server address127.0.0.1Remote SSH server port10022です。

ポートフォワーディングsshdump_Server

この状態でSSH remote capture: sshdumpをクリックすると、パケットキャプチャーが開始されます。

sshdumpの結果2

しかし、SSMセッションマネージャーでポートフォワーディングしている関係上、EC2インスタンスとSSMのエンドポイント間のパケットが大量に流れてしまい非常に辛いです。今回は15秒で11081パケットほどキャプチャーされています。

見た限りApplication Dataのパケットがほとんどでした。

こちらで使用しているIPアドレスを逆引きした結果、SOAレコードがAmazonのものだったため、こちらがSSMに関連するエンドポイントのIPアドレスだと推測します。

> dig -x 209.54.181.198 @8.8.8.8

; <<>> DiG 9.10.6 <<>> -x 209.54.181.198 @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 801
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;198.181.54.209.in-addr.arpa.	IN	PTR

;; AUTHORITY SECTION:
181.54.209.in-addr.arpa. 900	IN	SOA	dns-external-master.amazon.com. root.amazon.com. 1 3600 900 604800 900

;; Query time: 52 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Mar 13 15:09:52 JST 2023
;; MSG SIZE  rcvd: 127

こちらの一連の通信以外のパケットのみを表示するように変更します。

Application DataのTCPの情報を確認すると[Stream index: 0]でした。こちらの一連の通信以外のパケットのみを表示するようにディスプレイフィルターでnot(tcp.stream eq 0)を指定します。

これにより、4パケットのみ表示されるようになりました。

sshdhumpの結果2_tcp.steram eq 0

ただし、ディスプレイフィルターによるフィルタリングであるため、SSMのパケット自体はキャプチャーされ続けています。

確認したい通信がHTTPSではないのであれば、キャプチャーフィルターでnot (tcp port https)と指定するのも良いと思います。

選択したインターフェイスのキャプチャーフィルター

これによりキャプチャーサイズを抑えることができるようになります。

キャプチャーフィルターを追加

キャプチャーフィルターの構文を完全に理解したい場合はpcap-filterのマニュアルをご覧ください。

快適なWiresharkライフを

sshdumpを使って手元のマシン上のWiresharkからEC2インスタンスのパケットキャプチャーをしてみました。

非常に簡単にパケットキャプチャーできましたね。トラブルシューティングはもちろん、パケットを見てニヤニヤしたいなと言う衝動に駆られた際に役立ちます。

sshdumpの接続先マシンではtcpdumpもしくはdumpcapなどパケットキャプチャー用のソフトウェアが動作しています。もし、これらソフトウェアがインストールされていなければインストールしておきましょう。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!