【入門編】 ネットワークACL(NACL)のステートレス処理とエフェメラルポート許可の落とし穴 – クラウド&コンテナネットワーク実践ガイド

ネットワークの「門番」にご用心!NACLのステートレスとエフェメラルポートの深い話

こんにちは!クラウドアーキテクト兼SREの視点から、日々クラウドの深淵を覗いている筆者です。

AWSやGCPといったクラウドの設計をしていると、必ず出会うのが「セキュリティ」と「ネットワーク」の境界線です。特に「セキュリティグループ(ファイアウォール)」と「ネットワークACL(NACL)」の使い分け、皆さんは迷ったことはありませんか?

今回は、多くのエンジニアが一度は頭を抱える「NACLのステートレス処理」と「エフェメラルポート」という、ネットワーク設計の落とし穴について、身近な例えを交えながら解説していきます。

—

1. 「門番」の働き方:ステートフル vs ステートレス

まず、クラウドにおける2つの代表的な守護神を整理しましょう。

  • セキュリティグループ(ステートフル): とても優秀な秘書のような存在です。「さっき私が許可した通信の『返事』なら、たとえ誰からの通信でも自動的に通してあげよう!」と、通信の流れを記憶しています。
  • ネットワークACL(ステートレス): 厳格な門番です。「さっき通した通信かどうか?そんなことは知らん!今、目の前にいるパケットが許可リストにあるかだけが全てだ!」と、一つひとつのパケットを毎回ゼロベースでチェックします。

NACLが「ステートレス」であるということは、「行き」の通信だけでなく「帰り(応答)」の通信も、わざわざ個別に許可してあげないと、門前払いを食らってしまうということを意味します。

—

2. 「エフェメラルポート」って何者?

WebブラウザからWebサイトを見るとき、皆さんのPCは適当な空き番号を一時的に借りて通信を行います。これをエフェメラルポート(Ephemeral Port)と呼びます。

郵便配達に例えてみましょう。

1. あなた(クライアント): 宛先(サーバー)のポート 80(手紙の届け先)に手紙を出します。
2. あなた: 自分の差出人住所に「返信は適当な空き番号(例:49152番)に送ってね」と書き添えます。
3. サーバー: 手紙を受け取り、処理を終えたら「はい、返事だよ」と、あなたの書いた 49152 番へ返信を送ります。

この 49152 のような番号は、OSがその時々で勝手に割り振るため、固定されていません。一般的には 1024 から 65535 の範囲が使われます。

NACLの設定で「Webサイトへのアクセスを許可したい!」と思ったら、往路(80番への送信)だけでなく、復路(1024-65535番への返信)も許可してあげないと、返事が届かずサイトが表示されないという悲劇が起きるのです。

—

3. 実践!NACLの正しい設定

それでは、AWSのNACLを例に、実際にどのようなルールが必要か見ていきましょう。

アウトバウンド(送信)ルールの考え方

サーバーが外部(インターネットや他のサブネット)と通信する場合、このような設定が必要です。

| ルール番号 | タイプ | プロトコル | ポート範囲 | 許可/拒否 | 説明 |
| :— | :— | :— | :— | :— | :— |
| 100 | HTTP | TCP | 80 | 許可 | 外へのリクエスト送信 |
| 110 | カスタムTCP | TCP | 1024-65535 | 許可 | 返信を受け取るための門を開ける |

もし 110 のルールを忘れると、通信は出て行けたとしても、戻ってきたパケットが「お前なんて許可リストにない!」とNACLでドロップされてしまいます。

Terraformでの設定例

インフラ構成をコード化する際も、この考え方は同じです。

# アウトバウンドルールの定義
resource "aws_network_acl_rule" "outbound_http" {
  network_acl_id = aws_network_acl.main.id
  rule_number    = 100
  egress         = true      # アウトバウンド(外向き)
  protocol       = "tcp"
  rule_action    = "allow"
  cidr_block     = "0.0.0.0/0"
  from_port      = 80
  to_port        = 80
}

# 応答通信を受け入れるためのエフェメラルポート許可
resource "aws_network_acl_rule" "outbound_ephemeral" {
  network_acl_id = aws_network_acl.main.id
  rule_number    = 110
  egress         = true      # アウトバウンド
  protocol       = "tcp"
  rule_action    = "allow"
  cidr_block     = "0.0.0.0/0"
  from_port      = 1024      # エフェメラルポートの開始
  to_port        = 65535     # エフェメラルポートの終了
}

—

4. なぜこんな面倒なことをするのか?

「セキュリティグループだけでいいのでは?」と思ったあなた、鋭いです!その通り、多くのケースではセキュリティグループだけで十分です。

しかし、NACLはサブネット全体を覆う最後の砦です。万が一、セキュリティグループの設定を誤って「全公開(0.0.0.0/0)」にしてしまったとしても、NACLで「このネットワークはそもそもWeb以外通さない!」とガチガチに固めておけば、被害を最小限に抑えることができます。

いわば、「セキュリティグループは個室のドア」、「NACLは建物の入り口にある厳しい警備員」。二重にガードすることで、私たちのクラウド環境は安全に守られているのです。

—

まとめ:一歩ずつ理解を深めよう

今回のおさらいです。

  • NACLはステートレス(過去の通信を忘れる)。
  • 通信の返事を受け取るためには、エフェメラルポート(1024-65535)を許可する必要がある。
  • 面倒に感じるけれど、これは多層防御のための大切な「二重の鍵」である。

ネットワークの世界は、最初はパケットの行方に迷うことが多いかもしれません。でも、一つひとつ「郵便配達」に例えて考えていけば、必ず仕組みが見えてきます。

もし本番環境で「通信が繋がらない!」と焦ったら、まずは「NACLの復路ルール」を疑ってみてくださいね。それがプロへの第一歩です。

それでは、また次の記事でお会いしましょう!

コメント

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