対象読者: AWSをこれから触る人。 AWS勉強シリーズの番外編で、EC2とVPCの回で駆け足だったセキュリティグループだけを1本にしました。全体の地図は索引記事にあります。
EC2を立てた人が最初に踏む、この2つの症状で書きます。
- 「サーバーは動いているのに、ブラウザからもSSHからも繋がらない」
- 「インバウンドとアウトバウンド、どっちに何を書けばいいのか分からない」
どちらも「警備員は通したいものだけをリストに書く。戻りは確認しない」の2点で答えが出ます。

セキュリティグループを警備員に例えた図(筆者作成)。443の人は通る、8080の人は止まる。リストに無い=お断り、が既定です。
セキュリティグループとは何か
セキュリティグループ(SG)は、EC2などのサーバー1台ずつに付ける通信の許可リストです。上の図の警備員で、ドアの前に立って「どのポートに、どこから来た通信を通すか」だけを見ています。
大事な性質が2つあります。
- 許可しか書けない。 「8080は拒否」という行は存在しない。書かれていないものが全部拒否される(実測: 作った直後のインバウンドは空っぽ=全部お断り)
- サーバー単位で付く。 部屋(サブネット)の入口ではなく、サーバーのすぐ横に立つ警備員
警備員はどこに立つか
VPCの回のマンションで言うと、こうなります。

配置の図(筆者作成)。SGは机(EC2)ごと、ネットワークACLは部屋(サブネット)の入口。入門ではSGだけ触れば足ります。
「VPCで守ってるのにSGも要るの?」の答えがこの図で、VPCの案内板(ルートテーブル)は道を決め、SGはドアを決めます。道が繋がっていてもドアが閉まっていれば入れない。冒頭の「動いているのに繋がらない」の大半は、道は合っているのにドア(SG)が閉まっているケースです。
今はこれだけ分かればOK
| 必須の3語 | 意味 |
|---|---|
| インバウンドルール | 入ってくる通信の許可リスト。作った直後は空(全部拒否) |
| アウトバウンドルール | 出ていく通信の許可リスト。既定で全許可の行が1本入っている |
| ソース | 「どこから来た通信か」。IPの範囲(CIDR)か、別のSGのIDが書ける |
ネットワークACL、ステートレスの詳細は後回しで大丈夫です。
仕組みの要点。戻りは書かなくていい
初心者が一番混乱するのがここです。「443を許可したら、応答を返すためにアウトバウンドも書くの?」。書きません。

ステートフルの図(筆者作成)。行きを通した相手の戻りを、警備員はいちいち確認しません。
SGはステートフル(状態を覚える)で、「行き」を通した通信の「戻り」は自動で通します。だからWebサーバーのSGは「インバウンドに443」だけで動く。逆に、既定のアウトバウンド全許可を消して絞り込む運用は、この自動通過と混同しやすいので、入門の段階では触らないのが安全です。
このコードを動かす前提
この記事のコードはPython(boto3)です。動かす方法は2通りあります。
A. AWSアカウント無しで試す(おすすめ): motoというAWSのそっくりさんを使うと、課金もサインアップもなしでPCの中だけで動きます。
python3 -m venv venv
./venv/bin/pip install boto3 moto
from moto import mock_aws
@mock_aws # この中のboto3呼び出しは全部ローカルの偽AWSに行く
def main() -> None:
... # 以下の記事のコードをここに入れる
main()
B. 本物のAWSで動かす: 先にIAMユーザーとアクセスキーの設定が要ります。手順はIAM記事の「最初の1回だけやる手順」にあります。
使い方
「雇う→リストに足す→別の警備員を信用する→行を消す」の4手です。
import boto3
ec2 = boto3.client("ec2", region_name="ap-northeast-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"]
# ① 警備員を雇う(SGを作る)。この時点でインバウンドは空
sg = ec2.create_security_group(GroupName="web", Description="web server", VpcId=vpc)["GroupId"]
# ② 許可リストに2行足す。443は誰でも、22は自分のIPだけ
ec2.authorize_security_group_ingress(GroupId=sg, IpPermissions=[
{"IpProtocol": "tcp", "FromPort": 443, "ToPort": 443,
"IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "https"}]},
{"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22,
"IpRanges": [{"CidrIp": "203.0.113.5/32", "Description": "my ip"}]}])
# ③ DB用のSGは「webのSGから来た通信だけ」を許可(IPでなくSGをソースに)
db = ec2.create_security_group(GroupName="db", Description="db", VpcId=vpc)["GroupId"]
ec2.authorize_security_group_ingress(GroupId=db, IpPermissions=[
{"IpProtocol": "tcp", "FromPort": 3306, "ToPort": 3306,
"UserIdGroupPairs": [{"GroupId": sg, "Description": "from web sg"}]}])
# ④ 使い終わった行は消す(22を閉じる)
ec2.revoke_security_group_ingress(GroupId=sg, IpPermissions=[
{"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22,
"IpRanges": [{"CidrIp": "203.0.113.5/32"}]}])
実測の出力です。
作った直後のインバウンド: [] ← 空=全部拒否
作った直後のアウトバウンド: [('-1', ['0.0.0.0/0'])] ← 全許可が1本
追加後: [(443, ['0.0.0.0/0']), (22, ['203.0.113.5/32'])]
db SGのソース: sg-9af59f4c... (webのSG-ID)
22削除後: [(443, ['0.0.0.0/0'])]
③が実務の定番です。DBの警備員に「webの警備員が付いているサーバーから来た通信だけ通せ」と書く。webサーバーが増えてIPが変わっても、リストを書き換えなくていい。ソースにIPでなくSGを書くのがAWS流の設計です。
実際に叩くと止まるところ
間違えたときに何が返るか、実際に叩きました。
| やったこと | 返ってきたエラー | 意味 |
|---|---|---|
| 同じ許可を二重に追加 | InvalidPermission.Duplicate: The specified rule already exists |
冪等ではない。スクリプトで流し直す時は先にdescribeで確認 |
| 無い許可を削除 | InvalidPermission.NotFound |
消す行の指定は追加時と完全一致が必要。ポートやCIDRが1文字違うとこれ |
| 同名SGを再作成 | InvalidGroup.Duplicate |
SG名は同じVPC内で一意 |
| defaultのSGを削除 | motoでは通ってしまった | 本物のAWSでは削除できない(CannotDelete)。motoの再現漏れなので、ローカルで消せても本番で同じことはできません |
似た概念との使い分け
| 迷うところ | 答え |
|---|---|
| SGとネットワークACL | SGはサーバー単位・許可のみ・戻り自動。ACLはサブネット単位・許可と拒否・戻りも書く。入門はSGだけでいい |
| SGとIAM | IAMは「誰がAWSの操作をしていいか」、SGは「どの通信がサーバーに届いていいか」。EC2記事の権限3方向の話 |
| 22を0.0.0.0/0で開けたい | 開けない。SSHは自分のIP(/32)に絞る。全開放のSSHは攻撃の総当たりが即座に来る |
料金の考え方
セキュリティグループは無料です。何個作っても、ルールを何行書いても課金されません。既定の上限(インバウンド・アウトバウンド各60ルール。引き上げ可)はありますが、入門で当たることはまずありません。
よくある注意点
- 「繋がらない」の確認順は、SGの前にまずIP。 EC2記事の確認順の通り、パブリックIPの有無→SGの順で見る
- SGの変更は即時反映。 再起動は要らない。443を追加した瞬間から通る
- 1台に複数のSGを付けられる。 全部のリストの合算(和集合)で判定される。「どのSGで開いてるのか分からない」を避けるため、入門のうちは1台1SGが読みやすい
- 消す時は使われていないことを確認。 EC2にアタッチされたままのSGは消せない(DependencyViolation)。VPC記事の削除順の話
まとめ
冒頭の2つの症状に戻ります。
- 「動いているのに繋がらない」→ 作った直後のインバウンドは空です(実測の通り)。道(ルートテーブル)が合っていても、ドアの許可リストに行が無ければ届きません。使うポートを足してください
- 「インバウンドとアウトバウンド、どっち?」→ 入門ではインバウンドだけ書けば足ります。戻りの通信はステートフルで自動、アウトバウンドは既定で全許可のままにしておく
警備員のリストは「通したい行だけを書く。書いた瞬間に効く。戻りは書かない」。この3行で、SGの日常運用はだいたい説明できます。
次回はCloudFormation(インフラのコード化)を予定しています。
参考
- セキュリティグループ 公式ドキュメント
- 関連: 【図解】AWS EC2とは / 【図解】AWS VPCとは
- シリーズ索引: AWSとは結局何なのか