1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【#awscli】あらかじめ指定した接続元IPアドレス以外からの「AWS CLI v2」実行時はMFA(ワンタイムパスワードでの認証)が必要になるようIAMを設定する #AWS #awscliv2 #jawsug #環境構築 #環境設定

Last updated at Posted at 2020-03-20

特定の接続元IPアドレス以外からの「AWSコマンドラインインターフェイス(AWS CLI v2)」実行時のみMFA(Multi-Factor Authentication)が必要になるようにIAMの設定をしたので、その際の手順を自分用のメモとしてまとめました。

MFA(Multi-Factor Authentication:多要素認証)とは

参考: Wikipedia - 多要素認証
https://ja.wikipedia.org/wiki/多要素認証

簡単に説明すると次の4つの要素のうち2要素以上を使用して認証を行うことです
1.知る要素
2.持つ要素
3.備える要素
4.場所の要素

認証を多段階で実施しても(多段階認証をしても)、同じ要素での認証ではセキュアではないとされています(例: ”印鑑”と”通帳”など)

ちなみに、
天空の城ラピュタにおける崩壊の呪文は、

  • ”バルス” という呪文を【←知る要素】
  • 飛行石の結晶 を持った状態で【←持つ要素】
  • 王族の人間 が【←備える要素】
  • ラピュタ内の聖域と呼ばれる場所 で【←場所の要素】

唱えた場合のみ発動するので四要素認証になっています∑d(゚∀゚d)イカス!!

MFA(Multi-Factor Authentication)を設定しないとどうなるのか?

「AWS CLI」を使用するためにはアクセスキー(アクセスキーIDとシークレットキーのキーペア)が必要になるのですが、このアクセスキーが漏洩すると怖いことが起こります。

参考: 初心者がAWSでミスって不正利用されて$6,000請求、泣きそうになったお話。
https://qiita.com/mochizukikotaro/items/a0e98ff0063a77e7b694

参考: GitHub に AWS キーペアを上げると抜かれるってほんと???試してみよー!
https://qiita.com/saitotak/items/813ac6c2057ac64d5fef

AWSではどういった対策ができるのか?

[AWSマネージメントコンソールへのアクセス]時に ”スマーフォンデバイス(TOTP:Time-based One-Time Password)” での認証を有効にする↓というのは比較的知られていますが、「AWS CLI」でも同様に設定することが可能です。

capture_001_20032020_061743.jpg

少し違う点は、「AWS CLI」の場合、1コマンド実行するごとにワンタイムパスワード認証を求められるのはツライので、
「AWS Security Token Service (AWS STS)」より払い出された有効期限付き(デフォルト1時間)のセッショントークンを使用するという点です。

まず、前半の部分で「AWS STS」のセッショントークンを払い出す際はMFAを必要とする設定を行います。

加えて、後半の部分で、特定の接続IPアドレスからのアクセス時のみは、ワンタイムパスワードの入力なしでアクセスキー(アクセスキーIDとシークレットキーのキーペア)だけで実行できるようにする設定を行います。


1. IAMグループとIAMユーザーの作成 (「管理者」側手順)

まず、AWS CLI を実行する際に使用するIAMユーザーを作成します。

設定はIAMポリシーで制御するのですが、AWSのベストプラクティスに従って、IAMユーザーに直接ポリシーをアタッチするのではなく、IAMグループを作成して、作成したIAMグループに対してMFAを有効化するためのポリシーをアタッチしていきます

□手順 1-1: [Identity and Access Management(IAM)]サービスの[グループ]メニュー画面で[新しいグループの作成]をクリックします

capture_009_09032020_085018.jpg

□手順 1-2: [グループ名]に任意の名前(ここではMyUsers)を入力し[次のステップ]をクリックします

capture_010_09032020_085048.jpg

□手順 1-3: [ポリシーのアタッチ]画面で、任意のAWS管理ポリシー(ここではPowerUserAccessポリシー)を選択し[次のステップ]をクリックします

capture_012_09032020_085544.jpg

□手順 1-4: 内容を確認し[グループの作成]をクリックします

capture_013_09032020_085551.jpg

□手順 1-5: IAMグループ(MyUsers)が作成されたことを確認します

capture_014_09032020_085609.jpg

□手順 1-6: 続いて[Identity and Access Management(IAM)]サービスの[ユーザー]メニュー画面に移り[ユーザーを追加]をクリックします

capture_029_09032020_095629.jpg

□手順 1-7: [ユーザー名]に任意の名前(ここではcli-user)を入力し[プログラムによるアクセス]にチェックを入れて[次のステップ:アクセス権限]をクリックします

※必要ではないのでチェックを入れていませんが[AWSマネージメントコンソールへのアクセス]にチェックを入れても問題はないと思います

capture_047_09032020_100029.jpg

□手順 1-8: [ユーザーをグループに追加]で先ほど作成したIAMグループを選択し[次のステップ:タグ]をクリックします

capture_048_09032020_100035.jpg

□手順 1-9: 必要に応じてタグを設定し(ここでは何も設定せずに)[次のステップ:確認]をクリックします

capture_049_09032020_100037.jpg

□手順 1-10: 内容を確認し[ユーザーの作成]をクリックします

capture_050_09032020_100040.jpg

□手順 1-11: "成功"のメッセージを確認し[.csvのダウンロード]をクリックして完了です

※ダウンロードした CSVファイル は後ほど使用します

capture_052_09032020_100051.jpg

2. 「スマートフォンデバイス」(←持つ要素)によるMFA(多要素認証)の有効化 (「管理者」側手順)

AWSでは「仮想MFAデバイス」と「AWS Security Token Service (AWS STS)」の仕組みを使う事で「AWS CLI」でも「スマートフォンデバイス」(←持つ要素)でのMFA(多要素認証)を実現することができます

□手順 2-1: 作成したIAMグループ(MyUsers)をクリックします

capture_014_09032020_085609.jpg

□手順 2-2: [アクセス許可]タブをクリックします

capture_015_09032020_085614.jpg

□手順 2-3: [インラインポリシー]の”ここをクリックしてください”部分をクリックします

capture_016_09032020_093219.jpg

□手順 2-4: [カスタムポリシー]にチェックを入れます

capture_017_09032020_093245.jpg

□手順 2-5: [ポリシー名]に任意の名前(ここではMyUsersPolicy)、[ポリシードキュメント]に次の「AWSユーザーガイド」記載の内容を入力して[ポリシー]の適用をクリックします

AWSユーザーガイド - IAM: IAM ユーザーに MFA デバイスの自己管理を許可する
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_iam_mfa-selfmanage.html

MyUsersPolicy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowListActions",
            "Effect": "Allow",
            "Action": [
                "iam:ListUsers",
                "iam:ListVirtualMFADevices"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIndividualUserToListOnlyTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:ListMFADevices"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/*",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToManageTheirOwnMFA",
            "Effect": "Allow",
            "Action": [
                "iam:CreateVirtualMFADevice",
                "iam:DeleteVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ResyncMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ]
        },
        {
            "Sid": "AllowIndividualUserToDeactivateOnlyTheirOwnMFAOnlyWhenUsingMFA",
            "Effect": "Allow",
            "Action": [
                "iam:DeactivateMFADevice"
            ],
            "Resource": [
                "arn:aws:iam::*:mfa/${aws:username}",
                "arn:aws:iam::*:user/${aws:username}"
            ],
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        },
        {
            "Sid": "BlockMostAccessUnlessSignedInWithMFA",
            "Effect": "Deny",
            "NotAction": [
                "iam:CreateVirtualMFADevice",
                "iam:EnableMFADevice",
                "iam:ListMFADevices",
                "iam:ListUsers",
                "iam:ListVirtualMFADevices",
                "iam:ResyncMFADevice"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

このインラインポリシーを適用することによりユーザーは後述するMFAデバイスの登録作業などを以外のオペレーションはMFAなしでは実行できないようになります

□手順 2-6: 「管理者」側手順はこれで終了です

capture_020_09032020_093410.jpg

4. 仮想MFAデバイスの作成 (「ユーザー」側手順)

ここから「AWS CLI v2」を使用する「ユーザー」側の手順です

□手順 4-1: 「AWS CLI v2」の新機能であるaws configure importコマンドを使ってIAMユーザー作成時にダウンロードしたCSVファイルからクレデンシャル情報(アクセスキーの情報)を読み取ります

実行コマンド
aws configure import --csv file://<CSVファイル名>
実行例
[user@workstaion ~]$ aws configure import --csv file://credentials.csv

Successfully imported 1 profile(s)

□手順 4-2: この状態でコマンドを実行するとAccess Deniedとなってしまうことを確認します

実行例
[user@workstaion ~]$ aws s3 ls --proflie "cli-user"

An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

□手順 4-3: aws iam create-virtual-mfa-deviceコマンドを実行して仮想MFAデバイスと共有鍵情報が保存されたQRコードを生成します

--virtual-mfa-device-nameパラメーターに設定する名前はIAMユーザーと同じにしてください

実行コマンド
aws iam create-virtual-mfa-device --virtual-mfa-device-name "<IAMユーザー名>" --outfile <QRコードを出力する任意のパス> --bootstrap-method "QRCodePNG" --profile "<IAMユーザープロファイル名>"
実行例
[user@workstaion ~]$ aws iam create-virtual-mfa-device --virtual-mfa-device-name "cli-user" --outfile .\QRCode.png --bootstrap-method "QRCodePNG" --profile "cli-user"

{
    "VirtualMFADevice": {
        "SerialNumber": "<作成された仮想MFAデバイスのリソースネーム(ARN)>"
    }
}

ここで出力される”仮想MFAデバイスのリソースネーム(ARN)"の値は後ほど使用するのでメモしておきます

AWS管理コンソールからも確認可能です(該当IAMユーザーの[認証情報]タブ)↓

capture_002_20032020_062701.jpg

□手順 4-4: 「Google 認証システム(Google Authenticator)」などをスマートフォンにインストールして先ほど生成した共有鍵情報が保存されたQRコードを読み取ります

App Store - Google Authenticator
https://apps.apple.com/jp/app/google-authenticator/id388497605

Google Play - Google 認証システム
https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2

□手順 4-5: aws iam enable-mfa-deviceコマンドを実行して作成した仮想MFAデバイスの有効化(スマートフォンデバイスとの同期)を行います

実行コマンド
aws iam enable-mfa-device --user-name "<IAMユーザー名>" --serial-number "<仮想MFAデバイスのリソースネーム(ARN)>" --authentication-code1 "<MFAデバイスに表示されている6桁の数字>" --authentication-code2 "<`--authentication-code1`に設定した値の次に表示される6桁の数字>" --profile "<IAMユーザープロファイル名>"
実行例
[user@workstaion ~]$ aws iam enable-mfa-device --user-name "cli-user" --serial-number "<仮想MFAデバイスのリソースネーム(ARN)>" --authentication-code1 "123456" --authentication-code2 "234567" --profile "cli-user"

□手順 4-6: aws sts get-session-tokenコマンドを実行することで有効期限付き(デフォルト1時間)のセッショントークンを取得することができます

実行コマンド
aws sts get-session-token --serial-number "<仮想MFAデバイスのリソースネーム(ARN)>" --token-code <MFAデバイスに表示されている6桁の数字> --profile "<IAMユーザープロファイル名>"
実行例
[user@workstaion ~]$ aws sts get-session-token --serial-number "<仮想MFAデバイスのリソースネーム(ARN)>" --token-code <MFAデバイスに表示されている6桁の数字> --profile "cli-user"

{
    "Credentials": {
        "AccessKeyId": "<アクセスキーID>",
        "SecretAccessKey": "<シークレットアクセスキー>",
        "SessionToken": "<セッショントークン>",
        "Expiration": "<セッショントークンの有効期限(yyyy-MM-ddTHH:mm:ss+00:00)>"
    }
}

□手順 4-7: aws sts get-session-tokenコマンドで得られた値を次の環境変数に設定します

環境変数名 設定する値 説明
AWS_ACCESS_KEY_ID Credentials.AccessKeyIdの値 アクセスキーID
AWS_SECRET_ACCESS_KEY Credentials.SecretAccessKeyの値 シークレットアクセスキー
AWS_SESSION_TOKEN Credentials.SessionTokenの値 セッショントークン

[MacOSやLinux環境での実行例]jqコマンドが使える環境であれば次のようなスクリプトを作成して実行します

Bashの場合
virtualMFADevice = "<仮想MFAデバイスのリソースネーム(ARN)>"
profileName = "cli-user"

echo "MFAデバイスに表示されている6桁の数字を入力してください"
read tokenCode

sessionToken=$(aws sts get-session-token --serial-number "$virtualMFADevice" --token-code "$tokenCode" --profile "$profileName")

export AWS_ACCESS_KEY_ID=$(echo $sessionToken | jq -r .Credentials.AccessKeyId)
export AWS_SECRET_ACCESS_KEY=$(echo $sessionToken | jq -r .Credentials.SecretAccessKey)
export AWS_SESSION_TOKEN=$(echo $sessionToken | jq -r .Credentials.SessionToken)

[Windows環境での実行例]PowerShellのConvertFrom-Jsonコマンドレットを使えばJSONのパースが可能なので次のようなスクリプトを作成して実行します

PowerShellの場合
$virtualMFADevice = "<仮想MFAデバイスのリソースネーム(ARN)>"
$profileName = "cli-user"

$tokenCode = Read-Host "MFAデバイスに表示されている6桁の数字を入力してください"

$sessionToken = $(& aws sts get-session-token --serial-number "$virtualMFADevice" --token-code "$tokenCode" --profile "$profileName" | ConvertFrom-Json)

$env:AWS_ACCESS_KEY_ID=$sessionToken.Credentials.AccessKeyID
$env:AWS_SECRET_ACCESS_KEY=$sessionToken.Credentials.SecretAccessKey
$env:AWS_SESSION_TOKEN=$sessionToken.Credentials.SessionToken

□手順 4-8: この状態で「AWS CLI」を実行し Access Denied などのエラーメッセージが表示されなくなっていれば成功です

※この時--profileオプションの付与は不要です

実行例
[user@workstaion ~]$ aws s3 ls

yyyy-MM-dd HH:mm:ss xxxx
:

5. 特定の接続IPアドレス(←場所の要素)によるMFA(多要素認証)の有効化 (「管理者」側手順)

続いて、特定の接続IPアドレスからのアクセス時のみは、ワンタイムパスワードの入力なしでアクセスできるように設定します。

□手順 5-1: 作成したIAMグループ(MyUsers)をクリックします

capture_014_09032020_085609.jpg

□手順 5-2: [アクセス許可]タブをクリックします

capture_015_09032020_085614.jpg

□手順 5-3: [インラインポリシー]の”ポリシーの編集”部分をクリックします

capture_020_09032020_093410.jpg

□手順 5-4: ポリシードキュメントの ”Condition” 句を次のように修正して[ポリシーの適用]をクリックします

修正前
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
修正後
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                },
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "xxx.xxx.xxx.xxx",
                        "yyy.yyy.yyy.yyy"
                    ]
                }
            }

□手順 5-5: 「管理者」側手順はこれで終了です

6. 「AWS CLI」の実行(「ユーザー」側手順)

再び「AWS CLI」を使用する「ユーザー」側の手順です

□手順 6-1: --profileオプションを付与して「AWS CLI」を実行し、問題なく実行できれば成功です

実行例
[user@workstaion ~]$ aws s3 ls --proflie "cli-user"

yyyy-MM-dd HH:mm:ss  xxxx
:

以上、特定の接続元IPアドレス以外から「AWSコマンドラインインターフェイス(AWS CLI v2)」を実行した際のみMFA(Multi-Factor Authentication)が必要になるようにIAMの設定をした際の手順でした。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?