今すぐできる ! Amazon EC2 認証情報の漏洩対策

2023-05-02
ビジネス x クラウド

Author : 飯島 卓也

こんにちは。Security Specialist TAM の飯島です。

皆さんは AWS 環境におけるセキュリティを強化するために、どのような対策を実施していますでしょうか。様々な観点があると思いますが、AWS 環境への不正アクセスのリスクを低減するために認証情報の漏洩対策を考えることは重要な検討項目のひとつです。

AWS 環境内のリソースにアクセスするための認証情報としては、AWS Identity and Access Management (IAM) ユーザーの使用する永続的な認証情報と IAM ロールの使用する一時的な認証情報がありますが、本記事では、Amazon Elastic Compute Cloud (Amazon EC2) インスタンスにアタッチする IAM ロールの認証情報の漏洩対策について焦点を当てたいと思います。具体的には、2023 年 3 月に追加された IAM ポリシーの条件キーを使用して、EC2 インスタンスにアタッチしている IAM ロールの認証情報を外部から使用させないように制限できる興味深いアップデート「How to use policies to restrict where EC2 instance credentials can be used from」が公開されましたので、この内容を含めて、EC2 インスタンスの認証情報の漏洩防止や検出に役立つ AWS セキュリティサービスをご紹介しようと思います。

なお、IAM ロールについては、「テクニカルトレーナーと学ぶ AWS IAM ロール」において詳しい解説がされていますので、ぜひこちらの記事もご参照ください。


IAM ロールの認証情報

EC2 インスタンスの認証情報の漏洩対策について説明する前に、まずは EC2 において、IAM ロールの認証情報がどのように管理されているのかを見ておきたいと思います。

EC2 では、実行中のインスタンスの設定や管理を実施するためにインスタンスメタデータという情報を保持しており、ホスト名やインターフェイスに関連付けらているセキュリティグループ、VPC などの情報がカテゴリごとに保存されています。そして、このインスタンスメタデータは、EC2 インスタンスにログインし、リンクローカルアドレス 169.254.169.254 にアクセスすることで設定されている情報を取得することができます。

ここで、注意が必要な点としては、インスタンスメタデータのなかには IAM ロールの情報も含まれており、EC2 インスタンスにアタッチされた IAM ロールがある場合には、その IAM ロールの一時的なセキュリティ認証情報も取得することが可能になっています。

それでは、実際にインスタンスメタデータにどのようにアクセスできるのか見てみましょう。

インスタンスメタデータサービスバージョン 1 (IMDSv1) を使用している場合には、EC2 インスタンスにログインしたあと、リンクローカルアドレス 169.254.169.254 に対して、次のような HTTP リクエストを実施することによりインスタンスにアタッチされている IAM ロール名を確認することができます。

さらに、その IAM ロール名を加えた形で、次のような HTTP リクエストを送信することで、その IAM ロールにおいて使用している AccessKeyIdSecretAccessKeyToken の情報を取得することができます。


典型的な攻撃の例

IAM ロールの認証情報は、有効期限のある一時的な認証情報であるとはいえ、もし攻撃者が何らかの方法でその認証情報を盗み出すことができてしまうと、攻撃者は外部から EC2 インスタンスにアタッチされている IAM ロールの権限で API コールを実施することができてしまうため、大きなセキュリティリスクになります。このインスタンスメタデータから認証情報を盗み出す典型的な攻撃の例として、SSRF (Server Side Request Forgery) 攻撃というものがあります。SSRF 攻撃は、Web アプリケーションの欠陥や設定不備を悪用することで、本来外部から到達できないサーバーに対してリクエストを送信する攻撃手法です。

IAM ロールの認証情報を外部から盗み出すことを考えた場合、前述の通り、インスタンスメタデータには 169.254.169.254 のアドレスでアクセスできるため、EC2 インスタンス上で、このリンクローカルアドレス宛に HTTP リクエストの転送を許可する Web アプリケーションが動いている場合、攻撃者は外部から IAM ロールのセキュリティ認証情報を取得することができてしまいます。 それでは、このような SSRF 攻撃に対してどのような対策をとれば良いのでしょうか。


AWS WAF による対策

対策のひとつとしては、AWS WAF を使用する方法が考えられます。AWS WAF では、ユーザー独自のルール を作成したり、AWS マネージドルール を使用して、HTTP リクエストの検査をすることができるため、例えば、HTTP リクエストのクエリにインスタンスメタデータ宛の http://169.254.169.254/ が含まれている場合、その HTTP リクエストをブロックすることができます。

ユーザー独自のルールを作成する場合には、WebACL の設定画面でルールを追加する際に「Add my own rules and rule groups」を選択して、次のように、Query string において http://169.254.169.254/ の文字列が含まれているかどうか検査するルールを設定します。

AWS マネージドルールを使用する場合は、コアルールセット (AWSManagedRulesCommonRuleSet) において、HTTP リクエストのクエリ引数のほか、URI パスや リクエストボディ、Cookie から EC2 インスタンスのメタデータを盗み出すような試みがないか検査するルールが用意されています。

なお、AWS WAF を使用して、EC2 インスタンス上で稼働している Web アプリケーションを保護するためには、作成した Web ACL を Amazon CloudFront または Application Load Balancer (ALB) に関連付ける必要があります。


IMDSv2 の使用

AWS WAF による対策以外に、インスタンスメタデータサービスバージョン2 (IMDSv2) を使用することも、インスタンスメタデータへのアクセスを保護する対策として効果的です。

インスタンスメタデータサービスバージョン 1 (IMDSv1) では、HTTP GET リクエストを使用して、メタデータの情報を取得することができましたが、IMDSv2 ではセキュリティが強化されており、HTTP PUT リクエストによりセッショントークンを取得したあと、そのトークンをパスワードとして提示することで、実際のインスタンスメタデータの情報にアクセスすることができます。このため、攻撃者が Web アプリケーションの脆弱性を悪用して、不正なリクエストを送信しようとする場合にも、HTTP PUT を使用しなければならず、そのあとメタデータへアクセスする際の HTTP GET リクエストでは HTTP ヘッダーに取得したトークンを含めなければならないため、攻撃が成立するための条件が厳しくなります。

さらに、Web アプリケーションではなく、リバースプロキシを介して不正なリクエストが転送される場合、プロキシでは通常、オリジナルの送信元 IPアドレスを X-Forwarded-For ヘッダーに含めてリクエストを転送しますが、IMDSv2 では、X-Forwarded-For ヘッダーが含まれている場合には PUT リクエストは拒否されます。このため、IMDSv2 は、オープンなリバースプロキシからの不正アクセスをブロックする場合にも効果的です。


AWS Security Hub による IMDS バージョンのチェック

それでは、AWS アカウント内の EC2 インスタンスが現在どの IMDS バージョンを使用しているのか確認するにはどうしたら良いでしょうか。

EC2 インスタンスごとに確認をする場合には、Amazon EC2 のコンソールから対象のインスタンスにチェックを入れると、画面の下に詳細な情報が表示されますので、そこから IMDSv2 の設定が Optional なのか Required なのか確認することができます。Required と表示されていれば、IMDSv2 が有効になっていることを意味します。

クリックすると拡大します

ただし、インスタンスの数が多い場合や運用において新規に作成されるインスタンスの IMDS バージョンを毎回チェックするとなると、運用面での負担が大きくなると思います。このような場合は、AWS Security Hub を使用することで、現在のリソースの設定が AWS のセキュリティベストプラクティスに準拠しているかどうか、コンプラアンスの要件に準拠しているかどうかをチェックすることができます。

IMDSv2 が使用されているかどうかをチェックするうえでは、Security Hub のセキュリティ基準 AWS Foundational Security Best Practice に「[EC2.8] EC2 インスタンスは IMDSv2 を使用する必要があります」というコントロールがありますので、これを使用することができます。

Security Hub のコンソールにおいて、コンプライアンスのステータスが FAILED と表示されているインスタンスは、IMDSv2 が有効になっていないことを示すため、画面に表示されている修復手順を参考に設定変更を実施します。

クリックすると拡大します

IMDS バージョンの設定変更を実施する場合は、EC2 インスタンスのコンソールにおいて、対象のインスタンスにチェックを入れ、「アクション」 > 「インスタンスの設定」 > 「Modify instance metadata options」から変更するか、modify-instance-metadata-options CLI コマンドを使用して変更することができます。

この設定変更は、稼働中のインスタンスにも適用できるため、再起動の必要はありません。ただし、IMDSv1 を使用してメタデータにアクセスしているようなアプリケーションがあれば、CloudWatch の MetadataNoToken メトリクスを使用してその状況を確認しておく必要があります。IMDSv2 への移行についての詳細は、こちらの ユーザーガイド もご参照ください。

なお、Amazon Linux 2 では、IMDSv1 がデフォルト設定になっていますが、2023 年 3 月から提供が開始された Amazon Linux 2023 では、デフォルトで IMDSv2 を使用してインスタンスを起動するようになっています。


IAM ポリシーによる EC2 インタンス認証情報の使用制限

さらに、2023 年 3 月のアップデート「Amazon EC2 の IAM ロールに認証情報コントロールプロパティが提供されるようになりました」では、セキュリティ認証情報が発行された EC2 インスタンスの VPC やプライベート IP アドレスを判別することができる条件キーが追加されました。つまり、IAM ロールの認証情報を使用した API コールの送信元を IAM ロールのアタッチされている EC2 インスタンスに制限することができるようになったため、万が一 EC2 インタンスのセキュリティ認証情報が外部に漏洩した場合でも、外部から実行された API コールを拒否することができるようになりました。

具体的な設定としては、今回新たに追加された aws:Ec2InstanceSourceVpc 条件キーで IAM ロールの認証情報が発行された EC2 インスタンスの所属する VPC を特定し、aws:Ec2InstanceSourcePrivateIPv4 条件キーで IAM ロールの認証情報が発行された EC2 インスタンスの IP アドレスを特定することができるため、それぞれの値が実際のリクエストの送信元と一致していない場合には、リソースへのアクセスを拒否することができます。また、この 2 つはグローバル条件キーのため、IAM ポリシーのほか、Service Control Policy (SCP) や VPC エンドポイントポリシー、Amazon S3 バケットポリシーのようなリソースポリシーでも使用することができます。ただし、このポリシー条件で制御できるのは、VPC エンドポイントを経由する API コールとなるため、ポリシーを適用する際には注意が必要です。

それでは、実際の設定例を見てみましょう。次の図は、EC2 インスタンスに Amazon S3 と Amazon DynamoDB、AWS Systems Manager (SSM) へのアクセス許可を設定した IAM ロールがアタッチされている例を示しており、Amazon S3 と Amazon DynamoDB へは VPC エンドポイント経由でアクセスするとします。

このとき、VPC エンドポイント経由となる Amazon S3 と DynamoDB へのアクセスは、以下のように IAM ポリシーにおいて aws:Ec2InstanceSourceVpcaws:Ec2InstanceSourcePrivateIPv4 を条件に加えることにより、IAM ロールの認証情報を使用した API アクセスを当該 EC2 インスタンスからのみに制限することができます。このポリシーでは、IAM ロールの認証情報を発行した EC2 インスタンスの VPC や IP アドレスが、 aws:SourceVPC 変数や aws:VpcSourceIp 変数で示す実際の API コールの送信元 VPC や送信元 IP アドレスと同じではない場合には、Amazon S3 や DynamoDB へのアクセスを拒否する設定をしています。Null の箇所では、ec2:SourceInstanceARN 条件キーによってリクエストに EC2 インスタンスの ARN が存在することを条件にしており、EC2 インスタンスのロールに対してのみ、このポリシーが適用されるようにしています。また、aws:ViaAWSService 条件キーでは、IAM プリンシパルが直接リクエストを行った場合にポリシーを適用することを条件に含めています。何らかの AWS サービスが IAM プリンシパルの代理で、他の AWS サービスにアクセスする場合は、このキーの値は true となるため、リクエストが拒否されることはありません。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "s3:*",
                "s3-object-lambda:*",
                "dynamodb:*"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:ec2InstanceSourceVPC": "${aws:SourceVpc}"
                },
                "Null": {
                    "ec2:SourceInstanceARN": "false"
                },
                "BoolIfExists": {
                    "aws:ViaAWSService": "false"
                }
            }
        },
        {
            "Effect": "Deny",
            "Action": [
                "s3:*",
                "s3-object-lambda:*",
                "dynamodb:*"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:ec2InstanceSourcePrivateIPv4": "${aws:VpcSourceIp}"
                },
                "Null": {
                    "ec2:SourceInstanceARN": "false"
                },
                "BoolIfExists": {
                    "aws:ViaAWSService": "false"
                }
            }
        }
    ]
}

Amazon GuardDuty による検知

IAM ポリシーを使用して EC2 インスタンスの認証情報を外部から使用させないように制限する方法は、予防的な対策として効果がありますが、前述の通り、VPC エンドポイント経由の API コールが対象となるといった制約もあります。また、万が一 EC2 インスタンスの認証情報が漏洩した場合のことを想定して、予防的な観点だけではなく、検知の観点で、Amazon GuardDuty を有効化しておくこともお勧めです。Amazon GuardDuty では、AWS CloudTrail ログ、Amazon VPC フローログ、DNS クエリログなどを分析し、不審なアクティビティがあった場合に検出結果を生成してくれるサービスです。Amazon GuardDuty では、2023 年 4 月現在 110 以上の検出結果が用意されていますが、このなかには外部から EC2 インスタンスの認証情報を使用して API コールが実施された場合にトリガーされる検出結果も含まれており、この場合には、検出結果タイプ UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS が生成されます。また、GuardDuty の検出結果には、低、中、高の重要度レベルが定義されていますが、この検出結果については、EC2 インスタンスが侵害されたことを示唆する検出結果であるため重要度は「高」と表示されます。builders.flash 記事「すぐに始めて、継続できる AWS のセキュリティ対策」でも記載されている通り、重要度の高い検出結果についてはセキュリティ担当者がすぐに気付くことができるよう通知の仕組みを構築しておくことも重要です。そして、実際の運用においてこの検出結果が生成された場合には、内容確認のうえ、こちらの記事 も参照しながら対応を実施してください。また、IAM ロールの一時的なセキュリティ認証情報の取り消しを実施する場合の手順については、IAM ユーザーガイド もご参照いただければと思います。


まとめ

本記事では、EC2 インスタンスにアタッチしている IAM ロール認証情報の漏洩対策について、2023 年 3 月に追加された IAM 条件キーについてのアップデートも含めて、いくつかの方法をご紹介しました。

セキュリティ対策を実装するうえでは、複数のレイヤーで防御を行う多層防御が原則となります。AWS WAF を使用する方法、IMDSv2 の有効化や AWS Security Hub を使用して IMDS バージョンをチェックする方法、IAM ポリシーで制御する方法や Amazon GuardDuty を使用して認証情報漏洩を検知する方法など複数のアプローチを通じて、EC2 インスタンスを使用している AWS 環境のセキュリティを強化することができます。

本記事がこれから AWS 環境のセキュリティ対策を検討する皆様の役に立てば幸いです。

この連載記事のその他の記事はこちら

選択
  • 選択
  • サーバーレスのローカル開発環境を整備する ~前編
  • サーバーレスのローカル開発環境を整備する ~中編
  • サーバーレスのローカル開発環境を整備する ~後編

builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます


筆者プロフィール

飯島 卓也
アマゾン ウェブ サービス ジャパン合同会社
スペシャリスト テクニカルアカウントマネージャー (セキュリティ)

ネットワークとセキュリティ製品のテクニカルサポート、セキュリティ製品の導入や運用に伴う技術コンサルティングの経験を経て、AWS に入社。現在は、エンタープライズサポートに加入しているお客様向けにセキュリティ関連の技術支援を行っています。

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する