こんにちは!クラウドの世界へようこそ。インフラや開発の現場にいると、「セキュリティグループ」や「ネットワークACL」といった言葉によく出会いますよね。
「なんだか似たような名前だし、どっちもファイアウォール(門番)なんでしょ?」と思ってしまいがちですが、実はこの2つ、役割や性格がまったく違うんです。
今回は、新人のIT担当者や「セキュリティはちょっと苦手…」という開発者の方に向けて、私たちの身近な「家の防犯」にたとえながら、この2つの使い分けと最小権限の原則について優しく紐解いていきたいと思います。一歩ずつ、安心して学んでいきましょう!
—
1. 家の防犯で例える「セキュリティグループ」と「ネットワークACL」
クラウドのネットワークを考えるとき、イメージしやすいように「一軒家」にたとえてみましょう。
セキュリティグループ(SG)は「個室のドアの鍵」
セキュリティグループは、AWSやAzureなどのクラウドにおいて、仮想サーバー(EC2やVM)そのものにくっつく「個室のドアの鍵」です。
例えば、「リビング(サーバーA)には家族以外立ち入り禁止にする」「自分の部屋(サーバーB)には特定のPCからしか入れないようにする」といった、サーバー1台ごとの細かいアクセス許可を設定できます。
最大の特徴は「ステートフル(物覚えが良い)」ということ。「中から外へ出かけた通信」は、帰ってきたときにわざわざ「おかえり!」と本人確認をしなくても、自動的に「あ、さっき行った人だね」とドアを開けてくれます。すごく気が利く門番ですね。
ネットワークACL(NACL)は「家全体の門(フェンス)の鍵」
一方、ネットワークACLは、サーバーをすっぽり包み込む「敷地全体のフェンスと門の鍵」です。サブネット(ネットワークの区画)単位で適用されます。
こちらは「ステートレス(物覚えが悪い・融通が利かない)」という性格を持っています。
物覚えが悪いので、外へ通信を送り出すとき(リクエスト)に「通ってよし!」のルールが必要なのはもちろん、相手から返事が戻ってきたとき(レスポンス)にも、わざわざ「お前は誰だ!入ってよし!」のルールをもう一度チェックさせられます。 片道切符ではなく、往復の両方でルールを書かないといけない、ちょっと厳格で頑固な門番です。
—
2. なぜこの2つを使い分ける必要があるのか?(攻撃者の視点)
「じゃあ、個室のドアの鍵(セキュリティグループ)だけじゃダメなの?」と思いますよね。実はここに、サイバー攻撃者が狙う盲点があります。
もしあなたが悪意あるハッカーだと想像してみてください。
セキュリティが甘いネットワークの入口(敷地の門)から侵入した場合、もし敷地の門に鍵がかかっていなければ、敷地内のすべての家のドア(サーバー)を片っ端からガチャガチャと触って回ることができますよね。
ここで、「多層防御(たそうぼうぎょ)」という考え方が重要になります。
- 第1の防壁(ネットワークACL): 敷地の門で、そもそも怪しい国からのアクセスや、不要な通信を丸ごとシャットアウトする。
- 第2の防壁(セキュリティグループ): 個室のドアで、「このサーバーのこのポート(Web用の80番や443番など)以外は絶対に開けない」とピンポイントで絞る。
この2段構えにしておくことで、たとえ万が一どこかの防壁を突破されても、被害を最小限に抑えることができるんです。これが「最小権限の原則」の考え方です。
—
3. 実践!AWSにおける具体的な設定パターン
それでは、実際にクラウド(AWSのTerraformを例にします)でどのように設定するのがベストプラクティスなのか、コードを見てみましょう。難しく見えますが、日本語のコメントを読めば「なるほど!」と分かりますよ。
セキュリティグループ(SG)の設定例
Webサーバーを守るための、必要最小限のドアの鍵の設定です。
# Webサーバー用のセキュリティグループ定義
resource "aws_security_group" "web_server_sg" {
name -- "web-server-sg"
description -- "Webサーバーへのアクセスを最小限に許可するセキュリティグループ"
vpc_id -- aws_vpc.main.id
# 1. 外部からのHTTP(ポート80)アクセスを許可(世界中どこからでもWebサイトを見られるようにする)
ingress {
description -- "HTTPからのアクセスを許可"
from_port -- 80
to_port -- 80
protocol -- "tcp"
cidr_blocks -- ["0.0.0.0/0"] # パブリックに公開
}
# 2. 外部からのHTTPS(ポート443)アクセスを許可(暗号化通信)
ingress {
description -- "HTTPSからの暗号化通信を許可"
from_port -- 443
to_port -- 443
protocol -- "tcp"
cidr_blocks -- ["0.0.0.0/0"]
}
# 3. アウトバウンド(外への通信):サーバーから外部への通信はすべて許可(OSのアップデート等に必要)
egress {
description -- "すべての外への通信を許可"
from_port -- 0
to_port -- 0
protocol -- "-1" # すべてのプロトコル
cidr_blocks -- ["0.0.0.0/0"]
}
}
ネットワークACL(NACL)の設定例
こちらは敷地全体のフェンスの設定です。ステートレス(往復のルールが必要)な点に注目してください。
# パブリックサブネット用のネットワークACL定義
resource "aws_network_acl" "public_nacl" {
vpc_id -- aws_vpc.main.id
subnet_ids -- [aws_subnet.public.id]
# --- 【入ってくる通信(インバウンド)のルール】 ---
# 1. Web閲覧(HTTP/HTTPS)の往路を許可
ingress {
protocol -- "tcp"
rule_no -- 100
action -- "allow"
cidr_block -- "0.0.0.0/0"
from_port -- 80
to_port -- 80
}
ingress {
protocol -- "tcp"
rule_no -- 110
action -- "allow"
cidr_block -- "0.0.0.0/0"
from_port -- 443
to_port -- 443
}
# 2. 【ステートレスの罠!】サーバーから外部へ問い合わせた「返事(エフェメラルポート)」を通すためのルールが必須!
ingress {
protocol -- "tcp"
rule_no -- 120
action -- "allow"
cidr_block -- "0.0.0.0/0"
from_port -- 1024 # OSが自動割り当てする一時的なポート範囲
to_port -- 65535
}
# --- 【出ていく通信(アウトバウンド)のルール】 ---
# 3. サーバーからの返事や、外部への通信を許可
egress {
protocol -- "-1" # すべて
rule_no -- 100
action -- "allow"
cidr_block -- "0.0.0.0/0"
from_port -- 0
to_port -- 0
}
}
—
4. 現場でありがちな失敗とトラブルシューティング
最後に、現場で新人エンジニアがよくハマる「あるある」なトラブルをご紹介します。
「あれ?外部からAPIを呼び出せない!?」
原因: ネットワークACLで、サーバーからの返事を受け取るための「高位ポート(エフェメラルポート: 1024〜65535番)」のインバウンドルールを書き忘れているケースが非常に多いです。
対策: セキュリティグループは勝手に返事を通してくれますが、ネットワークACLを使うときは「往き」だけでなく「帰り(レスポンス)」のルールも必ずセットで書く!と覚えておきましょう。
—
まとめ
いかがでしたでしょうか?
- セキュリティグループ: サーバー個別のドアの鍵。物覚えが良くて(ステートフル)、主にサーバー単位のアクセス制御に使う。
- ネットワークACL: 敷地全体のフェンスの鍵。ちょっと物覚えが悪くて(ステートレス)、サブネット単位でガッチリと大枠の通信を制限する。
この2つを正しく理解し、役割分担を明確にすることで、あなたのクラウド環境は格段に堅牢になります。難しく考えず、まずは「個室の鍵とフェンスの鍵」というイメージを大切に、安全なクラウドインフラを作っていきましょう!
コメント