EC2 のメタデータ 169.254.169.254 の正体 - リンクローカルアドレスと IMDSv2 の設計
EC2 インスタンスメタデータサービスのエンドポイント 169.254.169.254 がリンクローカルアドレスである理由、SSRF 攻撃で悪用された歴史、IMDSv2 のトークンベース認証が生まれた経緯を解説します。
169.254.169.254 はどこにあるのか
EC2 インスタンスの内部から http://169.254.169.254/latest/meta-data/ にアクセスすると、インスタンス ID、AMI ID、IAM ロールの一時認証情報、ネットワーク設定など、インスタンスに関するメタデータが返されます。この 169.254.169.254 というアドレスは、インターネット上のサーバーではなく、インスタンスをホストする基盤が応答するローカルサービスです。Nitro 世代に固有の仕組みではなく、それ以前の世代のインスタンスでも同じアドレスでメタデータが提供されてきました。169.254.0.0/16 は RFC 3927 で定義されたリンクローカルアドレスで、ルーターを越えて転送されない特殊なアドレス範囲です。つまり、このアドレスへのリクエストはインスタンスの外に出ることなく、基盤側が直接応答します。この設計により、メタデータサービスはネットワーク障害の影響を受けず、VPC のルーティング設定にも依存しません。インスタンスが起動した瞬間から、ネットワーク設定が完了する前でも、メタデータサービスにアクセスできます。cloud-init がインスタンスの初期設定を行う際に、最初にメタデータサービスからユーザーデータやネットワーク設定を取得するのは、この信頼性の高さがあるからです。IPv6 のみのサブネットに置くインスタンス向けには fd00:ec2::254 という IPv6 エンドポイントも用意されています。こちらは Nitro System 上のインスタンスタイプに限られ、起動時にメタデータの IPv6 エンドポイントを有効にしておく必要があります。
Capital One 事件 - SSRF でメタデータが漏洩した日
2019 年、Capital One (米国の大手銀行) で約 1 億人の個人情報が漏洩する事件が起きました。不正アクセス自体は 2019 年 3 月に行われ、同年 7 月に公表されています。攻撃者は、Capital One の Web アプリケーションに存在した SSRF (Server-Side Request Forgery) 脆弱性を悪用し、EC2 インスタンスのメタデータサービスから IAM ロールの一時認証情報を取得しました。SSRF は、サーバーサイドのアプリケーションに任意の URL へのリクエストを実行させる攻撃です。攻撃者は Web アプリケーションに http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name というリクエストを送信させ、IAM ロールのアクセスキー、シークレットキー、セッショントークンを取得しました。この認証情報を使って S3 バケットにアクセスし、大量の個人情報をダウンロードしました。この事件は、IMDSv1 (Instance Metadata Service Version 1) の設計上の弱点を浮き彫りにしました。IMDSv1 は単純な HTTP GET リクエストでメタデータを返すため、SSRF 攻撃で容易にアクセスできてしまいます。
IMDSv2 - トークンベース認証による防御
Capital One 事件を受けて、AWS は 2019 年 11 月に IMDSv2 (Instance Metadata Service Version 2) をリリースしました。IMDSv2 は、メタデータへのアクセスにセッショントークンを要求するトークンベースの認証方式です。IMDSv2 でメタデータを取得するには、まず PUT リクエストでセッショントークンを取得し、そのトークンを HTTP ヘッダーに含めて GET リクエストを送信する必要があります。この 2 ステップの認証が SSRF 攻撃を防ぐ理由は、ほとんどの SSRF 脆弱性が GET リクエストしか実行できないためです。PUT リクエストを実行できる SSRF 脆弱性は稀であり、さらにレスポンスヘッダーからトークンを抽出して次のリクエストに含めるという複雑な操作が必要です。加えて、IMDSv2 のトークン取得リクエストには X-aws-ec2-metadata-token-ttl-seconds ヘッダーが必須で、IP フォワーディングされたリクエスト (TTL が 1 に設定されるため、ネットワークホップを越えられない) もブロックされます。IMDSv2 への移行は段階的に進んでいます。2023 年 11 月以降、マネジメントコンソールのクイックスタートは IMDSv2 を既定で選択します。2024 年半ば以降に新しくリリースされるインスタンスタイプは IMDSv2 のみに対応し、IMDSv1 を選べません。一方で既存のインスタンスタイプは起動時の既定が optional のままなので、アカウントとリージョン単位の既定設定 (instance metadata defaults) で IMDSv2 必須に寄せておくのが実務上の要点です。
メタデータで取得できる情報の全体像
メタデータサービスから取得できる情報は多岐にわたります。インスタンスの基本情報 (instance-id、instance-type、ami-id、hostname)、ネットワーク情報 (local-ipv4、public-ipv4、mac、network/interfaces)、IAM ロールの一時認証情報 (iam/security-credentials/role-name)、ユーザーデータ (user-data)、ブロックデバイスマッピング (block-device-mapping) などです。特に重要なのは IAM ロールの一時認証情報です。EC2 インスタンスに IAM ロールをアタッチすると、メタデータサービスから一時的なアクセスキー、シークレットキー、セッショントークンが取得できます。AWS SDK はこの仕組みを内部で自動的に使用しており、開発者がアクセスキーをコードにハードコードする必要がありません。一時認証情報には有効期限があり、期限が切れる前にメタデータサービス側で自動的にローテーションされます。SDK は取得済みの認証情報の残り時間を見て再取得するため、アプリケーション側で期限を管理する必要はありません。なお 1 秒から 6 時間の範囲で指定できるのは IMDSv2 のセッショントークンの TTL で、IAM ロールの一時認証情報の有効期限とは別物です。メタデータサービスにはインスタンスのユーザーデータも含まれます。ユーザーデータはインスタンス起動時に指定するスクリプトやデータで、cloud-init が初期設定に使用します。ユーザーデータにパスワードやシークレットを含めるのは危険です。メタデータサービス経由で誰でも読み取れるためです。
メタデータサービスのセキュリティ強化策
IMDSv2 の有効化に加えて、メタデータサービスのセキュリティを強化する方法がいくつかあります。第 1 に、HttpPutResponseHopLimit を見直すことです。起動テンプレートで指定しなければ既定値は 1 で、この場合は追加のネットワークホップを必要とする構成 (bridge ネットワークの Docker コンテナ内のアプリケーションなど) からメタデータに到達できません。注意が必要なのは、Amazon Linux 2023 の AMI がコンテナ化ワークロードを通すためにホップ制限を 2 に設定している点です。コンテナからのアクセスを塞ぎたいなら AMI 側の既定に任せず 1 を明示的に指定し、逆にホストを経由してアクセスさせる必要がある構成では 1 に下げると正常な処理まで止まります。第 2 に、メタデータサービス自体を無効化することです。HttpEndpoint を disabled に設定すれば、メタデータサービスへのアクセスが完全にブロックされます。IAM ロールの認証情報が不要なインスタンス (固定の認証情報を使用する場合) では、メタデータサービスを無効化するのが最も安全です。第 3 に、IAM ロールの権限を最小限にすることです。メタデータサービスから認証情報が漏洩しても、そのロールの権限が最小限であれば被害を限定できます。Capital One 事件では、漏洩したロールが S3 バケットへの広範なアクセス権限を持っていたことが被害を拡大させました。
参考資料 (AWS 公式)
本ページの一次情報は AWS 公式サイトおよび公式ドキュメントです。最新の仕様 / 料金は次の公式ページで確認できます。
本ページと公式ドキュメントの記述が食い違う場合は、公式ドキュメントを正としてください。