十六回目の投稿です。今回の内容は、tcpdumpによるパケットキャプチャの
取得に関するものです。参画中の案件では、顧客の業務システムの運用保守を
担当しており、業務システムを構成するサーバ群から発報されるアラートの
監視などを行っています。直近の業務で、とあるアラートの発報原因調査の
ため、関連する通信のパケットキャプチャを取得する機会がありました。
パケットキャプチャといえば、Wiresharkやtsharkなどで取得することが多い
ですが、案件によってはそういったユーティリティを使うことができません。
そこで今回は、Unix系のディストリビューションに標準的にインストール
されているtcpdumpを使ったパケットキャプチャの取得について紹介します。
◆ tcpdumpの概要
パケットキャプチャを取得してみる前に、tcpdumpについて説明します。
tcpdumpは、先述のとおり、Unix系ディストリビューションに標準的に導入
されており、ネットワークを流れるパケットをキャプチャするツールです。
ツール名に「tcp」とついていますが、TCPに限らず様々なプロトコルの
パケットを取得できます。パケットを見やすくするためのオプションや
フィルタが豊富で、例えばオプションには次のようなものがあります。
・-v:詳細な情報を取得する(-vv、-vvvにて、より詳細な情報を取得できる)
・-i:指定したインターフェースを対象にキャプチャする
・-X:取得した情報を16進数とASCIIで表示する
・-w:指定したファイルに取得した情報を出力する
・-r:-wで出力したファイルを読み込む
また、フィルタを使うことで、送信元/送信先、対象ポートなどでフィルタ
リングしたパケットを取得できます。フィルタにはたくさんの種類があり、
それらを組み合わせて使用することもできます。フィルタの使用例は次の
とおりです。
・23番ポートを使用するパケットの取得
# tcpdump -i <インターフェース名> port 23 -vvv -X -w /tmp/test.pcap
この例では「port」がフィルタに該当します(詳細については参考1が分かり
やすいです)。これを参考に、次節にて、telnet通信のパケットをキャプチャ
してみます。なお、tcpdumpを実行する際には、いくつか留意すべきことが
あります。
・パケットキャプチャは許可された環境でのみ取得する
・tcpdumpの実行にはroot権限が必要である
・-wを用いてファイルへ出力するときは、ファイルサイズの
急増に注意する(ディスク逼迫を回避するため)
◆ パケットキャプチャの取得
本節では、tcpdumpを用いてパケットキャプチャを取得してみます。対象の
プロトコルは、標準でTCPポートの23番を使うtelnetとし、使用するポートは
そのままとします。サーバとクライアント間の通信をキャプチャし、取得した
パケットからTCP通信やtelnetの特徴を確認してみます。
【手順】
[1] 対象サーバにおけるtelnetの有効化
サーバ側でtelnetを起動していない場合は、当然ですがクライアント側から
接続できません。また、必要に応じて使用ポートやファイアウォールなどの
設定を見直しておきます。
$ sudo -s
# systemctl status telnet.socket
# systemctl start telnet.socket
# systemctl status telnet.socket
[2] パケットキャプチャの取得開始
クライアント側でパケットキャプチャの取得を始めます。
インターフェース名はifconfigなどで確認して指定してください。
$ sudo -s # tcpdump -i enp0s5 port 23 -vvv -X -w /tmp/test.pcap
[3] 対象サーバへのtelnet接続
パケットキャプチャの開始後は、別のコンソールを起動してtelent接続します。
接続に用いるアカウントとそのパスワードの入力が求められます。
$ telnet <サーバのIPアドレス> <ポート番号>
[4] パケットキャプチャの取得終了
サーバへ接続できれば、任意のタイミング(適当なコマンドの実行後など)で
パケットキャプチャの取得をCtr-cなどで中断します。
[5] パケットキャプチャの確認
取得したパケットを確認します。このとき、tcpdumpの出力をlessなどに
渡すと確認しやすいです。
# tcpdump -nnttttr /tmp/test.pcap | less
※ nnとttttは、それぞれホスト名とタイムスタンプの表示に関する
オプションで、詳細は参考2が分かりやすいです
取得したパケットの最初の3つを見てみると、それぞれ次のようなパケットで
あることが分かります(TCP通信の特徴である3ウェイハンドシェイク)。
① クライアントの38638番ポートからサーバの23番ポートへのTCP通信で、
パケットにSYNフラグがセットされている
② サーバの23番ポートからクライアントの38638番ポートへのTCP通信で、
パケットにSYNフラグとACKフラグがセットされている
③ クライアントの番38638ポートからサーバの23番ポートへのTCP通信で、
パケットにACKフラグがセットされている
※ 表示パケットにおけるFlag「.」についてはtcpdumpのマニュアルを参照
簡単ではありますが、tcpdumpにてパケットキャプチャの取得ができました。
検証終了後は、必要に応じてtelnetサービスの無効化などを行っておきます。
# systemctl stop telnet.socket
# systemctl status telnet.socket
[補足] パケットキャプチャの解析
取得そのものはtcpdumpで済ませられましたが、tcpdumpでの解析は(個人的には)
不便ですので、更なる解析はWiresharkで行ってみます。上述の画面キャプチャと
同様に、通信が3ウェイハンドシェイクで始まっていることに加え、通信が暗号化
されていないというtelnetの特徴が確認できます。
◆ 感想など
パケットキャプチャを通じて、TCP通信とtelnetの特徴を確認できました。
今後は、tcpdumpのオプションやフィルタに対する理解を深めるとともに、
トラブルシュート時のパケットキャプチャの重要性を学んでいきたいです。
◆ 参考
・【参考1】https://manpages.ubuntu.com/manpages/jammy/ja/man8/tcpdump.8.html
・【参考2】https://www.tohoho-web.com/ex/tcpdump.html
以上です。