クラウドの世界へようこそ!皆さんは、AWSなどのクラウド環境でWebアプリやシステムを動かしたことはありますか?
サーバーをクラウド上に建てると、とっても便利にシステムを動かせる反面、「クラウドならではのセキュリティの落とし穴」があったりします。今回は、その中でも特に有名な「SSRF(サーバーサイド・リクエスト・フォージェリ)」という攻撃と、それを防ぐための最強の盾である「IMDSv2の強制」について、身近な防犯にたとえながら優しく紐解いていきたいと思います。
セキュリティの専門用語がずらりと並んでいても大丈夫。「一歩ずつ対策を学んでいきましょう!」
—
1. クラウドの「コンシェルジュ」:メタデータサービス(IMDS)とは?
まずは、AWSなどのクラウド環境にある「メタデータサービス(IMDS)」がどんなものかを知ることから始めましょう。
例えば、あなたが大きなホテルのVIPルーム(クラウド上のサーバー)に滞在しているとします。その部屋には、フロントへ内線で「今の外の天気は?」「私の部屋番号は?」「ホテルのWi-Fiのパスワードは?」と聞ける便利な内線電話が備え付けてありますよね。
この内線電話こそが、クラウドサーバーにとっての「メタデータサービス(IMDS)」です。
サーバー自身が「今、自分はどのリージョンで動いているのか」「自分に割り当てられている一時的な合鍵(アクセストークン)は何番か」といった情報を知るために、決まったアドレス(http://169.254.169.254/)にアクセスして情報を取得できるようになっています。プログラムから見れば、とてもありがたい便利な仕組みなんですよね。
—
2. 泥棒の手口:IMDSv1に潜む「合鍵の無断持ち出し」の恐怖
ここで、セキュリティ上の問題となるのが、古い仕組みである「IMDSv1」です。
先ほどのホテルの内線電話にたとえてみましょう。IMDSv1は、「部屋の中にある内線電話に向かって『フロントの合鍵をちょうだい』と言えば、誰にでも無条件で合鍵を教えてくれる」という仕様になっていました。
もし、あなたが作ったWebアプリに「外部から入力されたURLのページの画像を取ってくる」というような機能(例えば、ユーザーがアイコン画像をURLで指定する機能)があったとします。ここに悪意を持った攻撃者がやってきて、次のような細工をしたURLを入力したらどうなるでしょうか?
http://169.254.169.254/latest/meta-data/iam/security-credentials/admin-role/
アプリのプログラムが、この怪しいURLをうっかりそのまま「外部のウェブサイトだ」と勘違いしてアクセスしてしまったら……サーバーの裏側で何が起きるでしょうか?
なんと、サーバーの内線電話(IMDSv1)は、アプリからの依頼をそのまま信じ込んでしまい、サーバーが持っている最強の権限(合鍵)をペロッと答えてしまうのです。攻撃者はその合鍵を手に入れて、あなたのクラウド環境の金庫(データベースやS3バケットなど)を丸ごと乗っ取ってしまいます。これが、SSRF(サーバーサイド・リクエスト・フォージェリ)と呼ばれる攻撃の恐ろしい仕組みです。
—
3. 最強の防犯対策:IMDSv2で「合鍵の渡し方」を厳重にする
この危険な状況を防ぐためにAWSが用意したのが、新世代の仕組みである「IMDSv2」です。
IMDSv2では、先ほどの内線電話のルールをガラリと変えました。
今度のルールはこうです。
1. 「トークン(使い捨てのパスカード)」が絶対に必要
内線電話に情報を求めるとき、いきなり用件を伝えても「誰だお前は!」と無視されます。まず最初に「トークンをくれ」という特別な専用の合言葉(リクエスト)を送り、一時的なパスカードを発行してもらわなければなりません。
2. 「普通の偽装(普通のWebアクセス)」ではパスカードがもらえない
先ほどのような、攻撃者が仕掛けた単純なURLの読み込み(GETリクエスト)だけでは、この最初のパスカードを手に入れることができません。なぜなら、パスカードをもらうには「PUTリクエスト」という特殊な手順を踏む必要があるからです。
これで、泥棒が外から適当なURLを送り込んできても、パスカードを持っていないため内線電話から情報を引き出すことができなくなりました。これがIMDSv2の仕組みです。
—
4. もう一つの鉄壁:ホップ制限(Hop Limit)でさらに安全に
さらに、IMDSv2には「ホップ制限(Put Hop Limit)」という強力な追加の防犯機能があります。
「ホップ」とは、ネットワークの世界でルーターなどの機器を「中継する回数」のことです。
通常、クラウドサーバーの中にあるプログラムがメタデータサービスにアクセスする場合、中継する機器はゼロ、つまり「一歩(1ホップ)」で直接つながります。
しかし、もしサーバーの中で変なプログラムが動いていたり、複雑な中継ネットワークを経由して悪事を働こうとした場合、ホップ数が「2」以上になってしまいます。
そこで、サーバーの設定で「メタデータへのアクセスは、一歩(Hop Limit = 1)以内の直接の通信しか受け付けません!」と厳しく制限をかけておくのです。これにより、万が一アプリに別の脆弱性があったとしても、巧妙な中継を伴う攻撃をシャットアウトすることができます。
—
5. 実践!AWSでIMDSv2を強制する設定手順
それでは、実際に私たちのクラウド環境でIMDSv2を強制し、ホップ制限を設定する手順を見ていきましょう。
実務の現場では、Terraformなどのインフラコード(IaC)を使って設定するのが一般的です。以下に具体的な設定例とその解説を載せますので、そのままプロジェクトの参考にしてみてください。
Terraformでの設定サンプル
AWSのEC2インスタンスを作る際、metadata_optionsというブロックを使って設定を記述します。
# AWSのEC2インスタンス設定の例
resource "aws_instance" "web_server" {
ami = "ami-0c55b159cbfafe1f0" # サンプルのAMI ID
instance_type = "t3.medium"
# メタデータサービスのセキュリティ設定(ここが重要です!)
metadata_options {
# IMDSv2を「必須(required)」にする(v1を完全に禁止する)
http_endpoint = "enabled"
http_tokens = "required"
# ホップ制限を「1」に設定し、直接の通信以外をブロックする
http_put_response_hop_limit = 1
# インスタンスメタデータサービス自体を利用不可にする場合は "disabled" にすることも可能ですが、
# アプリがメタデータを必要とする場合は上記の通り "enabled" + "required" にします。
}
tags = {
Name = "安全なWebサーバー"
}
}
💡 設定のポイント解説
http_tokens = "required":この一行が、古い「IMDSv1」をシャットアウトし、安全な「IMDSv2」のトークン利用を強制する魔法の呪文です。これだけで、先ほどの泥棒の手口(単純なSSRFによるメタデータ窃盗)が無効化されます。http_put_response_hop_limit = 1:中継を許さないことで、不正な転送や予期せぬルーティングを通したアタックを防ぎます。
—
まとめ:一歩ずつ、安全なインフラを作っていきましょう
いかがでしたでしょうか?
一見すると難しそうな「IMDSv2の強制」や「ホップ制限」も、家の防犯(鍵の管理や、訪問者の身分証確認)に置き換えてみると、なぜそれが必要で、どうやって身を守っているのかがイメージしやすくなったのではないでしょうか。
セキュリティ対策は、一度にすべてを完璧にするのは大変です。ですが、「まずは古いIMDSv1を禁止して、IMDSv2を必須にする」といった具体的な設定を一つずつ確実に取り入れていくことで、システムの安全性は劇的に向上します。
新人のIT担当者の皆さんも、開発者の皆さんも、ぜひ今日の知識を実際の環境や設計レビューに活かしてみてくださいね。一歩ずつ、安全で強いシステムを一緒に作っていきましょう!
コメント