AWS 初心者必見! AWS の認証と認可を理解し、AWS アカウントをMFA で保護しよう Part2

前回の記事では、AWS アカウントをMFA で保護するための基礎知識の確認をしました。

Part2 では実際にMFA の設定を解説していきます。以下のステップで設定を進めていきます。

  1. MFA デバイスを用意する
  2. ルートユーザ/IAM ユーザにMFA を設定し、マネジメントコンソールのサインインにMFA を適用する
  3. MFA で認証されていないリクエストをすべて拒否するポリシーを割り当てる
  4. AWS CLI などのプログラムからのアクセスにMFA を利用する

上記手順の中で、1 および 2 を実施することで、マネジメントコンソールへのサインインにてMFA を適用することができます。ただ、前回の記事でお伝えしたようにAWS アカウントへの不正アクセスの多くはアクセスキーの流出によるものでした。まず重要なのはアクセスキーを流出させないということですが、仮にうっかり流出してしまったとしても、3 の内容を設定しておくことで、MFA 認証されていない不正なアクセスをポリシーの設定にてブロックすることが可能です。さらにその状況でCLI などのプログラムからMFA を使ってAWS API を実行する方法を解説します。

それでは順を追って見ていきましょう。

MFA デバイスを用意する

MFA デバイスとして利用できるのは以下の3種類となります。

  • 仮想MFA デバイス
  • U2F セキュリティキー
  • ハードウェアMFA デバイス

仮想MFA デバイスは、スマホやPC などにインストールして利用できる物理デバイスをエミュレートするアプリケーションです。具体的にどのようなプリケーションが利用できるかは、以下のドキュメントに記載があります。

ドキュメント: Multi-factor Authentication

なお、おすすめはTwilio Authy というアプリです。

U2F セキュリティキーは、PCやMAC などのUSB に接続して動作するデバイスです。Amazon などで購入できます。

Amazon.co.jp: Yubico セキュリティキー YubiKey

U2F セキュリティキーはUSB に接続して利用し、基本的にブラウザ上でのみ利用できます。よって、U2F セキュリティキーはマネージメントコンソールへのサインインに利用することはできますが、この記事の最後でご紹介するCLI などのプログラムからAPI を呼び出す際にはこのデバイスは利用できませんのでご注意ください。

ハードウェアMFA デバイスは、電池式で動く単独の小さなデバイスです。ボタンがついておりそのボタンを押すと6桁の数字がデバイスのディスプレイに表示されます。仮想MFA デバイスとハードウェアMFA デバイスはCLIやAPI 呼び出しで利用することができます。

どのタイプを選択すればよいのかですが、学習目的で自前でAWS アカウントを用意し、自分だけがアクセスするといったシチュエーションでは仮想MFA デバイスで十分だと思います。仮想MFA デバイスであれば、スマホやPC があれば無料でMFA を利用できます。

それ以外の例えばシステムの本番環境を動かしているようなAWS アカウントに関しては、物理デバイスを利用するというのが良いかと思います。物理デバイスは例えば金庫などの物理的に強固な場所に保管しておき、ルートユーザのアクセスが必要な場合などの、アカウントの重要な操作を実施する場合は、MFA デバイスを金庫から取り出して利用するなどの運用を考慮すると非常に強固なセキュリティになるかと思います。
その他には、ルートユーザはCLI で操作するということは無いため、ルートユーザのMFA 保護には、Yubikey などのU2F セキュリティキーを利用し、それ以外のIAM ユーザには、仮想MFA デバイスを利用するなども考えられます。

ともあれ、いろいろ迷ってしまって結局MFA を適用しないというのは避けるべきことですので、まずは仮想MFA デバイスで保護するところから着手し、その後物理デバイスを適用するかを考慮すればよいかと思います。

ルートユーザ/IAM ユーザにMFA を設定し、マネジメントコンソールのサインインにMFA を適用する

初めてAWS アカウントを作成した場合は、ルートユーザしか存在していないため、マネージメントコンソールへのアクセスはルートユーザで行うことになります。その後真っ先にやっていただきたいことが次の2点です。

  1. ルートユーザにMFAを設定する
  2. ルートユーザの代わりに操作するためのIAM ユーザを作成する

まずは、ルートユーザにMFA を設定しましょう。仮想MFA デバイスの具体的な設定手順はドキュメントに記載がありますのでそちらを参照してください。

ドキュメント: AWS アカウントの root ユーザーの仮想 MFA デバイスを有効にする (コンソール)

次にやることは、ルートユーザの代わりに操作を行うためのIAM ユーザを作成することです。最初に作成するIAM ユーザは、管理者の立場として利用することになりますので、大きめの権限を与えておいて良いかと思います。例えば、事前にAWS により用意されているAdministratorAccess などを割り当てればよいです。このIAM ユーザに割り当てるポリシーは後でMFA 対応します。

IAM ユーザの作成方法は以下のドキュメントをご参照ください。

ドキュメント: AWS アカウントでの IAM ユーザーの作成 – AWS Identity and Access Management

当然ですが、このIAM ユーザにもMFA を設定してください。

ドキュメント: 仮想 Multi-Factor Authentication (MFA) デバイスの有効化 (コンソール) – AWS Identity and Access Management

作成したIAM ユーザでマネジメントコンソールにログインし直します。IAM ユーザのログイン方法は以下のドキュメントをご参照ください。

ドキュメント: IAM ユーザーが AWS にサインインする方法 – AWS Identity and Access Management

これで、マネジメントコンソールにサインインする際にMFA により保護されるようになりました。

MFA で認証されていないリクエストをすべて拒否するポリシーを割り当てる

ここまで設定できれば、かなり安全にAWS アカウントを運用できます。ルートユーザやIAM ユーザの認証情報をきちんと管理しておくのは当然ですが、何かの拍子に認証情報が漏れてしまったとしてもMFA によりマネージメントコンソールへの不正ログインをブロックすることができます。

ただ、このままではまだ足りない部分があります。それは何でしょうか?もし皆さんが、マネージメントコンソールでの操作ではなくAWS CLI を利用した操作を学習したい場合、今のままで安全にAWS アカウントを運用することができるでしょうか?

Part 1 でご紹介したとおり、AWS CLI でAWS を操作する場合は、プログラムからアクセスするための認証情報であるアクセスキーが必要となります。よって皆さんがAWS CLI を使ってみたいと思った場合、一つ前のセクションで作成したIAM ユーザに対してアクセスキーを作成する必要があります。

IAM ユーザのアクセスキー作成方法に関しては、以下のドキュメントを参照してください。

ドキュメント: IAM ユーザーのアクセスキーの管理 – AWS Identity and Access Management

アクセスキーを作成したらAWS CLI 環境にそのアクセスキーを設定することで、IAM ユーザに割り当てたポリシーに基づいて、AWS API を呼び出すことができます。
AWS CLI にアクセスキーを設定する方法に関しては、以下のドキュメントをご参照ください。

ドキュメント: 設定の基本 – AWS Command Line Interface

ここまでで、AWS CLI によりAWS API を実行することができるようなりますが、このアクセスキーが外部に流出してしまった場合どうなるでしょうか?
現状のままでは、流出したアクセスキーが第三者に利用されてしまうと不正にアクセスされてしまいます。IAM ユーザにMFA を設定していても、アクセスキーによる認証にはMFA による保護がされていない状況なのです。

ということで、ここでは、AWS CLI などのプログラムからAWS API の呼び出しをMFA で保護する方法を解説していきます。

まずやることは、MFA 認証されていなAPI 呼び出しをすべてブロックするというポリシーを作成し、IAM ユーザに割り当てることです。これにより、MFA 認証されていないすべてのAPI リクエストは拒否されるようになります。

具体的には、以下のようなポリシーを作成します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "BlockAllAccessUnlessSignedInWithMFA",
            "Effect": "Deny",
            "Action": [
                "*"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": false
                }
            }
        }
    ]
}

このポリシーの意味ですが、”Condition” 句で”aws:MultiFactorAuthPresent”: false がリクエストに存在しているという条件を指定しています。これは、リクエストがMFA 認証れていない場合に該当します。MFA 認証されていないリクエストに対して、あらゆるリソースのあらゆる操作を拒否(=Deny) するように指定しています。このポリシーをIAM ユーザに割り当てることにより、MFA 認証されていないAPI リクエストをすべて拒否することができるようになります。
このため、先程のAWS CLI に設定したアクセスキーが仮に流出してしまったとしても、攻撃者は、IAM ユーザに設定されているMFA デバイスを同時に入手しない限り不正にAWS API を実行することはできなくなります。

IAM ポリシーの作成に関しては、以下のドキュメントをご参照ください。

ドキュメント: IAM ポリシーの作成 (コンソール) – AWS Identity and Access Management

IAM ユーザに対するIAM ポリシーの割当方法は以下のドキュメントをご参照ください。

ドキュメント: ポリシーを作成して IAM ユーザーにアタッチする – Amazon API Gateway

AWS CLI などのプログラムからのアクセスにMFA を利用する

ここまでの設定により、該当IAM ユーザのアクセスキーが流出してしまったとしても、MFA 認証されていない限り不正にAWS アカウントにアクセスができない状況になりました。
ただ、これは逆に言うと皆さんのAWS CLI からのアクセスキーを利用したアクセスも含めてブロックされてしまうということになります。このため次は、AWS CLI からMFA 認証されたリクエストを実行できるようにならなければなりません。

IAM ユーザで作成したアクセスキーには、MFA を適用できません。どうするかというとAWS Secure Token Service(STS) のGetSessionToken というAPI を利用します。
以下のようなコマンドでGetSessionToken を実行することで、MFA 認証済みの一時的認証情報を入手することができます。

aws sts get-session-token \
  --serial-number <your_mfa_device_arn> \
  --token-code <your_mfa_code>

<your_mfa_device_arn> の部分は、IAM ユーザに設定したMFA デバイスのARN に置き換えてください。<your_mfa_code> の部分は、ご自身のMFA デバイスから出力される6桁のコードを設定します。
なお、MFA デバイスのARN は、マネージメントコンソールにて、IAM ユーザの”認証情報” タブで確認できます。以下の画像を参考にしてください。

上記コマンドを実行すると以下のような出力を得ることができます。

{
    "Credentials": {
        "AccessKeyId": "ABCDXXXXXXXXXXXXX",
        "SecretAccessKey": "abc1234XXXXXXXXXXXXXXXX",
        "SessionToken": "abcdefXXXXXXXXXXXXx長い文字列xxxxx",
        "Expiration": "2021-03-06T16:53:15+00:00"
    }
}

この中に含まれる、AccessKeyId、SecretAccessKey、SessionToken の3つの組み合わせが一時的認証情報になります。”Expiration” に時間が設定されており、この時間まで有効な認証情報ということになります。この一時的認証情報はGetSessionToken の実行時にMFA 認証されているため、MFA 認証済みの認証情報になります。

この一時的認証情報をAWS CLI 環境に設定することでMFA 認証済みのリクエストを実行することができるようになります。一時的認証情報をAWS CLI 環境に設定する場合は、最もシンプルなやり方は、OS の環境変数に設定することです。以下のように環境変数に一時的認証情報を設定できます。鉤括弧(<>) で囲まれた部分を鉤括弧を含めて、上記のGetSessionToken で取得した一時的認証情報に書き換えてください。

export AWS_ACCESS_KEY_ID=<temporary_access_key_id>
export AWS_SECRET_ACCESS_KEY=<temporary_secret_access_key>
export AWS_SESSION_TOKEN=<temporary_session_token>

上記環境変数を設定することにより、AWS CLI の実行時に、環境変数に設定された一時的認証情報が利用されてAWS API が呼び出されます。

なお、上記のGetSessionToken の呼び出しから、入手した一時的認証情報を環境変数に設定する一連の処理は、スクリプトなどにしておくと便利です。以下は、Mac もしくはLinux で実行するスクリプトの例となります。(Windows 利用者の方はWindows 用に書き換えてください。)

#!/bin/bash -eu
credentials=$(aws sts get-session-token \
        --serial-number <your_mfa_device_arn> \
        --token-code $1  \
        --query "Credentials.[AccessKeyId, SecretAccessKey,SessionToken]" \
        --output text)

export AWS_ACCESS_KEY_ID=$(echo $credentials | cut -d ' ' -f 1)
export AWS_SECRET_ACCESS_KEY=$(echo $credentials | cut -d ' ' -f 2)
export AWS_SESSION_TOKEN=$(echo $credentials | cut -d ' ' -f 3)

上記スクリプトを作成したら、AWS CLI を実行するターミナルなどで以下のように実行します。<your_mfa_code> はMFA デバイスから出力されたコードに書き換えてください。

$ source ./スクリプトファイル名.sh <your_mfa_code>

ここまで実行することで、アクセスキーが仮に流出しても不正にアクセスできない環境になりましたので、とても安全にAWS アカウントを管理できるようになったかと思います。
当然ですが、認証情報(人が利用するものおよびアクセスキー)は厳重に管理することが重要です。

その他の方法

MFA 認証された一時的認証情報を利用する別の方法として、IAM ロールを利用する方法もあります。過去の記事に記載していますので、そちらをご参照ください。

応用編

AWS アカウントを個人で学習目的で利用する場合は、ここまでの内容で事足りるかと思います。ただ、システムの運用に利用しているような複数人で管理しているAWS アカウントをMFA で保護する場合は追加の考慮が必要となります。いくつか考えられる基本的な考慮点を最後に挙げておきます。

IAM グループでまとめてポリシーを割り当てる

今回のパターンでは、IAM ユーザに個別に”BlockAllAccessUnlessSignedInWithMFA” ポリシーを割り当てていました。仮にこのポリシーの割当を忘れたIAM ユーザが存在した場合、そのIAM ユーザにて作成したアクセスキーは、MFA 認証されていなくてもIAMユーザの権限でAWS API が実行できてしまいます。そういった割当ミスのリスクを低減するためにIAM グループを利用してください。まずIAM グループを作成し、”BlockAllAccessUnlessSignedInWithMFA” ポリシーとその他必要なポリシーを割り当てておきます。その後、新規作成したIAM ユーザは必ずそのIAM グループに所属するように設定し、IAM ユーザに直接ポリシーを割り当てるという運用をなくします。そうするとうっかりポリシーを割り当てそこねたIAMユーザが作成されてしまうのを防ぐことができます。

また、AWS Config Rules というサービスを利用して、継続的に”BlockAllAccessUnlessSignedInWithMFA” ポリシーが割当たっていないIAM ユーザが存在していないかをチェックする設定をしておくと、更に安全です。

AWS Config Rules に関する詳細はドキュメントなどをご参照ください。
特定のIAM ポリシーが利用されているかを継続的にチェックする場合は、以下のiam-policy-in-use マネージドルールを利用できます。

ドキュメント: iam-policy-in-use – AWS Config

セルフサービスでMFA デバイスを設定できるようにする

AWS アカウントを自分一人だけで利用している場合はIAMユーザを作成したときに、そのIAM ユーザが利用するMFAデバイスの設定を管理者である自分が設定するという運用でも問題ないと思います。
ただ、複数人数でAWS アカウントの運用をする場合、IAMユーザの作成自体は管理者が行っても、IAM ユーザの認証情報の管理や利用するMFA デバイスの管理はそのIAM ユーザを利用する人物が自分で設定・管理できたほうが便利です。この記事で作成した”BlockAllAccessUnlessSignedInWithMFA” ポリシーが割当たったIAM ユーザは、MFA 認証していないあらゆるリクエストが拒否されますので、MFA デバイスを自分で設定したくても、その設定するという操作もMFA 認証されていないと実施できないということになります。
これを回避し、MFAデバイスの設定に関しては、セルフサービスに実施できるように”BlockAllAccessUnlessSignedInWithMFA”ポリシーを書き換えることができます。

具体的には、以下のドキュメントをご参照ください。

ドキュメント: IAM: IAM ユーザーに MFA デバイスの自己管理を許可する – AWS Identity and Access Management

このポリシーにより、MFAデバイスの自己管理をIAM ユーザに許可することができます。

ポリシーの作成からIAM ユーザの割り当てるまでの一連の流れを体験できるチュートリアルも用意されていますのでこちらもご参照ください。

IAM チュートリアル: ユーザーが自分の認証情報および MFA 設定を管理できるようにする – AWS Identity and Access Management

複数アカウント全体をMFA保護したい

AWS を大規模に利用すると、複数のAWS アカウントの管理が必要となる場合がでてきます。その場合、あるアカウントでは、MFAの設定ができても、他のアカウントでMFA 設定ができていないという状況が発生する可能性があります。
複数アカウントにまたがってMFA の設定を強制し統制をかけたいという場合は、AWS Organizations というサービスを活用できます。

AWS Organizations は管理対象のAWS アカウントに対して、強制的にポリシーを適用できるサービスコントロールポリシーという機能があります。これを活用することで複数のAWS アカウントに対して統制をかけることができるようになります。


最後までお読みいただきましてありがとうございました!