【入門編】 セキュリティグループ(SG)とNACLの組み合わせにおけるステートフル・ステートレスの二重防御 – クラウド&コンテナネットワーク実践ガイド

こんにちは!メガクラウドのネットワークの迷宮へようこそ。第一線でSRE(サイト信頼性エンジニア)として日々パケットの行方を見守っている、技術メディア主筆の「おんちゃん」です。

AWSやGCPといったクラウドの世界に一歩足を踏み入れると、誰もが一度は「セキュリティグループ(SG)」と「ネットワークACL(NACL)」という2つの壁にぶつかります。

「どっちもアクセスを制限する仕組みでしょ? なんで2つもあるの?」
「設定したはずなのに、パケットが帰ってこない…!」

そんな風に頭を抱えた経験はありませんか?
安心してください。この記事を読み終える頃には、パケットがクラウドの中をどのように走り抜け、この2つの関門をどうくぐり抜けているのかが、手に取るようにイメージできるようになります。

一歩ずつ、楽しみながら紐解いていきましょう!

—

1. マンションで例える「SG」と「NACL」の超基本

まずは、小難しいネットワークの専門用語を一度忘れて、私たちが住む「セキュリティ付きマンション」を思い浮かべてみてください。

クラウドにおける仮想ネットワーク(VPC)は、大きな「マンションの敷地」です。そして、その中に配置される仮想サーバー(EC2インスタンスなど)は、個々の「お部屋」にあたります。

このマンションには、二重のセキュリティゲートが存在します。

【マンションの外】
       │
       ▼
 ┌──────────────┐
 │  エントランス  │ ── NACL(ネットワークACL)の関門
 └──────────────┘
       │
       ▼
 ┌──────────────┐
 │   各部屋のドア │ ── セキュリティグループ(SG)の関門
 └──────────────┘
       │
       ▼
 【 インスタンス 】(あなたのお部屋)

NACLは「エントランスの厳格な門番」

NACL(Network Access Control List)は、サブネットという「マンションのフロア(または建物全体)の入り口」に立つ門番です。
ここを通るすべてのパケットを、1列に並ばせてルールブック(名簿)通りにチェックします。

セキュリティグループ(SG)は「お部屋の専属ボディーガード」

SG(Security Group)は、仮想サーバー(インスタンス)という「お部屋のドアの直前」で守ってくれる、あなた専用の優秀なボディーガードです。

—

2. 「ステートフル」と「ステートレス」ってどういうこと?

ここからが、今回の主役である「ステートフル(SG)」と「ステートレス(NACL)」の最大の違いです。この「ステート」とは、英語で「状態」や「文脈」を意味します。

分かりやすく「会話(手紙のやり取り)」に例えてみましょう。

セキュリティグループ(SG)は「記憶力抜群のボディーガード(ステートフル)」

SGはステートフル(状態を保持する)です。

あなたが部屋の中から、外の友達に「今から郵便を出すね!」と手紙を送った(アウトバウンド)とします。
SGというボディーガードは、「主人が今、外に手紙を出したな」という出来事(コンテキスト)をしっかりと記憶しています。

そのため、その友達から返事の手紙(インバウンド)が届いたとき、SGは「あ、さっき主人が出した手紙の返事だな!」と判断し、返信用の特別な許可ルールがなくても、自動的にその手紙を通してくれます。

  • 特徴: 行き(または帰り)の片方だけ許可しておけば、その「往復のペア」となるパケットは自動的に通してくれる。

NACLは「記憶喪失の冷徹な門番(ステートレス)」

一方、NACLはステートレス(状態を保持しない)です。

この門番は、驚くほど記憶力がありません。1秒前の出来事すら忘れてしまいます。
あなたが外に手紙を出したことなんて、これっぽっちも覚えていません。

そのため、友達から返事の手紙がエントランスに届いたとき、門番(NACL)はこう言います。
「おい、この手紙を中に入れるルールは名簿(インバウンドルール)に書いてあるか? え? さっき主人が手紙を出した? 知らん。ルールに書いてなければ、容赦なくゴミ箱行きだ!」

  • 特徴: 「行き」と「帰り」のルールを、両方とも手動で明示的に書いておかなければ、パケットは絶対に通り抜けられない。

—

3. パケットが通る順番:インバウンドとアウトバウンド

ネットワークを流れるデータ(パケット)が、この2つの関門を通過する順番を整理しておきましょう。ここを勘違いしていると、トラブルシューティングで迷子になってしまいます。

① 外から中へ入る時(インバウンド)

インターネットや他のネットワークから、あなたのサーバーへアクセスが来る時の順番です。

1. まず「NACL(マンションのエントランス)」を通過する
2. 次に「SG(お部屋のドア)」を通過する
3. 無事にサーバー(インスタンス)へ到着!

② 中から外へ出る時(アウトバウンド)

あなたのサーバーが、外のサイトにデータを送ったり、アップデートファイルをダウンロードしに行ったりする時の順番です。

1. まず「SG(お部屋のドア)」を出発する
2. 次に「NACL(マンションのエントランス)」を通過する
3. 外の世界へ旅立つ!

—

4. 初学者が必ずハマる「エフェメラルポート」の罠

ここで、インフラエンジニアが人生で一度は必ず夜通し悩むことになる「エフェメラルポート(一時ポート)」の罠についてお話しします。

例えば、「自分のウェブサーバー(ポート 80)に、外からアクセスさせたい」という設定を考えてみましょう。

セキュリティグループ(SG)の設定(これだけでOK)

  • インバウンド: ポート 80 からのアクセスを「許可」
  • (アウトバウンドは、ステートフルなので自動で返してくれるから設定不要!)

NACL(ステートレス)の設定(これが必要!)

「エントランスの門番」であるNACLには、行きと帰りの両方を書かないといけません。

  • インバウンド: ポート 80 宛てのパケットを「許可」
  • アウトバウンド: ???

ここで「アウトバウンドもポート 80 を許可すればいいのかな?」と思ってしまいがちですが、これが大間違いなのです!

なぜポート「80」で返してはいけないのか?

郵便で考えてみましょう。
あなたがウェブサーバー(宛先ポート:80)に手紙を送る時、あなたのパソコン(送信元)は、空いている適当な引き出し(例えばポート 50213 のようなランダムな番号)から手紙を送り出します。

そして、ウェブサーバーから返事をもらう時は、「ポート 50213 宛てに返してね!」とお願いするのです。

この「一時的に使われる、帰りの宛先ポート」のことをエフェメラルポート(または一時ポート)と呼びます。OSの種類によって異なりますが、一般的には 32768 〜 61000(または 1024 〜 65535)という非常に広い範囲が使われます。

つまり、NACLで「帰りのパケット」を通すためには、アウトバウンドルールにこの「エフェメラルポートの範囲」からの送信を許可すると書いておく必要があるのです。これを忘れると、「サーバーまではパケットが届いているのに、返事が外に出ていけない」という謎の通信障害が発生します。

—

5. 実践!Terraformで構築する「二重の砦」

言葉だけでなく、実際のインフラコード(Terraform)を見てみましょう。
「Webサーバー(ポート 80)を安全に公開し、かつパケットが正しく往復する」ための、SGとNACLの正しい設定例です。

# =========================================================================
# 1. セキュリティグループ(SG)の設定
# ボディーガードは「ステートフル」なので、行きのルール(インバウンド)だけでOK!
# =========================================================================
resource "aws_security_group" "web_sg" {
  name        = "web-server-sg"
  description = "Allow inbound HTTP traffic"
  vpc_id      = aws_vpc.main.id

  # インバウンド(お部屋に入ってくるパケット)のルール
  ingress {
    description = "Allow HTTP from anywhere"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # インターネット全体からのアクセスを許可
  }

  # アウトバウンド(お部屋から出ていくパケット)のルール
  # ※基本的には全開放にしておき、ボディーガードの判断に任せます
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# =========================================================================
# 2. ネットワークACL(NACL)の設定
# 門番は「ステートレス」なので、行きと帰りのポートを両方明示する必要があります!
# =========================================================================
resource "aws_network_acl" "public_nacl" {
  vpc_id = aws_vpc.main.id

  # -------------------------------------------------------------------------
  # インバウンドルール(エントランスに入ってくるパケットのチェック)
  # -------------------------------------------------------------------------
  
  # ルール100: 外からウェブサーバー(ポート80)へのアクセスを許可
  ingress {
    protocol   = "tcp"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 80
    to_port    = 80
  }

  # ルール110: 外のサーバー(例: アップデートサーバー)から返ってくるパケットを許可
  # ※サーバー自身が外にアクセスした時の「帰り道」用(エフェメラルポート)
  ingress {
    protocol   = "tcp"
    rule_no    = 110
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 1024
    to_port    = 65535
  }

  # -------------------------------------------------------------------------
  # アウトバウンドルール(エントランスから出ていくパケットのチェック)
  # -------------------------------------------------------------------------

  # ルール100: ウェブサーバーが、クライアントへ「返事」を送るのを許可
  # ※クライアントの「エフェメラルポート」宛てに返すため、広い範囲を開けます
  egress {
    protocol   = "tcp"
    rule_no    = 100
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 1024
    to_port    = 65535
  }

  # ルール110: サーバー自身が外(インターネット)へリクエストを開始するのを許可(例: yum updateなど)
  egress {
    protocol   = "tcp"
    rule_no    = 110
    action     = "allow"
    cidr_block = "0.0.0.0/0"
    from_port  = 80
    to_port    = 80
  }
}

—

6. パケットが届かない時の「3大チェックリスト」

もし構築中に「通信が繋がらない!」となったら、焦らずに以下の順番でパケットの旅路を追いかけてみましょう。

📌 チェック1:SGとNACL、どちらで止まっているか?

「通信が届かない」のか「返事が返ってこない」のかを切り分けます。

  • 「Webページの読み込み中…」のままタイムアウトする場合:

パケットが途中で「破棄(Drop)」されています。NACLのインバウンド、またはSGのインバウンドで弾かれている可能性が大です。

  • 「接続が拒否されました(Connection Refused)」となる場合:

パケットはサーバーまで届いていますが、サーバー上のアプリケーション(NginxやApacheなど)が起動していないか、ポートの設定が違います。

📌 チェック2:NACLの「エフェメラルポート」は開いているか?

「サーバーのログにはアクセスが記録されているのに、ブラウザ側には何も表示されずにタイムアウトする」という場合、ほぼ100% NACLのアウトバウンドでエフェメラルポート(1024-65535)が閉じているのが原因です。門番が帰りのパケットを通せんぼしています。

📌 チェック3:NACLの「ルール番号(Rule Number)」の優先順位

NACLは、ルール番号が小さい順に上から評価され、最初にマッチしたルールが適用されます。
例えば、ルール 100 で「全員拒否(DENY)」と書いてある後ろに、ルール 200 で「ポート80を許可(ALLOW)」と書いても、ルール 100 でバッサリ落とされてしまいます。
設定を追加するときは、ルールの評価順序に注意しましょう!

—

7. まとめ:二重の盾をマスターしたあなたへ

最後に、今回学んだ超重要ポイントを振り返りましょう。

  • SG(セキュリティグループ)は、インスタンス単位のボディーガード。ステートフルなので、帰りのルートは自動で確保してくれる。
  • NACL(ネットワークACL)は、サブネット単位の門番。ステートレスなので、行き(インバウンド)と帰り(アウトバウンド)の両方のルールを自分で書く必要がある。
  • ステートレスなNACLを扱うときは、帰りの通り道であるエフェメラルポート(一時ポート)の許可を絶対に忘れないこと。

クラウドネットワークのセキュリティは、この「きめ細やかなSG」と「大枠をがっちり守るNACL」の二重防御(ディフェンス・イン・デプス)によって保たれています。

仕組みさえ分かってしまえば、もうパケットの迷子に怯える必要はありません。
一歩ずつ、確実なインフラを作っていきましょう。あなたのクラウドエンジニアとしての旅路を応援しています!

それでは、また次回の技術ブログでお会いしましょう!

コメント

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