Security Group はステートフル、NACL はステートレス - この違いが生まれた設計判断

Security Group が接続追跡でステートフルに動作する仕組み、NACL がステートレスである理由、エフェメラルポートの落とし穴、両者を組み合わせた多層防御の設計パターンを解説します。

ステートフルとステートレスの違い

Security Group はステートフルなファイアウォールです。インバウンドルールで許可されたリクエストに対するレスポンスは、アウトバウンドルールに関係なく自動的に許可されます。逆に、アウトバウンドルールで許可されたリクエストに対するレスポンスも、インバウンドルールに関係なく自動的に許可されます。NACL (Network Access Control List) はステートレスなファイアウォールです。インバウンドとアウトバウンドのルールが独立して評価されます。インバウンドで許可されたリクエストに対するレスポンスであっても、アウトバウンドルールで明示的に許可されていなければブロックされます。この違いは、接続の状態を追跡するかどうかの実装の違いによるものです。Security Group は接続追跡 (Connection Tracking) テーブルを維持しており、各接続の状態 (送信元 IP、送信先 IP、ポート、プロトコル) を記録しています。レスポンスパケットが到着すると、接続追跡テーブルと照合し、既存の接続に属するパケットであれば自動的に許可します。NACL は接続追跡テーブルを持たず、各パケットを独立して評価します。

なぜ 2 種類のファイアウォールが存在するのか

NACL を Security Group と併用する理由の 1 つは、多層防御 (Defense in Depth) です。Security Group はインスタンスレベル (ENI レベル) で動作し、NACL はサブネットレベルで動作します。この 2 つのレイヤーが異なるレベルで防御を提供します。Security Group が侵害された場合 (たとえば、IAM 権限を持つ攻撃者が Security Group のルールを変更した場合)、NACL がバックアップとして機能します。NACL はサブネット全体に適用されるため、個々のインスタンスの Security Group が変更されても、NACL のルールはサブネットの単位で適用されたままです。もう一つの理由は、明示的な Deny の必要性です。Security Group は許可ルールのみを定義でき、拒否ルールを定義できません。特定の IP アドレスからのアクセスを明示的にブロックしたい場合、Security Group では実現できません。NACL は許可ルールと拒否ルールの両方を定義でき、ルール番号の順序で評価されるため、特定の IP アドレスを明示的にブロックできます。

NACL のエフェメラルポートの落とし穴

NACL がステートレスであることに起因する設定ミスの 1 つは、エフェメラルポート (一時ポート) の許可漏れです。クライアントがサーバーに接続する際、クライアント側のソースポートはオペレーティングシステムが動的に割り当てるエフェメラルポートを使用します。Linux では 32768〜60999、Windows では 49152〜65535 の範囲です。NACL のアウトバウンドルールで HTTP (ポート 80) を許可しても、レスポンスはクライアントのエフェメラルポートに返されます。NACL のインバウンドルールでエフェメラルポートの範囲を許可していなければ、レスポンスがブロックされます。Security Group ではこの問題は発生しません。ステートフルであるため、アウトバウンドで許可されたリクエストに対するレスポンスは自動的に許可されます。NACL を使用する場合は、インバウンドとアウトバウンドの両方でエフェメラルポートの範囲 (1024〜65535) を許可する構成をとります。この広い範囲の許可に抵抗がある場合は、NACL ではなく Security Group で細かい制御を行い、NACL はサブネットレベルの粗い制御に留める方法があります。

Security Group の接続追跡の詳細

Security Group の接続追跡には、追跡される接続と追跡されない接続があります。TCP と UDP の通信では、すべてのトラフィック (0.0.0.0/0 または ::/0) を許可するルールがあり、逆方向にもすべてのポートの応答トラフィックを許可するルールがある場合、その通信は追跡されません (自動的に追跡される接続を除く)。追跡が不要なためです。接続追跡テーブルにはサイズの上限があります。追跡できる接続の最大数は、Amazon EC2 がインスタンスごとに定めています。上限に達すると、新しい接続を確立できないため、送受信されるパケットが破棄されます。大量の短命な接続を処理するワークロード (ロードバランサーの背後のインスタンスなど) では、追跡している接続の数を監視します。ネットワークパフォーマンスのメトリクス conntrack_allowance_exceeded で、追跡できる接続の上限を超えてパケットが破棄されたかを確かめられます。アイドル状態の接続追跡のタイムアウトの既定値は、UDP が 30 秒、UDP ストリームが 180 秒で、TCP の確立済み接続はインスタンスタイプによって異なります。タイムアウトした接続はテーブルから削除されます。

実践的な多層防御の設計パターン

Security Group と NACL を組み合わせた実践的な設計パターンを紹介します。パブリックサブネットの ALB には、Security Group でインバウンド HTTP/HTTPS (0.0.0.0/0) を許可し、NACL はデフォルト (すべて許可) のままにします。ALB は公開サービスのため、この構成では NACL で制限しません。プライベートサブネットのアプリケーションサーバーには、Security Group でインバウンドを ALB の Security Group からのみ許可し、NACL でインバウンドを ALB のサブネットの CIDR からのみ許可します。Security Group が ALB からのトラフィックのみを許可し、NACL がサブネットレベルでバックアップの防御を提供します。データベースサブネットには、Security Group でインバウンドをアプリケーションサーバーの Security Group からのみ許可し、NACL でインバウンドをアプリケーションサブネットの CIDR からのみ許可します。特定の IP アドレスからの攻撃を検知した場合は、NACL の拒否ルールでブロックできます。Security Group のルールを変えても追跡中の接続はすぐには切れませんが、NACL でトラフィックを止めると既存の接続も切れるため、緊急対応に使えます。

参考資料 (AWS 公式)

本ページの一次情報は AWS 公式サイトと公式ドキュメントです。最新の仕様と料金は次の公式ページで確認できます。

本ページと公式ドキュメントの記述が食い違う場合は、公式ドキュメントを正としてください。

共有する