🦁

【AWS】セキュリティグループとNACLの違いをカンタンに

に公開

はじめに

セキュリティグループとNACLは、VPC内のリソースのアクセス管理・セキュリティ管理で重要な概念ですが、機能が似ていてまだどっちがどっちなのか整理をつけられていないので、この際しっかり整理しようと思いました。

1. 適用単位

・セキュリティグループ(SG): リソース単位(EC2インスタンス、RDS、ELBなど個別のリソース)

VPC
 └─ サブネット (10.0.1.0/24)
     ├─ EC2-A (SG-Web)    ← port 80, 443許可
     ├─ EC2-B (SG-App)    ← port 8080許可
     └─ EC2-C (SG-DB)     ← port 3306許可
     ↑ それぞれ異なるSGを設定できる

・ネットワークACL:サブネット単位

VPC
 └─ サブネット (10.0.1.0/24)  ← NACLはここに適用
     ├─ EC2-A
     ├─ EC2-B
     └─ EC2-C
     ↑ 全部同じNACLルールが適用される

2. ステートフル or ステートレス

・セキュリティグループ:
ステートフル
行き(インバウンド)の通信を許可したら、帰り(アウトバウンドルール)の通信は自動で許可される)

セキュリティグループの設定:
  インバウンドルール:
    HTTP (port 80) from 0.0.0.0/0  ← これだけ設定

  アウトバウンドルール:
    (何も設定しなくてもOK)

これで、クライアント → EC2 (port 80) をインバウンドで許可しており、その応答であるEC2 → クライアントは、自動で許可されます(= ステートフル

・ネットワークACL
ステートレス
行きと帰りの両方を明示的に設定する必要がある

NACLの設定:
  インバウンドルール:
    HTTP (port 80) from 0.0.0.0/0        ← EC2の「ポート80」宛ての通信を許可。HTTPSへのリダイレクトとか
    HTTPS (443)   ←  EC2の「ポート443」宛ての通信を許可
    TCP (port 1024-65535) from 0.0.0.0/0 ← EC2の「ポート1024-65535」宛ての通信を許可

  アウトバウンドルール:
    TCP (port 1024-65535) to 0.0.0.0/0   ← クライアントのポート1024-65535宛て」の通信を許可
    HTTPS (port 443) to 0.0.0.0/0        ← EC2からの「インターネットのポート443宛て」の通信を許可

これにより、クライアント → EC2 (port 80) はインバウンドで許可され、応答であるEC2 → クライアント の方向も、アウトバウンドルールにより明示的に許可が必要したことにより通信可能です。

ここで、NACLでは応答用のエフェメラルポート(一時的なポート番号)(1024-65535)を必ず設定することが必要

(補足)同じアプリでも、接続ごとに異なるポート番号が割り当てられることで、その接続からの送信かがわかるようになる。それがポート番号の役割。macOS/Linuxでは、以下のコマンドでどのようなポートで今接続しているのかが確認できる

lsof -i -P | grep ESTABLISHED

注意:ステートフルのSGも、インバウンド、アウトバウンドそれぞれで何を許可するのかを設定する必要がある。


3. 新規作成時のデフォルト設定

・セキュリティグループ
インバウンド:すべて閉ざされている
アウトバウンド:開いている
このため、基本的に外部からはアクセスできないようになっており、安全な状態になっています。

・ネットワークACL
インバウンド:すべて通す
アウトバインド:すべて通す
SGで防御すればいいという考えのもと、基本的に邪魔をしないです。

考察① なぜ、SGのデフォルトのアウトバウンドルールは「全許可」なのか

もしデフォルトのアウトバウンドが全拒否だったら、
yum update、pip install、外部API、DBに接続(EC2 → RDS)、DNSクエリができず、EC2がほぼ使い物にならないためです。

そのため、NACLもデフォルトはインバウンドアウトバウンド両方とも全許可です。

考察② なぜ、NACLのデフォルトはINもOUTも「全許可」なのか

これは、基本的にSGで防御すればいいからだと思います。

基本的にSGもNACLも、制御できる機能としては

  • IPアドレス(範囲)
  • ポート番号
  • プロトコル(TCP/UDP/ICMP)
    と、(本当はSGは他のSGからのIN/OUTも制御できるが、基本的には)同じものを制御することができるようになっています。

例として、

  HTTP (80) from 0.0.0.0/0
    → どこからでも、ポート80
    
  SSH (22) from 203.0.113.5/32
    → 特定IPから、ポート22
    
  (※ 以下はSG限定で)
  MySQL (3306) from SG-App
    → 特定SGから、ポート3306

そのような制御の仕方が可能です。

自分も以前、VPCのSGの設定で、インバウンドとして何を許可するのかを設定した記憶がありますが、NACLは設定した記憶がありません。そのため、厄介であるネットワークへの開通が初心者ながら簡単に行えた記憶があります。また、SGではリソース単位できめ細かいアクセス制御ができたため、個人開発のような少ないリソースしか管理しない場合はこちらの方が便利でした。

あくまで個人的な意見ですが、使い方の方針として、SGでメイン制御し、必要であればNACLで補助的な防御をするという設計が最もいいのかなと思います。

NAClでは、例えば、

  • 特定IP(攻撃IPなど)のブロック
  • コンプライアンス要件として、サブネット全体を防御する必要がある場合
    時に、SGのリソース単位では、リソースごとのため設定が煩雑で、ミスをしてしまう可能性が高まるため、一括で設定をするという目的で使うのがいいのかなと思いました。

まとめ

セキュリティグループとネットワークACLについて整理をしました。
もしこの記事で読者様のセキュリティグループとネットワークACLの違いに関する理解が深まれば幸いです。

Discussion