この記事は公開されてから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サーバーをキャプチャーする例です。
提供する機能
MacとLinuxで動作するように実装し、以下の機能を実現しています。
- tcpdumpをエージェントとして利用したリモートキャプチャー
- キャプチャーデータの圧縮転送
- キャプチャーデータ転送パケットの除外
- ポートフォワーディングによって踏み台を経由してPrivateのEC2インスタンスのキャプチャーに対応
- 通信経路のキープアライブ(デフォルト:60秒)
- キャプチャのフィルター条件を自由に設定
- 関連プロセスの生成・開放の制御
WireSharkのインストール
インストールしていない場合はクライアントとなるMacやWindowsにWireSharkをインストールしてください。リモートキャプチャーですので、NICがないマシンで結構です。
Macの場合
- XQuartz http://xquartz.macosforge.org/landing/
- Wireshark http://www.wireshark.org/download.html Or brew install wireshark --with-x
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の場合
RHEL6/CentOS6の場合
WireSharkのキャプチャーを停止
キャプチャー結果の保存はこれまで通りです。データの保存が済みましたらCtrl+Cを押しランチャーを停止してください。
Ctrl+Cで停止させる方法は、荒っぽい印象を受けるかもしれませんが、ランチャーのシェルが停止することによって、子プロセスであるリモートのtcpdumpプロセスや、ポートフォワーディングなどの関連プロセスがクリーンナップされるように実装しています。
最後に
VPNやDirect Connectといったネットワーク設定などは実際のパケットの動きをリアルタイム確認しながら構築・検証を進めることが欠かせません。あらゆる通信が暗号化される今日においても、ELBのSSLターミネション機能を利用している環境では内部のメッセージは暗号化しておりませんので、パケットキャプチャリングによる調査は効果的です。実務での利用を意識して踏み台サーバーを経由したリモートキャプチャーに対応しましたので、ぜひともご活用ください。