SJ blog
architecture
A

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

セキュリティグループ vs ネットワークACL — ステートフル/ステートレスの本質

VPCのセキュリティグループとネットワークACLの根本的な違い(ステートフルvsステートレス)、評価順序、インバウンド/アウトバウンドルールの書き方、設計パターンを解説。

一言結論

セキュリティグループはステートフルで応答トラフィックの戻りルールが不要なのに対し、NACLはステートレスのためエフェメラルポートを両方向で許可する必要があり、特定IPを明示的にブロックしたい場合のみNACLのDenyルールを追加するというのが実運用の設計パターンだ。

根本的な違い:ステートフル vs ステートレス

セキュリティグループとNACLの最大の違いは「接続状態を追跡するかどうか」だ。

特徴セキュリティグループネットワークACL
適用レイヤーインスタンス(ENI)単位サブネット単位
状態追跡ステートフルステートレス
デフォルト動作全拒否(Allowのみ記述)全許可(Allow/Deny両方記述)
ルールの優先度なし(全ルールを評価)番号順(低い番号が優先)
Denyルール書けない書ける

ステートフル(セキュリティグループ)

ステートフルとは「インバウンドを許可したら、その応答のアウトバウンドは自動的に許可される」ことを意味する。

EC2インスタンスにHTTPS(443)インバウンドを許可すると:
  インバウンド: クライアント → EC2 (ポート443) ← 許可ルールが必要
  アウトバウンド: EC2 → クライアント (エフェメラルポート) ← 自動許可(ルール不要)
セキュリティグループの設定例(Webサーバー):
インバウンドルール:
  HTTP  80  0.0.0.0/0  ← 許可
  HTTPS 443 0.0.0.0/0  ← 許可
  SSH   22  10.0.0.0/8 ← 社内のみ許可

アウトバウンドルール:
  ALL  ALL  0.0.0.0/0  ← デフォルトのAll Allow(通常そのまま)
  ※ インバウンド許可の応答は自動許可なのでアウトバウンドの明示設定は
    「EC2が外に出るトラフィック(DBへの接続など)」のためのもの

ステートレス(ネットワークACL)

ステートレスは「リクエストと応答を別々に評価する」。両方向のルールを明示的に書く必要がある。

NACL設定例(Webサーバーサブネット):
インバウンドルール:
  100  TCP  80   0.0.0.0/0  ALLOW  ← HTTP
  110  TCP  443  0.0.0.0/0  ALLOW  ← HTTPS
  120  TCP  1024-65535 0.0.0.0/0 ALLOW ← 戻りトラフィック用エフェメラルポート
  *    ALL  ALL  0.0.0.0/0  DENY   ← デフォルト拒否

アウトバウンドルール:
  100  TCP  80   0.0.0.0/0  ALLOW  ← HTTP応答(エフェメラルポートから)
  110  TCP  443  0.0.0.0/0  ALLOW  ← HTTPS応答
  120  TCP  1024-65535 0.0.0.0/0 ALLOW ← クライアントへの応答
  *    ALL  ALL  0.0.0.0/0  DENY   ← デフォルト拒否

エフェメラルポート(1024-65535)をNACLで開けないと、Webサーバーへのアクセスが通らない。

NACLのルール番号の評価順序

NACLはルール番号の小さい順に評価し、最初にマッチしたルールが適用される。

例(ブラックリスト方式):
  Rule 100: 203.0.113.50/32 → DENY
  Rule 200: 0.0.0.0/0      → ALLOW
  Rule *:   0.0.0.0/0      → DENY(デフォルト)

→ 203.0.113.50からのアクセス: Rule100でDENY
→ それ以外: Rule200でALLOW

ルール番号は10または100刻みで設定することで、後から追加しやすくなる。

特定IPを拒否する場合の違い

セキュリティグループ:
  Denyルールを書けない
  → 特定IPを許可しないことはできるが、「このIPは絶対Deny」は設定不可

ネットワークACL:
  Denyルールが書ける
  → 特定IPを明示的にブロックできる
  → DDoS対策やIPブラックリストの実装に使える

セキュリティグループの参照

セキュリティグループはIPアドレスの代わりに別のセキュリティグループを参照できる。

例: AppサーバーのSGからDBのSGに対してMySQLを許可

DBサーバーのセキュリティグループ:
  インバウンド: TCP 3306 sg-app-servers(AppサーバーのSG ID)← Allow

→ AppサーバーSGが付いているインスタンスからのみMySQLアクセスを許可
→ IPアドレスが変わっても自動的に適用される
→ オートスケーリングのインスタンスにも自動対応

多層防御の設計

インターネット → NACL(サブネット境界) → セキュリティグループ(インスタンス境界)

パブリックサブネットNACL:
  - DDoS対策の悪意のあるIPをDeny
  - HTTP/HTTPSをAllow

Webサーバーのセキュリティグループ:
  - HTTP/HTTPSのみAllow

プライベートサブネットNACL:
  - パブリックサブネットのCIDRからのみHTTPS許可
  - それ以外はDeny

APIサーバーのセキュリティグループ:
  - WebサーバーのSGからのみAllow

試験頻出ポイント

シナリオ回答
特定IPを完全ブロックしたいNACL(SGではDeny書けない)
オートスケーリングのインスタンスへの自動適用SGのSG参照機能を使う
NACLでHTTPを許可したが応答が返らないエフェメラルポートのインバウンドAllow漏れ
SGの変更はいつ反映される即時反映(接続中のセッションを含む)
1つのENIに付けられるSGの数最大5つ(デフォルト、引き上げ可能)

まとめ

セキュリティグループはステートフルで使いやすく、NACLはステートレスで追加の設定が必要だが「Deny」が書ける。実運用ではSGを主体にし、NACLはサブネット境界のIPブラックリストや規制要件対応で補完的に使うパターンが多い。