Fortigateのログでcloseとrstが混在する理由をパケットレベルで調べた
ネットワーク運用において、Fortigateのトラフィックログを精査していると「なぜセッション終了時に『close』と『rst』が混在するのか」という疑問に直面することがあります。一見すると、正常終了と異常終了がランダムに発生しているかのように見えますが、これはTCPのプロトコル仕様と、Fortigateのセッション管理(ステートフル・インスペクション)の挙動が深く関与しています。本記事では、パケットキャプチャとFortigateの内部処理の観点から、この挙動の正体に迫ります。
TCPセッション終了のメカニズムとFortigateの役割
まず前提として、TCPの終了処理には「正常終了(FIN)」と「強制終了(RST)」の2種類が存在します。
正常終了は、双方がFINパケットを交換し、お互いにデータ転送の終了を確認する「4ウェイハンドシェイク」で行われます。一方、RST(Reset)は、何らかの理由で通信が継続不可能と判断された場合、あるいはセッションの整合性が失われた場合に送信されます。
Fortigateはステートフル・ファイアウォールとして、通過するすべてのセッションをメモリ上のセッションテーブルで管理しています。このセッションテーブルには「タイムアウト値」や「ステート情報」が保持されており、Fortigateはパケットを中継するだけでなく、通信のライフサイクルそのものを監視しています。ログに記録される「close」と「rst」は、Fortigateがそのセッションをどのようにクローズしたか、あるいは通信の終端で何が起きたかを示しています。
ログにおけるcloseとrstの定義
Fortigateのトラフィックログにおける「action=close」および「action=rst」は、以下のように解釈できます。
close:これは、TCPのFINパケットが正常に送受信され、Fortigateがセッションテーブルからエントリを正常に削除したことを意味します。つまり、アプリケーションレベルで通信が正しく完了したことを示します。
rst:これは、セッション中にRSTフラグが立ったパケットが観測されたか、あるいはFortigate側から強制的にセッションを切断したことを意味します。ここが運用の悩みの種となりやすいポイントです。
なぜログが混在するのか:パケットレベルの分析
ログが混在する主な理由は、ネットワーク環境における非対称ルーティング、タイムアウト設定の不一致、そして「Fortigateがセッションを監視しているから」という点に集約されます。
1. クライアント/サーバのタイムアウト不一致
多くの場合、Webブラウザやアプリケーションは独自のタイムアウト値を持っています。例えば、サーバ側が通信を終了させたにもかかわらず、クライアント側がそれを認識できずに古いセッションを保持し続け、後からパケットを送信した場合、Fortigateは「既に終了したセッションに対する未知のパケット」と判断し、RSTを返します。
2. 非対称ルーティングによるFINパケットの欠落
Fortigateを通過する経路において、往路と復路が異なる場合、FINパケットがFortigateを通過せず、片側の通信のみが記録されることがあります。Fortigateはセッションの終了を検知できず、セッションタイムアウトまで待機します。この際、片側からFINが来ても、もう片方が応答しないため、最終的にセッションがタイムアウトする直前にRSTが投げられるケースがあります。
3. セッションのエイジングアウト
Fortigateのセッションタイムアウト値がアプリケーションのキープアライブ間隔よりも短い場合、Fortigateは「通信が途絶えた」と判断し、セッションテーブルからエントリを削除します。この時、Fortigateは通信している両端に対してRSTを送信し、強制的にセッションを終了させます。
パケットキャプチャによる検証サンプル
FortigateのCLIから、特定のセッションをパケットキャプチャして分析する手法を紹介します。
# 特定のIPアドレスに対する通信をキャプチャする(CLIコマンド)
diagnose sniffer packet any "host 192.168.1.10 and port 80" 4 0 l
# 出力結果の解釈例
# 10:00:01.123456 port1 in 192.168.1.10.50000 -> 10.0.0.1.80: fin 1
# 10:00:01.123500 port2 out 192.168.1.10.50000 -> 10.0.0.1.80: fin 1
# 10:00:01.124000 port2 in 10.0.0.1.80 -> 192.168.1.10.50000: fin 1
# 10:00:01.124100 port1 out 10.0.0.1.80 -> 192.168.1.10.50000: fin 1
# 上記は正常な「close」ログを出力するパターン。
# 一方、RSTが混在する場合のパケット
# 10:00:05.000000 port1 in 192.168.1.10.50001 -> 10.0.0.1.80: push 1
# 10:00:05.000100 port2 out 10.0.0.1.80 -> 192.168.1.10.50001: rst 1
# これは、既に終了したセッションに対してデータが送られたか、
# ファイアウォールがタイムアウトで切断したことを示唆する。
実務アドバイス:トラブルシューティングの勘所
現場で「rstが多い」というアラートが上がった場合、即座に「攻撃」や「異常」と断定するのは危険です。以下の手順で切り分けを行ってください。
1. ログの相関分析
RSTが発生している際の通信相手を確認してください。特定のクライアントや特定のサーバに集中している場合、そのエンドポイントのネットワークスタック設定や、アプリケーションのタイムアウト設定が原因である可能性が高いです。
2. セッションタイムアウトの確認
Fortigateの `config system session-ttl` を確認し、アプリケーションのキープアライブ間隔と比較してください。TCPのデフォルトタイムアウトは3600秒ですが、短すぎる場合は通信が強制切断される原因となります。
3. TCP RSTの発生源を特定
Fortigateが出しているRSTなのか、エンドポイントが出しているRSTなのかを見極める必要があります。Fortigateが生成したRSTには、IPヘッダのTTL値や特定のTCPオプションが付与されるため、キャプチャデータで送信元MACアドレスを突き合わせれば、誰がRSTを投げたのかが明確になります。
4. 非対称ルーティングの排除
ネットワーク構成図を確認し、パケットが往復で同じインターフェースを通っているかを確認してください。特に冗長構成やマルチホーム環境では、非対称ルーティングが「セッション状態の不整合」を引き起こし、RSTを誘発する最大の要因となります。
まとめ
Fortigateのログにおいて「close」と「rst」が混在するのは、必ずしもネットワーク障害を意味するわけではありません。むしろ、TCPの正常な終了処理と、ファイアウォールとしてのステートフル・インスペクションによる「セッション管理の厳格さ」が共存している証拠です。
エンジニアとして重要なのは、ログ上の「rst」という文字列に惑わされるのではなく、その背後にあるパケットのやり取りを可視化することです。今回紹介したCLIでのパケットキャプチャや、セッションテーブルの確認手法を駆使することで、単なる「通信の終了」なのか「予期せぬ切断」なのかを正確に判別できるようになります。
ネットワークの健全性は、こうした細かいログの「意味」を深く理解し、積み重ねることで維持されます。RSTログが多発している場合は、まずエンドポイントの挙動と、ネットワーク経路の対称性を疑うことから始めてみてください。それが、トラブルシューティングを迅速かつ的確に進めるための最短ルートです。

コメント