見出し画像

MFA認証+AWS CLIの利用手順が面倒なのでスイッチロールで使い易くする

1.はじめに

前回、プロジェクトのメンバーにIAMユーザを払い出す際、
MFA認証していないと、最低限の機能しか使いない方法を記載しました。

MFA認証しいない場合は、以下のAction以外が全て拒否されます。
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"sts:GetSessionToken", ※今回使っています
"iam:ChangePassword"

        {
            "Sid": "DenyAllExceptListedIfNoMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:GetUser",
                "iam:ListMFADevices",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice",
                "sts:GetSessionToken",
                "iam:ChangePassword"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {"aws:MultiFactorAuthPresent": "false"}
            }
        }

AWSマネージメントコンソールを利用する場合は、問題はないのですが、AWS CLI(コマンドラインインターフェイス)を使う時にとても面倒な作業が必要になります。(2.AWS CLIにおけるMFA認証方法で説明します)

MFA認証していない場合、ほとんどの操作を禁止するポリシーを適用しているケースにおいて、MFA認証せずにCLIを実行するとAccessDeniedとなります。これは期待どおりの動きです
(今回は、S3の一覧を表示するコマンドを実行しています)

$ aws s3 ls --profile dev-simple-user
An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

補足
aws configure --profile dev-simple-userを実行し、AWS Access KeyおよびAWS Secret Access Keyを設定済です

2.AWS CLIにおけるMFA認証方法

マネージメントコンソールの時には、MFAコードを入力させる画面が表示されているのですが、CLIの場合どうやってやるのだろうと調べると、
以下が見つかります。

1)一時認証情報の取得

上記は、aws stsコマンドを使い、一時クレデンシャル(access key id, secret access key, session token)を取得する手順になります。
取得した一時クレデンシャルを使ってCLIコマンドを実行します。

$ aws sts get-session-token --serial-number arn-of-the-mfa-device --token-code code-from-token

CLIを実行する時に以下の情報を設定して、stsコマンドを実行します。
これが非常にめんどくさい

--serial-number 自分のMFA仮想デバイスのARNを設定
--token-code MFA仮想デバイスで表示されているMFAコードを設定

あと、忘れていけないのは
--profile プロファイル名を設定(ex --profile dev-simple-user)

一時クレデンシャルの取得に成功すると、次のような結果が返ってきます。

$ aws sts get-session-token --serial-number arn:aws:iam::123456789012:mfa/dev-simple-user --token-code 123456 --profile dev-simple-user
{
    "Credentials": {
        "AccessKeyId": "ABCDEFGHIJKLMNOPQRST",
        "SecretAccessKey": "1111111111111111111111111111111111111111111111111111111",
        "SessionToken": "222222222222222222222222222222222222222222222222222222222222222",
        "Expiration": "2022-09-11T12:48:34Z"
    }
}

2)credentialファイル編集

一時認証情報の値を使い、.aws/credentialファイルを編集します。

[profile名]
aws_access_key_id = 上記のAccessKeyIdの値
aws_secret_access_key = 上記のSecretAccessKeyの値 
aws_session_token = 上記のSessionTokenの値

mfaというprofile名で追記する場合の例

[mfa]
aws_access_key_id = ABCDEFGHIJKLMNOPQRST
aws_secret_access_key = 1111111111111111111111111111111111111111111111111111111 
aws_session_token = 222222222222222222222222222222222222222222222222222222222222222

3)一時クレデンシャルを使ったCLIの実行

--profile 一時クレデンシャル用に作成したプロファイル名を設定

// --profile mfaを指定してCLIを実行すると、S3のバケット一覧が取得できる
$ aws s3 ls --profile mfa
2022-08-07 08:21:08 example-scraping-data

めでたく、バケット一覧を取得できました。

しかし、一時クレデンシャルは有効時間(デフォルト12時間、設定可能)があるので、その間は、再度トークンを取得する必要は無いが、毎日
1.仮想MFAデバイスを見て、MFAコードを確認する
2.aws stsコマンドを組み立て、一時クレデンシャルを取得
3.一時クレデンシャルの内容を使ってcredentialを編集する

この2.と3.の作業が非常に面倒なのです。(毎日やらないといけない)

そこで、もっと簡単に使う方法が無いか・・・と調べていたら
対話形式でMFAコードを要求するような方法がを見つけました。
それが「スイッチロール」です。

3.スイッチロールによるCLIの実行

スイッチロールを使うと、対話形式でMFAコード入力することでCLIを使うことができます。(非常に便利です)

$ aws s3 ls --profile dev
Enter MFA code for arn:aws:iam::123456789012:mfa/dev-simple-user

事前準備1(AWS環境側の設定)

1)スイッチ先のIAMロール作成

IAMサービスからロールを作成します。
信頼されたエンティティタイプ AWSアカウントを選択
AWSアカウント このアカウントを選択、MFAが必要を選択

スイッチした後に割り当てたいポリシーを選択します。
今回は、AmazonS3FullAccessの管理ポリシーを選択(最小限の権限)
 ※"PowerUserAccess"を選択しても良いと思います。

ロール名を決めます(今回は、dev-SwitchRole-S3FullAccess)

上記で作成したロールのARNを控えておきます
arn:aws:iam::123456789012:role/dev-SwitchRole-S3FullAccess

2)スイッチロールを許可するためのポリシーを作成

dev-SwitchRole-S3FullAccessに対してAssumeRoleアクションを許可します。

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::123456789012:role/dev-SwitchRole-S3FullAccess"
  }
}

ポリシー名を決めます(今回は、dev-SwitchRolePolicy-S3FullAccess)

3)IAMユーザもしくはグループにポリシーをアタッチ

今回は、IAMユーザに対して、スイッチロールするためのポリシー(dev-SwitchRolePolicy-S3FullAccess)をアタッチしていますが、
実際の運用ではIAMユーザではなくグループに設定する方が管理がしやすいと思います。

AWS環境側の準備はこれで完了しました。
次に、利用者側の環境設定の手順を説明します。

事前準備2(利用者側の設定)

4)configファイル編集

~/.aws/configにスイッチロールするための設定を追記します

$ cat ~/.aws/config
: <省略>
[profile dev-simple-user]
region = ap-northeast-1

dev-simple-userというプロファイルがあることを前提に記載します

・profile スイッチロール時のプロファイル名(今回はdevで作成)
・role_arn スイッチ先のロールのARN
・source_profile スイッチ元のプロファイル名
・mfa_serial 仮想デバイスのARN


[profile dev-simple-user]
region = ap-northeast-1

[profile dev] 
role_arn = arn:aws:iam::123456789012:role/dev-SwitchRole-S3FullAccess
source_profile = dev-simple-user 
mfa_serial = arn:aws:iam::123456789012:mfa/dev-simple-user

3)スイッチロールしてCLIを実行

スイッチロール用の作成したprofile名(dev)を指定して実行するだけです。

AWS CLIを実行すると、MFAコードを要求されるようになります。
ここで登録している仮想デバイスのMFAコードを入力してENTERボタンを押下するだけで、コマンドが実行できるようになります(超便利)

$ aws s3 ls --profile dev
Enter MFA code for arn:aws:iam::123456789012:mfa/dev-simple-user

MFAコードを入力し、ENTERを押下すると

$ aws s3 ls --profile dev
Enter MFA code for arn:aws:iam::123456789012:mfa/dev-simple-user2022-08-07 08:21:08 example-scraping-data

4.最後に

今回、MFAを強制したい環境下において、CLI実行時に簡単にMFA認証する方法として、スイッチロールについて紹介しましたが、AWS CLIに限らず、AWS マネージメントコンソールの利用においても、スイッチロールを前提とした運用の方がいいのかも、と思っているところです。

特に、開発環境、検証環境、本番環境で、AWSアカウントが異なる場合は、スイッチロールできるように環境設定しないと、毎回再ログインする必要があり、とても面倒臭いですよね。

この記事が気に入ったらサポートをしてみませんか?