Amazon CloudWatch Network Monitorで送出される監視パケットを調べてみた

2023.12.27

しばたです。

先日AWSより相手先にオンプレ環境を想定したネットワーク監視を行うAmazon CloudWatch Network Monitorがリリースされました。
サービスの概要などは以下の記事をご覧ください。

こちら仕組みとしては割とシンプルで、監視元となるVPCに専用のENIを生やし宛先となるアドレスに対しICMPおよびTCPパケットを送出して監視を行います。
ただ、より具体的な内容として「どの様なデータ(パケット)」を「どの程度の頻度で送出する」のか明記されていなかったので実際に確認することにしました。

検証環境

今回は私の検証用AWSアカウントの東京リージョンにVPCを一つ用意し、そこにCloudWatch Network Monitor環境を一つ作成します。
監視の宛先は同一VPC内にAmazon Linux 2023 EC2を1台用意しておきます。

プローブは2つ作成し、それぞれ「ICMP」の監視、「TCP 8080」の監視を行います。
TCPの監視を受け付けるため宛先のEC2にNGINXをインストールして8080ポートでHTTPサーバーを公開しておきます。
ポート番号が8080なのはインスタンスメタデータへの通信がTCP 80で発生しキャプチャしにくかったためです。

注意 : 宛先が同一VPCにあることに関して

CloudWatch Network Monitorはドキュメントの冒頭に

Amazon CloudWatch Network Monitor provides visibility into the performance of the network connecting your AWS hosted applications to your on-premises destinations and allows you to identify the source of any network performance degradation within minutes.

とある様に宛先がSite-to-Site VPNやDirect Connectを超えた先にあるオンプレミス環境を想定したサービスです。

今回は単純に「手軽にパケットキャプチャしたい」という意図で宛先を同一VPC内のEC2にしています。
ただ、詳細は後述しますが、これはAWSが想定しない構成であり良い結果を得ることができませんでした。

CloudWatch Network Monitorの設定

作成したCloudWatch Network Monitorはこんな感じでメトリクスの集計期間はデフォルトの30秒にしています。

ICMP監視用のプローブはこんな感じにしており、IPアドレスを宛先EC2に設定しパケットサイズはデフォルトの56Byteにしています。

TCP監視用のプローブはこんな感じで、こちらもパケットサイズはデフォルトの56Byteのままです。

確認結果

各プローブをしばらく稼働させた状態で宛先EC2にログインしてtcpdumpを使ったパケットキャプチャを行いました。

1. ICMPパケット

最初に以下の様なコマンドを打ち、どの程度の間隔で監視用のパケットがやってくるか確認してみました。

# ICMPパケットをキャプチャ
sudo tcpdump icmp

予想としては「メトリクスの集計期間(30秒)ごとにいくつかのパケットが来るのかな?」と思っていたのですが、実際にはパケットキャプチャを始めた瞬間からずっとICMPパケットが届き続けました。
今回作成したプローブでは2つのENIが生成されており、両方のENIから均等にパケットがやってきました。
結果として、

  • 2つのENI両方からICMPパケットが送出される
  • 常に連続してパケットが送られ続ける

という動作となります。

つぎに個別パケットの内容を確認したところ以下のとおりでした。

前の記事でPingコマンドのパケットサイズについて書きましたが、CloudWatch Network Monitorでは「ICMPパケット全体で56Byte(=ペイロードは48Byte)」となっていました。
ペイロードにタイムスタンプは含まれず、その内容もランダムなバイト列 *1が設定されていました。

Pingコマンドと同サイズのパケットを送りたい場合は64Byteに設定する必要がありますのでご注意ください。

また、プローブの設定でパケットサイズを変更した結果はだいたい1分後に反映されました。
思ったより変更が反映されるのが早かったです。

2. TCPパケット

次に以下の様なコマンドを打ち、TCPパケットがやってくる頻度を確認してみたのですがかなり謎な結果になりました...

# 8080ポートに関連する通信をざっくりチェック
sudo tcpdump port 8080

# 一応Probe ENIに関連する通信もチェック済み
sudo tcpdump host 10.0.21.105 or host 10.0.21.215

期待に反してTCPのパケットが一切やってきませんでした。

ただ、非アクティブ化ト→アクティブ化の流れでプローブを再アクティブ化してみると、アクティブ化されて最初の間(約1分間)だけはTCPパケットの受信を確認できました。 *2

その際はICMP同様連続したパケットが送られていました。
パケットキャプチャした結果はざっくりこんな感じです。

ドキュメントに記載の通り最初にSYNパケットが送信され、SYN+ACKが返されたあとは直ちにRSTを送り通信を終了しています。
SYNパケットのサイズはTCPヘッダ 20Byte + ペイロード 36Byteで合計56Byteと設定通りでした。

そしてキャプチャした最後のフレームを確認してみると宛先EC2からACK + RSTを送っており、パケットの送出が止まってしまったのはEC2側に原因があるかもしれません。

一応NGINX側でパケットをドロップしてる可能性を考慮し別ポートとツール(TCP 22, sshdやWindowsインスタンスでTCP 3389, rdp)でも確認してみましたが同じ結果でした。
ただし、これらは宛先からACK + RSTを送ることは無かったです。

加えてこの状況でもCloudWatch Metricsでは「パケットロス0%」「RTT0ミリ秒」という値が記録され続けてしまいました。メトリクスが欠落するならまだ納得いくのですがかなり謎な結果となっています。

「どうせパケットが来ないならEC2をシャットダウンしたらどうなるだろう?」と思い、こちらも試しましたが変わらず「パケットロス0%」「RTT0ミリ秒」のままでした。

(上図はEC2をシャットダウンしたまま放置した状態)

データポイントの数(サンプル数)を確認すると1分間に2つとメトリクスの集計期間30秒と合致したので、これらのメトリクスではあくまでもロス率やRTTの計算結果を0として定期計上しているだけの様です。

ちなみにICMPであれば常にパケットが送出されているのでロス率100%が記録されます。
TCPも同じ挙動になることを期待していたのですがそうはいきませんでした。

(宛先が停止している場合の結果。ICMPはパケットロス100%、TCPはパケットロス0%に)

サポート問い合わせするも

いちおうTCP監視の挙動についてサポートに問い合わせてみたのですが、ざっくり「AWSとしては宛先にオンプレミス環境を想定したサービスでありVPC内を宛先とするのは想定外。(大意)」という状況でこれ以上の調査は難しそうです。

想定外の環境で試している私が悪いので仕方ありません。

最後に

以上となります。

パケットロス率やRTTを計算する都合でしょうが予想以上にアグレッシブに監視用パケットを送出していました。

また、AWSが想定していない検証環境であることが悪いものの、TCPパケットの監視については機能自体に不安を覚える結果となってしまいました。
日程は約束できませんが後日改めてオンプレミス環境に対する監視でも同様か調査したいと思います。

脚注

  1. 調べた限りでは法則性を見つけることができませんでした...
  2. 加えてプローブの設定内容を変更した際(Pending→Activeの状態変化が発生した際)も同様の挙動となった