話題の記事

[EC2]5分でできる!? WireSharkのリモートキャプチャー

2014.08.31

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

はじめに

Amazon LinuxをはじめとするEC2インスタンスはグラフィカルログインが提供されていませんのでWireSharkによるリアルタイムキャプチャーができません。そのため、EC2の入出力パケットをキャプチャーをするにはtcpdumpでキャプチャーして、そのファイルをローカルのPCにダウンロードしてWireSharkで確認します。この方法は、手間が多いだけでなく、ネットワークに流れるパケット情報をリアルタイムで調査できるWireSharkの長所が失われてしまします。

キャプチャー対象となるEC2インスタンスの設定変更と添付したシェルの設定項目を書き換えのみで、リモートキャプチャーできるランチャーを作成しましたのでご紹介します。

5分で手早く利用したい方は、下記のシェルと設定ファイルをコピーして、図を参考に設定を置き換えることで動作できるでしょう。

WireSharkのリモートキャプチャー

tcpdumpをエージェントとして利用したWireSharkのリモートキャプチャーです。キャプチャー対象のサーバーにssh接続してtcpdumpを実行し、キャプチャーデータのストリームをMacやLinux上のWireSharkに送りリアルタイム解析します。

一般にELB配下のwebサーバーやセキュアなプライベートネットワークのサーバーには直接ログインすることはできませんので、以下の例では、踏み台サーバー(bastion)を経由してELB配下のWebサーバーをキャプチャーする例です。

wireshark-remote

提供する機能

MacとLinuxで動作するように実装し、以下の機能を実現しています。

  • tcpdumpをエージェントとして利用したリモートキャプチャー
  • キャプチャーデータの圧縮転送
  • キャプチャーデータ転送パケットの除外
  • ポートフォワーディングによって踏み台を経由してPrivateのEC2インスタンスのキャプチャーに対応
  • 通信経路のキープアライブ(デフォルト:60秒)
  • キャプチャのフィルター条件を自由に設定
  • 関連プロセスの生成・開放の制御

WireSharkのインストール

インストールしていない場合はクライアントとなるMacやWindowsにWireSharkをインストールしてください。リモートキャプチャーですので、NICがないマシンで結構です。

Macの場合

RHEL6/CentOS6の場合

  • Wireshark と wireshark-gnome sudo yum install wireshark.x86_64 wireshark-gnome.x86_64

wireshark-remoteの設定

設定ファイルの例

デフォルトで読み込まれる設定ファイルは、wireshark-remote.confです。

###############################################################################
# Target Host Setting
#

# EC2のキーペア
# EC2にSSHでログインするときに使用するキーペアのファイルパスを指定してください。
KEY_PAIR=/Users/foo/key-pair.pem

# EC2の接続ユーザ
# EC2にログインする場合のユーザ名です。Amazon Linux の場合はec2-userを指定してください。
USER=ec2-user

# 接続ホスト名
# PublicのIPアドレスでアクセスできる場合は、EC2のPublic DNSを指定する。
# 踏み台サーバを経由する場合はlocalhostを指定する。
#CONNECT_HOSTNAME=ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com
CONNECT_HOSTNAME=localhost

###############################################################################
# Capture Setting
#

# チャプチャーインタフェース
# キャプチャー対象のネットワークインタフェース名を指定してください。
# Amazon Linux はeth0を指定してください。
INTERFACE=eth0

# キャプチャーIPアドレス(EC2のPrivate DNSのIPアドレス)
TARGET_PRIVATE_IPADDR=yy.yy.yy.yy

# キャプチャーフィルタ
# (通信が大量にある場合は設定することが必須)
# 例.FILTER="tcp port 80"
FILTER=

###############################################################################
# Portforward Setting (Optional)
#

# ポートフォワードする場合はローカルの空きポート番号を指定する(1024番以上)
# ポートフォワードを利用指定しない場合はコメントに設定してください。
PORTFORWARD_PORT=8022

# 踏み台サーバ(ポートフォワードサーバ)を指定する
# EC2のPublic DNSを指定する。
PORTFORWARD_HOSTNAME=ec2-zz-zz-zz-zz.ap-northeast-1.compute.amazonaws.com

EC2のキーペアのファイルパス

EC2にSSHでログインするときに使用するキーペアのファイルパスを指定してください。

例.key-pair.pemの場合 KEY_PAIR=/Users/foo/key-pair.pem

EC2の接続ユーザ

EC2にログインする場合のユーザ名です。Amazon Linux の場合はec2-userを指定してください。

例.ec2-userの場合 USER=ec2-user

接続ホスト名

ポートフォワーダを利用して踏み台サーバを経由する場合はlocalhostを指定してください。一方、PublicのIPアドレスでアクセスできる場合は、AWSのManagement Consoleからキャプチャー対象となるEC2の設定”Public DNS”に表示されているホスト名のFQDNを指定してください。

例.ポートフォワーダを利用する場合 CONNECT_HOSTNAME=localhost

例.PublicのIPアドレスでアクセスできる場合 CONNECT_HOSTNAME=ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com

キャプチャーインタフェース

キャプチャー対象のネットワークインタフェース名を指定してください。Amazon Linux はeth0を指定してください。

例.eth0の場合 INTERFACE=eth0

 キャプチャーIPアドレス

AWSのManagement Consoleに”Private DNS”に表示されているIPアドレスを指定してください。 この指定をすることでEC2とPC間のSSHパケットをキャプチャーの対象から除外します。この指定に誤りがあるとキャプチャーデータ送信パケットをさらにチャプチャーしてしまい正しい結果が得られません。

例.yy.yy.yy.yyの場合 TARGET_PRIVATE_IPADDR=yy.yy.yy.yy

キャプチャーフィルタ

TCPDUMPのキャプチャーフィルタを指定します。詳細は PCAP-FILTER の EXAMPLESを参考にしてください。

例.全て FILTER=

例.HTTP(80番ポート) FILTER="tcp port 80"

Portforwarderポートの設定

ポートフォワードを利用して踏み台サーバーを経由する場合は、ローカルの空きポート番号(1024番以上)を指定してください。一方、ポートフォワードを利用指定しない場合はコメントに設定してください。

例.8022番ポートの場合 PORTFORWARD_PORT=8022

Portforward Sercverの設定

ポートフォワードサーバ(踏み台サーバ)のEC2のPublic DNSを指定する。

例.ec2-zz-zz-zz-zz.ap-northeast-1.compute.amazonaws.comの場合 PORTFORWARD_HOSTNAME=ec2-zz-zz-zz-zz.ap-northeast-1.compute.amazonaws.com

wireshark-remote.sh

#!/bin/sh
#
# Name
#   wireshark-remote
#
# format
#   wireshark-remote.sh [-c config_path]
#
# description
#   ssh経由でtcpdumpを実行した結果をwiresharkに転送することによって
#   間接的にwiresharkによるリモートキャプチャーする
#
# requirements
#   1. !requiretty設定
#     リモートホスト(EC2)でtcpdumpを実行するユーザ(ec2-user)に
#     コマンド(tcpdump)を実行するときにTTYを要求しない設定を追加する
#     例.ec2-userの場合、visudoにて以下の行を追加
#       Defaults:ec2-user !requiretty
#
#   2. Wiresharのキャプチャー開始
#     このシェルを実行してWireshark起動すると直ちにスタートボタンを
#     押してください。
#
# return
#      0 =  SUCCESS
#      0 != FAILED
#

##############################################################################
# Function
#

trap 'terminate' HUP
trap 'terminate' INT
trap 'terminate' TERM

terminate()
{
killchild $$
}

killchild()
{
local ppid=$1
local is_target=0
local is_pid pid
local pslist=`ps -o ppid,pid`
local i=0
for pid in $pslist; do
  is_pid=`expr $i % 2`
  if [ $is_pid -eq 1 ]; then
    if [ $is_target -eq 1 ]; then
      kill $pid >/dev/null 2>&1
    fi
    is_target=0
  else
    if [ "x$pid" == "x$$" ]; then
      is_target=1
    fi
  fi
  i=`expr $i + 1`
done
}

##############################################################################
# Main
#

SSH=ssh
SUDO=sudo
WIRESHARK=wireshark
TCPDUMP=tcpdump

SNAPLEN=1600
KEEP_ALIVE=60

# include config. (default: wireshark-remote.conf)
if [ "x$1" == "x-c" ]
then
  config=$2
else
  config=`pwd`/wireshark-remote.conf
fi
if [ -f $config ]
then
  source $config
else
  echo "Invalid config file : "$config
fi

# Portforwarding as child process.
if [ "x$PORTFORWARD_PORT" != "x" ]
then
  sleep 1
  ${SSH} -i ${KEY_PAIR} -o ServerAliveInterval=${KEEP_ALIVE} -N -L ${PORTFORWARD_PORT}:${TARGET_PRIVATE_IPADDR}:22 ${USER}@${PORTFORWARD_HOSTNAME} &
  portforward_option=" -p ${PORTFORWARD_PORT} "
fi
sleep 2

# Set Filter
if [ "x$FILTER" != "x" ]
then
#  filter=" or \(${FILTER}\)"
  filter=" or ${FILTER}"
fi

# Capture With tcpdump.
exclude_ipaddr=${TARGET_PRIVATE_IPADDR}
${SSH} -i ${KEY_PAIR} ${portforward_option} -C -o ServerAliveInterval=${KEEP_ALIVE} ${USER}@${CONNECT_HOSTNAME} ${SUDO} ${TCPDUMP} -U -i ${INTERFACE} -s ${SNAPLEN} -w - "not \(host ${exclude_ipaddr} and tcp port 22\) ${filter}"  | ${WIRESHARK} -i -

result=$?
if [ $result -ne 0 ]; then
  terminate
fi

exit $result

実行手順

キャプチャー対象のサーバーの設定変更

この設定はキャプチャするサーバー、つまりtcpdumpを実行するサーバー上に設定してください。

リモートホスト(EC2)でtcpdumpを実行するユーザ(ec2-user)にコマンド(tcpdump)を実行するときにTTYを要求しない設定を追加します。再起動なしに設定・解除ができます。

例.ec2-userの場合、visudoにて以下の行を追加 Defaults:ec2-user !requiretty

wireshark-remote.shの実行

デフォルトでは実行ディレクトリの設定ファイル(wireshark.conf)を読み込みます。個別の設定ファイルを読み込ませて

例.デフォルトの設定ファイル(wireshark-remote.conf)で起動する ./wireshark-remote.sh

例.設定ファイル(another-setting.conf)を指定して起動する ./wireshark-remote.sh -c another-setting.conf

WireSharkのキャプチャーを開始

WireSharkが起動するとキャプチャインタフェースに「-:(NULL)」が指定されています。この状態で、「スタート」(赤く囲ったボタン)を押して実行してください。

Macの場合

mac-wireshark-start

RHEL6/CentOS6の場合

centos-wireshark-start

WireSharkのキャプチャーを停止

キャプチャー結果の保存はこれまで通りです。データの保存が済みましたらCtrl+Cを押しランチャーを停止してください。

Ctrl+Cで停止させる方法は、荒っぽい印象を受けるかもしれませんが、ランチャーのシェルが停止することによって、子プロセスであるリモートのtcpdumpプロセスや、ポートフォワーディングなどの関連プロセスがクリーンナップされるように実装しています。

最後に

VPNやDirect Connectといったネットワーク設定などは実際のパケットの動きをリアルタイム確認しながら構築・検証を進めることが欠かせません。あらゆる通信が暗号化される今日においても、ELBのSSLターミネション機能を利用している環境では内部のメッセージは暗号化しておりませんので、パケットキャプチャリングによる調査は効果的です。実務での利用を意識して踏み台サーバーを経由したリモートキャプチャーに対応しましたので、ぜひともご活用ください。