【実務・中級編】 VPCフローログのサンプリング間隔、集約ウィンドウ、およびドロップパケットの解析 – クラウドインフラと仮想化ネットワーク実践ガイド

パケットはどこへ消えた?AWS VPCフローログのサンプリング、集約ウィンドウ、そしてドロップパケット解析の深層

「おい、また本番環境のAPIサーバーから、外部の決済代行APIへの通信がタイムアウトしているぞ。セキュリティグループ(SG)のルールは追加したはずなのに……!」

夜遅く、Slackのインシデントチャネルに飛び込んできたピリついたアラート。あなたなら、この「闇に消えたパケット」をどうやって暴き出しますか?

こんにちは。数々の修羅場をくぐり抜けてきたシニアSREの私です。クラウドネイティブなシステムを運用していると、「通信できない」というトラブルに必ず直面します。KubernetesのPodから外へ出られない、あるいはALBからバックエンドのECSタスクへ接続できない。そんなとき、私たちの強力な武器となるのが AWS VPCフローログ(VPC Flow Logs) です。

しかし、このVPCフローログ、ただ有効化して眺めているだけでは本領を発揮しません。パケットが実際にキャプチャされてからS3やCloudWatch Logsに流れるまでの「タイムラグ」、そしてセキュリティグループやネットワークACL(NACL)に弾かれたパケット(REJECT)がログ上でどう表現されるのか。このメカニズムを骨の髄まで理解していないと、障害対応の現場で痛い目をみます。

今回は、VPCフローログのライフサイクル、サンプリングと集約の裏側、そしてドロップパケットの解剖学を、現場のノウハウを交えながら徹底的に解説していきましょう。

—

1. パケットのライフサイクルと集約ウィンドウの正体

まず、VPCフローログがどのように生成されるのか、そのパケットの旅路を追ってみましょう。

教科書的には「VPC内のネットワークインターフェイス(ENI)を通過するIPトラフィックを記録する機能」と説明されますが、実務上知っておくべき極めて重要な事実があります。それは、VPCフローログはリアルタイムのパケットスニッファー(Wiresharkのようなもの)ではないということです。

サンプリングと集約(Aggregation)のメカニズム

ENIを通過したすべてのパケットが、1対1でログの1行になるわけではありません。AWSのハイパーバイザー層で動作するロギングエージェントは、パフォーマンスとストレージコストのバランスを取るために、次のようなプロセスでデータを処理しています。

1. キャプチャ: ENIを通過するパケットのメタデータをメモリ上で捉えます。
2. フローの集約 (Aggregation): 宛先IP、送信元IP、ポート、プロトコルなどの「5タプル」が一致するパケット群を一定期間まとめ上げます。
3. 集約ウィンドウ (Aggregation Interval): まとめたデータを外部ストレージ(S3やCloudWatch Logs)にフラッシュするまでのウィンドウ時間です。

AWSでは、この集約ウィンドウとして 「1分(60秒)」 または 「10分」 を選択できます。実務のトラブルシューティングにおいて、これは生死を分けるパラメータです。

> SREの教訓: リアルタイム性が求められるセキュリティインシデントの調査では、必ず集約ウィンドウを 1分 に設定してください。10分に設定していると、障害発生からログに反映されるまでに最大10分のタイムラグが生じ、原因究明が致命的に遅れます(コストは若干上がりますが、障害時の調査スピードに比べれば微々たるものです)。

—

2. REJECTパケットの解剖:なぜその通信は捨てられたのか?

セキュリティグループやNACLの設定ミスでパケットがドロップされた場合、VPCフローログには action フィールドに REJECT が記録されます。

ここで、多くのエンジニアがハマる罠があります。それは、「送信側(クライアント)のENI」と「受信側(サーバー)のENI」のどちらにログが出るか という点です。

通信フローとログの出力ポイント

例えば、クライアント(Pod)からサーバー(外部API)へリクエストを投げたものの、サーバー側のセキュリティグループでインバウンドが塞がれていたとします。このとき、ログはどこに残るでしょうか?

  • クライアント側ENI: パケットは送信されているため、action=ACCEPT(あるいは往路は出ていく)。
  • サーバー側ENI: サーバーのセキュリティグループがパケットを拒絶するため、サーバー側のENIのフローログに action=REJECT が記録されます。

つまり、パケットをドロップした張本人であるENIのフローログを見なければ、本当の拒絶理由はわからないのです。

VPCフローログの標準フォーマットと注目すべきフィールド

デフォルトのログフォーマットに加え、カスタムフォーマットを活用することで、より詳細な情報を引き出すことができます。最低限、以下のフィールドの意味を押さえておきましょう。

  • version: フローログのバージョン(通常は2以降)
  • account-id: AWSアカウントID
  • interface-id: 対象のENI ID
  • srcaddr / dstaddr: 送信元および宛先のIPアドレス
  • srcport / dstport: 送信元および宛先のポート番号
  • protocol: IANAプロトコル番号(TCPは 6、UDPは 17 など)
  • packets: 集約ウィンドウ内で転送/ドロップされたパケット数
  • bytes: 転送/ドロップされたバイト数の総計
  • start / end: フローの最初のパケットがキャプチャされた時間、および最後のパケットの時間(Unixエポック秒)
  • action: ACCEPT(許可)または REJECT(拒絶)
  • log-status: OK(正常記録)、NODATA(データなし)、SKIPDATA(キャプチャ容量オーバー等によるスキップ)

—

3. 実践:CloudWatch Logs Insightsを使ったドロップパケットのハンティング

口で言うだけではなく、実際に手を動かしてみましょう。
例えば、特定のプライベートサブネットから外部への通信が REJECT されている状況を想定し、CloudWatch Logs Insightsで迅速に犯人を特定するためのクエリを記述します。

以下のクエリをCloudWatch Logs Insightsのコンソールに貼り付けて実行してください。

-- セキュリティグループやNACLによってドロップされた通信を集計するクエリ
fields @timestamp, interface-id, srcaddr, dstaddr, dstport, protocol, packets, bytes
| filter action = "REJECT"
| stats count(*) as reject_count, sum(bytes) as total_bytes by srcaddr, dstaddr, dstport
| sort reject_count desc
| limit 20

このクエリのポイントは、action = "REJECT" でフィルタリングした上で、どの送信元(srcaddr)からどの宛先・ポート(dstaddr, dstport)への通信が最も多く拒絶されているかを一目で集計できる点です。

Pythonによる自動解析スクリプトの活用

もし、大量のログをローカルで詳細に分析したい、あるいはSlackへ自動通知させたいといった場合は、Boto3を使ってCloudWatch Logsからデータを取得するスクリプトが役立ちます。以下に、実務でそのまま使えるPythonスクリプトのサンプルを提示します。

import time
import boto3

# クライアントの初期化(リージョンやプロファイルは適宜変更してください)
client = boto3.client("logs", region_name="ap-northeast-1")

# 検索対象のCloudWatch Logsロググループ名
LOG_GROUP_NAME = "/aws/vpc/flow-logs/my-production-vpc"


def query_rejected_flows(log_group_name):
    # 過去1時間以内のデータを対象とする
    start_time = int(time.time()) - 3600
    end_time = int(time.time())

    query = """
        fields @timestamp, interface-id, srcaddr, dstaddr, dstport, protocol
        | filter action == "REJECT"
        | sort @timestamp desc
        | limit 10
    """

    print("CloudWatch Logs Insightsへのクエリ実行中...")
    response = client.start_query(
        logGroupName=log_group_name,
        queryString=query,
        startTime=start_time,
        endTime=end_time,
    )

    query_id = response["queryId"]

    # クエリの完了を待機
    while True:
        status_response = client.get_query_results(queryId=query_id)
        status = status_response["status"]

        if status == "Complete":
            print("クエリ完了。結果を解析します:\n")
            for row in status_response["results"]:
                # 各フィールドの値を抽出して表示
                log_data = {item["field"]: item["value"] for item in row}
                print(
                    f"Time: {log_data.get('@timestamp')} | "
                    f"ENI: {log_data.get('interface-id')} | "
                    f"Src: {log_data.get('srcaddr')} -> "
                    f"Dst: {log_data.get('dstaddr')}:{log_data.get('dstport')} | "
                    f"Protocol: {log_data.get('protocol')}"
                )
            break
        elif status in ["Failed", "Cancelled"]:
            print(f"クエリが失敗しました。ステータス: {status}")
            break

        print("結果待ち...")
        time.sleep(2)


if __name__ == "__main__":
    query_rejected_flows(LOG_GROUP_NAME)

このスクリプトを回すことで、どのIPアドレス間の通信が遮断されているのかをプログラム側から迅速にキャッチアップし、インシデントの初動対応を劇的に効率化できます。

—

4. トラブルシューティングの現場における実践的なTips

最後に、長年のインフラ運用で得た「VPCフローログ運用のベストプラクティス」をいくつか授けましょう。

1. log-status の SKIPDATA に注意する
もしログに SKIPDATA が頻出している場合、それはENIを通過するトラフィック量が多すぎて、AWS側でロギングの処理が追いつかずドロップされている状態を意味します。主要なルーターや高トラフィックなNATゲートウェイのENIでは、サンプリングレートやリソース設計の見直しが必要です。

2. カスタムフォーマットで可観測性を高める
デフォルトのフィールドだけでは、フローがどのTCPフラグで終了したか(例: FINやRST)や、パケットの方向(flow-direction)が分かりにくい場合があります。本番環境のVPCフローログを有効化する際は、必ず flow-direction や tcp-flags を含んだカスタムフォーマットを定義するようにしましょう。

3. コスト最適化を忘れない
フローログは非常に強力ですが、全ENIで有効化して1分間隔にすると、CloudWatch LogsやS3のストレージ・スキャンコストが爆発的に跳ね上がります。「普段は必要最小限のサブネットに絞り、障害切り分け時やセキュリティ監査時に動的に有効化する」あるいは「S3にParquet形式で出力してAthenaで安価にクエリする」といった設計思想を持つことが、プロのアーキテクトとしての腕の見せ所です。

—

まとめ

パケットは嘘をつきません。ネットワークの迷宮で迷子になったパケットの足跡をたどり、セキュリティグループの壁に激突した瞬間を捉える。VPCフローログの仕組みとライフサイクル、そして集約ウィンドウの挙動さえ頭に入っていれば、どんな不可解な通信エラーも必ず論理的に解明できます。

「なぜつながらないのか」と悩む夜から解放され、スマートにパケットをハンドリングできる真のネットワーク・マスターを目指しましょう。あなたのインフラライフに、幸運な ACCEPT が常にあることを祈っています!

コメント

タイトルとURLをコピーしました