AWS中級 #2 EC2 運用 — security group、key pair、SSM
#1 EC2 と VPC の基礎 で EC2 を 1 台立ち上げる絵を掴みました。今回はその EC2 を 扱う方法 を整理します。セキュリティルールはどう設計し、接続はどう行い、同じインスタンスを何度も立ち上げるには何を固めるべきかを見ていきます。
運用 EC2 の 80% の仕事は次の 3 つです。
- Security Group で入ってこられる相手を制御
- 接続 — 昔は SSH + key pair、今は SSM Session Manager
- AMI で骨格を固めて同じインスタンスを高速に再生成
この 3 つを 1 本の線で通せば EC2 運用の日常がシンプルになります。
Security Group の形 #
Security Group (SG) はインスタンス (正確には ENI) に紐づく stateful ファイアウォール。インスタンス 1 台に SG を 複数 アタッチでき、SG 1 つを 複数のインスタンス が共有することも可能。
Inbound vs Outbound #
SG のルールは 2 方向:
| Inbound | Outbound | |
|---|---|---|
| 何を制御 | 入ってくるトラフィック | 出ていくトラフィック |
| デフォルト | すべて遮断 | すべて許可 |
| よく触る | ✅ | ほぼ触らない |
デフォルトを覚えておきましょう。Inbound は既定で遮断、Outbound は既定で許可。なので SG 作業の 99% は Inbound ルール追加。
ルールの形 #
Protocol Port Source Description
TCP 80 0.0.0.0/0 HTTP from anywhere
TCP 443 0.0.0.0/0 HTTPS from anywhere
TCP 22 198.51.100.10/32 SSH from my home IP各ルールは (プロトコル、ポート、ソース) の組み合わせ。ソース (Source) には 2 種類が入ります:
- CIDR ブロック —
0.0.0.0/0(全 IP)、10.0.0.0/16(VPC 内部)、198.51.100.10/32(単一 IP) - 別の SG の ID —
sg-0abc...← これが本当に強力
SG が SG を指す #
運用の核心パターンは SG が他の SG を指すこと。
ALB SG (sg-alb)
Inbound: TCP 443 from 0.0.0.0/0
App SG (sg-app)
Inbound: TCP 8080 from sg-alb ← IP ではなく SG そのものALB の IP が変わっても (実際 ALB は複数の IP を動的に割り当てる) SG 指定は自動的に追従。運用インフラのルール保守がぐっと楽になります。
よくある SG 設計 #
ALB SG (sg-alb)
in: 443 ← 0.0.0.0/0
out: all
App SG (sg-app)
in: 8080 ← sg-alb ← ALB だけ入れる
22 ← sg-bastion ← Bastion から SSH (旧式)
out: all
DB SG (sg-db)
in: 5432 ← sg-app ← アプリサーバーだけ DB アクセス
out: all (または閉じる)
Bastion SG (sg-bastion)
in: 22 ← 198.51.100.10/32 ← 自分の IP のみ
out: allルールが 「SG → SG」 で流れるのが核心。IP ではありません。
Outbound を絞る場合 #
デフォルトは outbound すべて許可ですが、侵害された際のデータ流出を抑えるため outbound も狭めるパターンがあります。通常は運用環境の DB / 内部用途から適用。
App SG outbound:
TCP 5432 → sg-db ← DB のみ
TCP 443 → 0.0.0.0/0 ← 外部 API 呼び出し
TCP 53 → 0.0.0.0/0 ← DNS
UDP 53 → 0.0.0.0/0 ← DNSNACL — もう 1 層 #
VPC のもう 1 つのファイアウォールが NACL (Network Access Control List)。サブネット単位で動きます。
| Security Group | NACL | |
|---|---|---|
| 適用単位 | インスタンス (ENI) | サブネット |
| Stateful | ✅ | ❌ (応答も明示許可が必要) |
| ルール種別 | Allow only | Allow + Deny |
| 評価順 | すべてのルール | 番号順 (低い番号が先) |
| 日常で | 毎日触る | ほぼ触らない |
NACL は あまり使いません。 既定 NACL がすべてのトラフィックを許可していて、SG が十分に細かいから。NACL を触る場合:
- 特定 IP 帯の遮断 (Deny が必要 — SG には Deny がない)
- 攻撃を受けたときの一時遮断
- コンプライアンス要件でサブネット単位の明示遮断
NACL の stateless の罠 #
NACL は stateless なので応答トラフィックも明示的に許可する必要があります。
Inbound Allow TCP 1024-65535 0.0.0.0/0 ← ephemeral port 応答
Outbound Allow TCP 80 0.0.0.0/01024-65535 が ephemeral port の領域です。これを書き忘れると応答が戻りません。SG は stateful で自動なのに、NACL は明示が必要です。
Key pair の場と限界 #
昔から EC2 への SSH 接続は key pair で行ってきました。
# キーペア作成
aws ec2 create-key-pair --key-name my-key --query 'KeyMaterial' --output text > my-key.pem
chmod 400 my-key.pem
# インスタンス起動時に key 指定
aws ec2 run-instances --key-name my-key ...
# 接続
ssh -i my-key.pem ec2-user@<public-ip>EC2 が起動するとき、インスタンスの ~/.ssh/authorized_keys に自動でキーが書き込まれて SSH が可能になります。
key pair の限界 #
key pair モデルは運用規模が大きくなると破綻します。
- キー紛失 — 失くすと再生成不可。インスタンス作り直し、または EBS をマウントして手動追加
- キー共有のリスク — チームメンバーに渡す必要があるが、一度漏れたら回収不能
- 監査が難しい — 誰がいつ入ったか別途ロギングが必要
- インターネットに 22 ポート露出 — 攻撃面
- MFA 不可 — キーがあれば通る
EC2 Instance Connect #
コンソールが作る一時的な SSH キーを 1 度だけ使う方式。SG への 22 ポート許可は依然必要。コンソールの「Connect」ボタンがこれを使います。
SSM Session Manager — キーなし接続 #
SSM (AWS Systems Manager) の Session Manager は EC2 接続の新しい標準。22 ポートも開けず、キーも使わずに EC2 内のシェルへ入っていきます。
[自分の PC] ──HTTPS──▶ [SSM Endpoint] ◀──HTTPS──[EC2 内の SSM Agent]
│
▼
IAM 権限を確認EC2 内で動く SSM Agent が AWS API へ outbound 接続を作り、そのチャネルを通じてコンソールのシェル入力が流れます。方向が逆 (EC2 が outbound) なので SG inbound 22 ポートが不要。
Session Manager のセットアップ #
- SSM Agent が入った AMI — Amazon Linux 2023 / Ubuntu 最新は標準で入っている
- EC2 の IAM Role に
AmazonSSMManagedInstanceCoreポリシー - outbound インターネット または VPC Endpoint (Private サブネットの EC2 でも SSM 可能)
aws ssm start-session --target i-0abc1234def567890
# ポートフォワーディングも可能
aws ssm start-session --target i-0abc... \
--document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["80"],"localPortNumber":["8080"]}'key pair vs Session Manager #
| key pair (SSH) | Session Manager | |
|---|---|---|
| 22 ポート | 開ける必要あり | 開けなくてよい |
| キー管理 | 自分で | 不要 |
| 認証 | SSH キー | IAM (MFA 可) |
| 監査ログ | 別途 | CloudTrail / S3 が自動 |
| Private サブネット | Bastion 必要 | VPC Endpoint で直接 |
| ポートフォワード | ssh -L | start-session で可 |
運用は Session Manager がほぼ常に正解。詳しい IAM 設定は 基礎 #2、セキュリティ設定は 基礎 #6 を参照。
CloudShell と混同しないでください。 基礎 #5 CloudShell は AWS コンソール内のブラウザターミナル (自分の IAM 認証で
aws cliを使う方式) です。Session Manager は EC2 インスタンス内のシェルです。
EC2 のメタデータサービス (IMDS) #
EC2 内から自インスタンスの情報 (インスタンス ID、リージョン、IAM ロールの認証情報など) を取得できる仕組みが IMDS (Instance Metadata Service) です。
TOKEN=$(curl -X PUT http://169.254.169.254/latest/api/token \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/instance-id169.254.169.254 という link-local アドレスが EC2 内だけで応答するメタデータのエンドポイントです。IAM Role の一時認証情報もここから渡されます — aws cli が EC2 内で自動的にその認証情報を使うのはこのためです。
IMDSv1 vs IMDSv2 #
昔はトークンなしの GET で取得 (IMDSv1)。SSRF 攻撃でトークンを抜かれる事故が多発し IMDSv2 に移行 — PUT でトークン取得、それを使って GET。新規インスタンスは IMDSv2 のみ有効化 が推奨。
aws ec2 modify-instance-metadata-options \
--instance-id i-0abc... \
--http-tokens required \
--http-endpoint enabledAMI を作る — 骨格を固める #
同じセットアップのインスタンスを 何度も高速に 立ち上げたいなら 2 通り。
- AMI 作成 — 現在のインスタンスをスナップショットして新 AMI に
- User data + IaC — 空 AMI で起動して、セットアップスクリプトを自動実行
AMI 作成 #
コンソールでインスタンス右クリック → 「イメージの作成」、または:
aws ec2 create-image \
--instance-id i-0abc... \
--name "my-app-2026-04-19" \
--description "Node 20 + nginx + my-app v1.2.3" \
--no-reboot # オプション — 再起動なし (ディスク整合性が少し落ちる可能性)できた AMI は:
- インスタンスの EBS スナップショット + メタデータ
- その AMI で新インスタンスを立てると同じディスク状態でスタート
- リージョン単位 — 別リージョンでは
copy-image
User data — 起動スクリプト #
AMI の代わりに 空の OS イメージで立ち上げ、起動スクリプトでセットアップ するパターン。AMI より柔軟で、変更追跡もしやすい。
#!/bin/bash
yum update -y
yum install -y nginx
systemctl enable --now nginx
# アプリコードを取得
aws s3 cp s3://my-bucket/app.tar.gz /tmp/
tar -xzf /tmp/app.tar.gz -C /opt/myappUser data はインスタンス初回起動時に 1 回実行。ログは /var/log/cloud-init-output.log。
Golden AMI vs User data #
| Golden AMI | User data | |
|---|---|---|
| 起動速度 | 速い | 遅い (スクリプト実行時間) |
| 変更管理 | AMI 再ビルド | スクリプト修正 |
| 再現性 | 非常に高い | 外部依存 (yum repo, S3) が変わる可能性 |
| 方式 | ASG の高速スケール / 安定 | 開発 / 高速変更 |
運用では 両方を併用 します — Golden AMI で OS / 依存を固め、User data でアプリバージョンだけ差し込む形。
Auto Scaling Group — 自動復旧 #
インスタンスが死んだら 新しく立ち上げて ALB に自動接続 してくれるのが ASG (Auto Scaling Group) です。
Launch Template (インスタンステンプレート: AMI、タイプ、SG、key、user data)
│
▼
┌─────────┐
│ ASG │ desired=2 min=2 max=10
└─────────┘
│
├─── EC2 (AZ a) ← health check 失敗 → terminate + 新規起動
├─── EC2 (AZ b)
└─── EC2 (AZ b)基本だけ:
- Launch Template — どんな EC2 を起動するか定義 (AMI、タイプ、SG、IAM、user data)
- Desired / Min / Max — 常に維持する数、最小、最大
- Health Check — EC2 自体 (
EC2) または ALB target group (ELB) 基準
詳しい ASG は 上級 #1 ECS / Fargate のほうがなめらかな代替 — ECS がコンテナ ASG を吸収します。
よくハマる罠 #
1) 「なぜ ALB が EC2 に届かないの?」 #
チェックリスト (上から下):
- ALB SG outbound と EC2 SG inbound が一致
- EC2 SG inbound に ALB SG が source として入っている
- EC2 の OS 内ファイアウォール (
firewalld、ufw) もそのポート許可 - ALB target group の health check パス が 200 応答
- EC2 がそのポートで listen 中 (
ss -tlnp)
たいてい 1) または 2)。SG を IP で書いていたら SG 自体に置き換えるのが運用の正解。
2) 「キーがないけど EC2 内に入る必要がある」 #
- Session Manager が有効なら →
aws ssm start-session - 有効でないなら → インスタンス停止 → EBS デタッチ → 別 EC2 にマウント →
~/.ssh/authorized_keysを編集 → 再接続 - または EBS スナップショットを取って新キーで新インスタンス起動
3) Outbound all のまま → データ流出 #
EC2 が侵害された際 outbound が全開だと、攻撃者が 任意の IP へデータ送信。DB サーバー / 内部用途は outbound も絞る のがベスト。
4) NACL の任意遮断で応答が来ない #
NACL が stateless であることを忘れて outbound だけ許可 → inbound 応答が塞がる。ほぼ常に NACL はデフォルト、SG だけ触るのが安全。
5) IMDSv1 のまま #
古い AMI / 旧設定が IMDSv1 のまま運用 → SSRF 攻撃面。すべてのインスタンスに --http-tokens required。
6) AMI が大きすぎて起動が遅い #
長く運用したインスタンスをそのまま AMI にして 5GB+ になるケース。起動時間が伸びます。AMI 作成前に:
- ログ / キャッシュ / 一時ファイル整理 (
yum clean all等) cloud-init clean(次回起動時に init 再実行)- swap / journal をクリア
まとめ #
今回押さえたこと:
- SG = インスタンス単位 stateful ファイアウォール。SG → SG パターンが IP より強力
- 既定は inbound 遮断 + outbound 許可。Outbound を絞ればデータ流出防御
- NACL はサブネット単位 stateless。ほぼ触りません。Stateless なので応答 ephemeral port も許可必要
- key pair は旧標準。キー紛失 / 共有 / 22 ポート露出が限界
- SSM Session Manager が新標準。22 ポートもキーも使わず IAM で認証、監査ログ自動
- IMDSv2 を強制 — SSRF 防御
- AMI で骨格を固め + User data で起動時セットアップ、通常は両方併用
- ASG が自動復旧。Launch Template + desired/min/max + health check
- 罠 — ALB→EC2 5 ステップ点検、キーなし復旧、outbound all、NACL stateless、IMDSv1、巨大 AMI
次回 — S3 #
EC2 のポジションは整いました。次は EC2 とよく一緒に扱う オブジェクトストレージ に進みます。
#3 S3 — 静的ホスティング、presigned URL では、バケットの形、ポリシーと public access block、静的サイトホスティング、presigned URL のような日常パターンを整理します。