Network ACLとセキュリティグループの違いと使い分け：実務で活用するAWSネットワークセキュリティ

## 概要

AWSクラウドでのネットワークセキュリティは多層防御が基本です。その中核となるのがNetwork ACLとセキュリティグループという2つの仕組みですが、実務では後者の活用が中心になっています。この記事では、両者の違いを詳細に比較し、なぜセキュリティグループが主に使われるのか、また状況に応じた効果的な使い分け方を解説します。AWS環境でのセキュリティ設計を考える際に役立つ実践的な知識と設計パターンを提供します。

## 想定読者

- AWSを使い始めたばかりのエンジニア
- AWSでセキュリティ設計を行う必要があるアーキテクト
- Network ACLとセキュリティグループの違いを明確に理解したい方
- 実務に即したAWSネットワークセキュリティの実装方法を知りたい方

前提知識として、VPC、サブネット、EC2インスタンスなどのAWSの基本的なネットワーク構成要素についての理解があると理解しやすいでしょう。

## 目次

1. [はじめに](#はじめに)
2. [Network ACLとセキュリティグループの基本](#Network-ACLとセキュリティグループの基本)
3. [技術的な違いを比較する](#技術的な違いを比較する)
4. [なぜセキュリティグループが実務で多用されるのか](#なぜセキュリティグループが実務で多用されるのか)
5. [効果的な使い分けのシナリオ](#効果的な使い分けのシナリオ)
6. [セキュリティグループを中心とした設計パターン](#セキュリティグループを中心とした設計パターン)
7. [実装例と設定のベストプラクティス](#実装例と設定のベストプラクティス)
8. [トラブルシューティングとよくある問題](#トラブルシューティングとよくある問題)
9. [まとめと次のステップ](#まとめと次のステップ)

## はじめに

クラウド環境のセキュリティ設計において、ネットワークレベルでの防御は最も基本的かつ重要な要素です。AWSでは、この役割を担うのがNetwork ACL（以下、NACL）とセキュリティグループ（以下、SG）という2つの機能です。

AWSの公式ドキュメント[1]によると、これらは「異なるレベルでネットワークトラフィックをフィルタリングするファイアウォール」として位置づけられています。多くのユーザーがこれらを混同したり、違いを十分に理解せずに使っていたりする場合があります。

興味深いことに、実務環境では多くの場合、NACLはデフォルト設定のまま使われ、実質的なトラフィック制御はSGで行われています。これは単なる習慣ではなく、それぞれの特性を踏まえた実践的な選択です。

本記事では、NACLとSGの基本的な違いから始め、なぜSGが実務で好まれるのか、そして本当に効果的な使い分け方について、実例を交えて解説します。

## Network ACLとセキュリティグループの基本

まずは、NACLとSGの基本的な定義と機能について押さえておきましょう。

### Network ACLとは

Network ACL（NACL）は、**サブネットレベル**で動作するネットワークフィルターです。AWSの公式ドキュメント[2]によると、NACLは「サブネットとの間のトラフィックを制御するファイアウォールとして機能する、オプションのセキュリティレイヤー」と定義されています。

NACLの重要な特徴として、**ステートレス**であることが挙げられます。これは、インバウンドとアウトバウンドのトラフィックを個別に評価し、それぞれに対応するルールを明示的に設定する必要があることを意味します。

### セキュリティグループとは

一方、セキュリティグループ（SG）は、**インスタンスレベル**で動作するネットワークフィルターです。AWSの公式ドキュメント[3]によれば、「インスタンスへのインバウンドおよびアウトバウンドトラフィックを制御する仮想ファイアウォール」とされています。

SGの特徴として最も重要なのは、**ステートフル**であることです。これは、許可されたインバウンドトラフィックがレスポンスとして戻ることを自動的に許可するという意味です。そのため、戻りトラフィックに対して明示的なルールを設定する必要がありません。

### トラフィックフローにおける両者の関係

VPC内のトラフィックフローを考えると、その制御には次の順序でNACLとSGが関わります：

1. インバウンドトラフィック：NACL（サブネットレベル）→ SG（インスタンスレベル）
2. アウトバウンドトラフィック：SG（インスタンスレベル）→ NACL（サブネットレベル）

この順序は、セキュリティにおいて「多層防御」の概念を実現しています。

## 技術的な違いを比較する

NACLとSGの主な違いを表にまとめると以下のようになります：

| 特性 | Network ACL | セキュリティグループ |
|------|------------|-----------------|
| 適用レベル | サブネット | EC2インスタンス、ENI |
| ステート性 | ステートレス | ステートフル |
| ルールタイプ | 許可と拒否 | 許可のみ |
| ルール評価 | 番号順（低い番号が優先） | すべてのルールを評価 |
| デフォルト設定 | すべてのトラフィックを許可 | すべてのインバウンドを拒否、すべてのアウトバウンドを許可 |
| 関連付け | 各サブネットに1つのNACL | インスタンスに複数のSG可能 |

### スコープと適用レベル

NACLはサブネット全体に適用されるため、そのサブネット内のすべてのリソースに影響します。一方、SGはEC2インスタンスやELB、RDSなどの特定のリソースに直接関連付けられます。

これはアパートの建物全体のセキュリティシステム（NACL）と、各住戸の入口にある鍵やインターフォン（SG）の違いに例えることができるでしょう。

### ステートフルvsステートレス

SGがステートフルであるというのは、実践的には大きなメリットです。例えば、Webサーバーへの80番ポートへのアクセスを許可すると、クライアントからのリクエストに対するレスポンスは自動的に許可されます。

一方、NACLはステートレスなので、次のように明示的に両方向のルールを設定する必要があります：

```
インバウンドルール: 80番ポートへのトラフィックを許可（TCP）
アウトバウンドルール: エフェメラルポート（クライアント側が一時的に使用するポート番号，通常は1024-65535）へのレスポンストラフィックを許可
```

エフェメラルポートの範囲はオペレーティングシステムによって異なるため、NACLでの設定が複雑になることがあります。

### ルール評価と優先順位

NACLのルールには番号（1-32766）があり、低い番号から順に適用されます。最初にマッチしたルールが採用され、それ以降のルールは評価されません。これは「first match」として知られるルール評価方式です。デフォルトでは、ルールは100番から始まり、その後のルールは10もしくは100刻みで設定するのが、推奨されています。このように設定することで、今後ルールを追加する必要になった際に役立ちます。というのも「first match」の評価方式から番号順に評価するため、番号間に余裕があると後の追加が楽なんですよね。

一方、SGではすべてのルールが評価されます。どのルールにもマッチしなければ、トラフィックはデフォルトで拒否されます。また、SGは許可のルールのみを設定できるホワイトリスト形式です。SGは、拒否のルールを明示的に設定できません。

### デフォルト設定の違い

デフォルトのNACLはすべてのインバウンドとアウトバウンドのトラフィックを許可します。対照的に、デフォルトのSGはすべてのインバウンドトラフィックを拒否し、すべてのアウトバウンドトラフィックを許可します。

この違いは、AWSのセキュリティに対する「デフォルトで安全」という設計思想を反映しています。SGは「明示的に許可されない限り拒否」というセキュリティの基本原則に沿っています。

## なぜセキュリティグループが実務で多用されるのか

実務環境では、多くの場合NACLはデフォルト設定のままで、SGが主要なセキュリティ制御として使われています。この実践には複数の理由があります：

### 管理のしやすさと柔軟性

SGはリソースに直接関連付けられるため、アプリケーションの論理的なグループ化に合わせて設計できます。例えば：

- Web層のインスタンス群に「web-sg」
- アプリケーション層に「app-sg」
- データベース層に「db-sg」

このようにアプリケーションアーキテクチャに合わせたSGの設計ができます。

また、SGはリソースの作成と同時に関連付けることができるため、Infrastructure as Code（IaC）の実装と相性が良いです。

### ステートフル検査の利点

SGのステートフル特性は、管理の複雑さを大幅に軽減します。特に以下のような場合に効果的です：

- 動的なエフェメラルポートを使用する通信
- ALBやNLBなどのロードバランサーを介した通信
- 多様なクライアントとの通信が必要なアプリケーション

NACLでこれらを実現するには、追加のルール設定やメンテナンスが必要になります。

### リソースグループ化の容易さ

SGはタグ付けやグループ化と組み合わせることで、より柔軟なセキュリティポリシーを実現できます。例えば：

- 同じSGを参照する他のSGのルール（セキュリティグループの参照）
- SGをタグベースで動的に割り当てるオートメーション

AWSの公式ドキュメント[4]でも、「セキュリティグループは、インスタンスの役割を反映してグループ化する方法」として推奨されています。

### 監査とトレーサビリティの向上

SGはAWS Config、CloudTrailなどのサービスと連携することで、変更履歴や設定のコンプライアンスを容易に監査できます。このように変更管理や監査対応の視点からもSGは優れています。

## 効果的な使い分けのシナリオ

状況に応じた効果的なNACLとSGの使い分けを見ていきましょう。

### セキュリティグループだけで十分なケース

多くの場合、以下のようなシナリオではSGのみで十分なセキュリティを確保できます：

- 単一のVPC内で完結するシステム
- マイクロサービスアーキテクチャ
- オートスケーリングを活用する動的なインフラ

例えば、典型的な3層アーキテクチャ（Web、App、DB）の場合、それぞれの層に適切なSGを設定するだけで、必要なセキュリティコントロールを実現できます。

```
web-sg：80/443ポートへの全インターネットからのアクセスを許可
app-sg：Webサーバーからの特定ポートへのアクセスのみ許可（web-sgからの通信）
db-sg：アプリケーションサーバーからの3306ポートへのアクセスのみ許可（app-sgからの通信）　注:3306ポートはMySQLプロトコルによって予約されているwell-knownポートの1つです。
```

### Network ACLが必要になるケース

以下のようなシナリオでは、NACLの追加が有効です：

1. **特定の攻撃パターンのブロック**：
   - 特定のIPアドレスやCIDRブロックからのすべてのトラフィックを拒否したい場合
   - レートリミットやDDoS対策の一部として使用する場合

2. **コンプライアンス要件**：
   - PCI DSSなどのコンプライアンス要件で多層防御が明示的に要求される場合
   - 明示的な「拒否」ルールが必要なセキュリティポリシーがある場合

3. **ネットワークレベルでの分離**：
   - サブネット間の通信を厳格に制限したい場合
   - トランジットゲートウェイやVPCピアリングを使用する複雑なネットワーク構成

### 多層防御の実践例

金融システムなど、高度なセキュリティが求められる環境では、NACLとSGを組み合わせた多層防御が効果的です。例えば：

1. **境界防御としてのNACL**：
   - パブリックサブネットのNACLで、既知の悪意あるIPからのトラフィックをブロック
   - SSH/RDPなどの管理ポートへの直接アクセスを許可するIPアドレス帯を制限

2. **詳細なアクセス制御としてのSG**：
   - アプリケーションレベルでの通信制御
   - リソース間の最小権限アクセスポリシーの実装

この組み合わせにより、「防御の深さ」というセキュリティの基本原則に従った堅牢な環境を構築できます。

## セキュリティグループを中心とした設計パターン

実務で効果的なSGを中心とした設計パターンをいくつか紹介します。

### 基本的なセキュリティグループ設計

最も基本的なアプローチは、アプリケーションの各コンポーネントに専用のSGを割り当てる方法です。以下は一般的な3層アーキテクチャの例です：

1. **ALB用セキュリティグループ（alb-sg）**
   - インバウンド：80/443ポートへのインターネットからのアクセスを許可（0.0.0.0/0）
   - アウトバウンド：Webサーバーポートへのアクセスのみ許可（web-sgへ）

2. **Webサーバー用セキュリティグループ（web-sg）**
   - インバウンド：ALBからの特定ポートへのアクセスのみ許可（alb-sgから）
   - アウトバウンド：アプリケーションサーバーへのアクセス（app-sgへ）

3. **アプリケーションサーバー用セキュリティグループ（app-sg）**
   - インバウンド：Webサーバーからの特定ポートへのアクセスのみ許可（web-sgから）
   - アウトバウンド：データベースサーバーへのアクセス（db-sgへ）

4. **データベース用セキュリティグループ（db-sg）**
   - インバウンド：アプリケーションサーバーからの特定ポートへのアクセスのみ許可（app-sgから）
   - アウトバウンド：必要最小限のアウトバウンド通信のみ許可

この設計では、各レイヤーが上位レイヤーからの接続のみを受け入れる形になっており、最小権限の原則に従っています。

### ロール別のセキュリティグループ設計

より高度な設計として、機能やロールごとにSGを分離する方法があります：

1. **ベースインフラSG（base-sg）**
   - すべてのインスタンスに適用される基本的なルール
   - 例：監視システムからのヘルスチェック、管理用SSHアクセスなど

2. **機能別SG（function-sg）**
   - 特定の機能を提供するコンポーネント用
   - 例：web-sg、app-sg、db-sg、cache-sgなど

3. **環境別SG（env-sg）**
   - 開発、テスト、本番などの環境ごとに追加ルール
   - 例：dev-sgは広めのアクセス許可、prod-sgは厳格なアクセス制限

EC2インスタンスには、これらの複数のSGを組み合わせて適用することで、きめ細かいセキュリティ制御を実現します。

### マイクロサービスでのセキュリティグループ活用

マイクロサービスアーキテクチャでは、サービスごとにSGを定義する設計が有効です：

1. **サービス専用SG**
   - 各マイクロサービスに固有のSG
   - サービス間の依存関係を明示的に定義

2. **共通インフラSG**
   - ロードバランサー、サービスディスカバリなどの共通コンポーネント用
   - すべてのサービスと通信可能な設定

この設計により、サービス間の通信フローが明確化され、セキュリティの可視性が向上します。また、新しいサービスの追加や既存サービスの変更にも柔軟に対応できます。

## 実装例と設定のベストプラクティス

SGを効果的に実装するための具体的な例とベストプラクティスを紹介します。

### セキュリティグループの効果的な設定方法

SGを設定する際の重要なポイントを以下に示します：

1. **最小権限の原則に従う**
   - 必要なポートとプロトコルのみを許可
   - ソースを可能な限り制限（0.0.0.0/0を使わない）
   - SGの相互参照を活用（CIDRブロックではなくSG ID）

2. **命名規則を統一する**
   - 目的が明確な名前（例：web-alb-sg、app-server-sg）
   - タグを活用した分類（Name、Environment、Purposeなど）

3. **説明を詳細に記述する**
   - ルールの目的
   - 承認者や変更理由（可能であれば）

4. **変更管理プロセスを確立する**
   - 変更履歴の記録（CloudTrail、AWS Configなど）
   - IaCツールを使用した設定管理

### CloudFormationでの実装例

3層アーキテクチャのSGをCloudFormationで実装する例を示します：

```yaml
Resources:
  ALBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for ALB
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: alb-sg

  WebSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for Web servers
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          SourceSecurityGroupId: !Ref ALBSecurityGroup
      Tags:
        - Key: Name
          Value: web-sg

  AppSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for App servers
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 8080
          ToPort: 8080
          SourceSecurityGroupId: !Ref WebSecurityGroup
      Tags:
        - Key: Name
          Value: app-sg

  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security group for Database servers
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 3306
          ToPort: 3306
          SourceSecurityGroupId: !Ref AppSecurityGroup
      Tags:
        - Key: Name
          Value: db-sg
```

### 一般的なアンチパターンと回避方法

実務でよく見られるSGの設定ミスと、その回避方法を紹介します：

1. **過度に緩いルール**
   - 問題：0.0.0.0/0 からのSSHアクセスを許可
   - 解決策：特定のIPまたはCIDRブロックのみにSSHアクセスを制限
   
2. **不必要なポートの開放**
   - 問題：使用していないサービスのポートが開放されている
   - 解決策：定期的なセキュリティグループの監査と未使用ポートの閉鎖

3. **運用上の便宜のための一時的な緩和**
   - 問題：トラブルシューティングのために一時的に緩めたルールが元に戻されない
   - 解決策：変更管理プロセスの導入と自動チェック

4. **説明不足のルール**
   - 問題：ルールの目的や理由が記録されていない
   - 解決策：すべてのルールに詳細な説明を追加

5. **過度に複雑なSGの連鎖**
   - 問題：多数のSGが相互参照して複雑になりすぎている
   - 解決策：SGの階層を整理し、不要な参照を排除

## トラブルシューティングとよくある問題

SG関連のトラブルシューティング手法をいくつか紹介します。

### 接続問題の原因特定

接続問題が発生した場合の切り分け手順：

1. **基本的な確認事項**
   - インスタンスのステータス確認
   - ネットワークインターフェイスの状態確認
   - ルートテーブルの確認

2. **SG設定の確認**
   - インバウンドルールの確認（ポート、プロトコル、ソース）
   - アウトバウンドルールの確認（必要に応じて）
   - 複数SGが適用されている場合はすべてを確認

3. **ツールを使った診断**
   - VPCフローログの分析
   - `nc`（netcat）や`telnet`を使用した接続テスト
   - EC2インスタンス上のパケットキャプチャ

4. **AWS提供のリソースの活用**
   - Reachabilityアナライザー
   - VPC Network Access Analyzer

### ルールの競合解決

SGのルール間で期待通りの動作にならない場合の対処法：

1. **SGの評価ロジックの理解**
   - SGはデフォルトで「暗黙的な拒否」
   - 明示的な許可があればトラフィックは許可される
   - どのルールもマッチしなければトラフィックは拒否される

2. **一般的な競合パターン**
   - 複数のSGが適用され、一部のSGでポートが開放されていない
   - SG間の参照が正しく設定されていない
   - エフェメラルポートの範囲に関する問題

3. **対処手順**
   - 最も制限の強いSGから確認
   - すべての関連SGを一覧化して分析
   - 問題のトラフィックパターンを明確にする

## まとめと次のステップ

### 要点のまとめ

- **NACLとSGの主な違い**
  - NACLはサブネットレベル（ステートレス）、SGはインスタンスレベル（ステートフル）
  - NACLは許可と拒否のルールを持つが、SGは許可のみ
  - SGは実務で広く使われる理由があり、多くの場合十分なセキュリティを提供できる

- **SGを中心とした設計のメリット**
  - 管理のしやすさと柔軟性
  - アプリケーションアーキテクチャとの親和性
  - Infrastructure as Codeとの相性

- **効果的な使い分け**
  - 基本はSGでアクセス制御
  - 特定のシナリオではNACLも組み合わせて多層防御を実現
  - 最小権限の原則に従い、細かく設計する

- **ベストプラクティス**
  - 常に最小権限の原則に従う
  - IaCを活用した一貫した管理
  - 定期的な監査と更新

### より深く学ぶためのリソース

AWS VPCのセキュリティについてさらに学ぶには、以下のリソースが役立ちます：

- [AWSセキュリティベストプラクティス](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/welcome.html)
- [AWS Well-Architectedフレームワーク](https://aws.amazon.com/architecture/well-architected/)
- [AWS VPCネットワーキングワークショップ](https://networking.workshop.aws/)

NACLとSGを適切に組み合わせることで、クラウド環境のセキュリティを強化できます。まずはSGを中心とした設計を確立し、必要に応じてNACLによる追加のセキュリティレイヤーを検討することをお勧めします。

## 参考文献・参考サイト

[1] https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Security.html
[2] https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html
[3] https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html
[4] https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-best-practices.html
[5] https://aws.amazon.com/blogs/networking-and-content-delivery/vpc-security-capabilities-you-should-know-about/
[6] https://aws.amazon.com/blogs/security/how-to-filter-network-access-to-s3-buckets-using-vpc-endpoints/