「IMDSv1は即刻ゴミ箱へ」― クラウド環境を狙うSSRFの盲点を塞ぐ実務ガイド
現場でインシデント対応をしていると、いまだに「なぜこんな単純な設定ミスで、クラウドの管理権限が丸裸にされたのか」と頭を抱えることがよくある。その主犯格の一つが、AWSのIMDSv1(Instance Metadata Service Version 1)の放置だ。
「SSRF(Server-Side Request Forgery)なんて、自分たちのコードには関係ない」と高を括っているなら、今すぐ考えを改めたほうがいい。今日は、なぜIMDSv1が命取りになるのか、そしてIMDSv2への移行をどう実装すべきかを、現場の泥臭い知見を交えて解説する。
—
1. なぜIMDSv1は「攻撃者の招待状」なのか
IMDSv1は、インスタンス上で動作するアプリケーションが、自分自身のメタデータ(IAMロールの認証情報など)を取得するための仕組みだ。しかし、これには致命的な欠陥がある。「認証がない」ことだ。
もし、あなたのWebアプリケーションにパラメータ経由でURLを操作できるSSRFの脆弱性が一つでもあれば、攻撃者は以下のコマンドを叩くだけで、あなたのクラウド環境の鍵(一時的な認証情報)を盗み出せる。
攻撃者がSSRFを利用して実行するコマンドの例
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/[ロール名]
これだけで、`AccessKeyId`、`SecretAccessKey`、`Token`が手に入る。攻撃者はこれを自分のPCに設定し、まるで管理者であるかのようにあなたのS3バケットを漁り、RDSのデータを抜き取る。「境界防御のファイアウォール」なんて、インスタンスの内側から食い破られたら何の意味もないんだ。
—
2. IMDSv2による「セッションベースの防御」
IMDSv2は、この悪夢を終わらせるために導入された。最大の違いは、「セッション指向の認証」が必須になったことだ。
1. PUTリクエストによるトークンの生成: 事前に特定のヘッダーを付与したPUTリクエストを送り、有効期限付きのセッションを取得する必要がある。
2. ヘッダーによる検証: その後の取得リクエストには、発行されたトークンを`X-aws-ec2-metadata-token`ヘッダーに含めなければならない。
SSRF攻撃者が送信する単純なGETリクエストでは、この「PUTトークン発行」のステップを突破できない。これが、脆弱なアプリを抱えていても防衛線が崩れない理由だ。
—
3. 実践:IMDSv2の強制と実装サンプル
まずはインフラ側で「IMDSv1を無効化」し、IMDSv2を強制する。Terraformなら以下の設定だ。
AWS EC2 Instanceの設定 (Terraform例)
resource “aws_instance” “web_server” {
ami = “ami-xxxxxxxx”
instance_type = “t3.micro”
metadata_options {
http_endpoint = “enabled” # メタデータサービス自体は有効
http_tokens = “required” # IMDSv2を強制(v1を無効化)
http_put_response_hop_limit = 1 # SSRF対策としてホップ数を制限
}
}
アプリケーション側での取得例(Python)
もし、アプリケーションコード内でメタデータを利用しているなら、以下のように修正する必要がある。
import requests
def get_metadata_v2(path):
# 1. セッション用のトークンを取得
headers = {“X-aws-ec2-metadata-token-ttl-seconds”: “21600”}
token_url = “http://169.254.169.254/latest/api/token”
token = requests.put(token_url, headers=headers).text
# 2. 取得したいメタデータをリクエスト
metadata_url = f”http://169.254.169.254/latest/{path}”
headers = {“X-aws-ec2-metadata-token”: token}
response = requests.get(metadata_url, headers=headers)
return response.text
実行例: IAMロールの認証情報を安全に取得
print(get_metadata_v2(“meta-data/iam/security-credentials/MyRole”))
—
4. 現場のセキュリティ担当者からのアドバイス
「設定すれば終わり」ではない。以下の運用チェックリストをチームで共有してほしい。
- HTTPホップ制限を意識せよ: `http_put_response_hop_limit = 1` を設定すると、コンテナ環境(Docker等)からメタデータを取得する際に疎通が取れなくなることがある。その場合は「2」にするが、SSRFのリスクはわずかに上がる。可能な限り「1」を目指す設計を心がけること。
- WAFのルールを過信しない: WAFで`169.254.169.254`へのアクセスをブロックする手法もあるが、これは「対症療法」に過ぎない。根本治療は、メタデータサービス側のハードニング(IMDSv2強制)だ。
- IAMロールの最小権限: 万が一メタデータが盗まれても被害を最小化するため、EC2に付与するIAMロールは「S3へのPUT権限が必要なら、そのバケットのみに限定する」といった、厳格なポリシー運用を徹底してくれ。
結局のところ、セキュリティとは「多層防御」の積み重ねだ。IMDSv2への移行は、その中でも最もコストパフォーマンスが高く、即効性のある防御策だ。明日と言わず、今すぐクラウドコンソールを開いて、設定状況を確認してほしい。
「設定できるものは、すべて強制する」。 これが、インシデントを起こさないエンジニアの基本姿勢だ。

コメント