AWS CLI環境でMFAの有効化と、MFAの認証を行う方法

## 概要

AWSに限ったことではありませんが、今どきの個人認証ではMFA（多要素認証）を行うことが一般化しつつあります。

AWSにおいては、AWSマネジメントコンソールにサインインする際にMFAを有効化することができます。

このMFAですが、アクセスキー・シークレットアクセスキーを用いる環境でも有効化できます。なるべくでしたらアクセスキー・シークレットアクセスキーを使わないで運用したいところですが、CLI環境やCDKなど、開発者のPCでアクセスキー・シークレットアクセスキーが必要となる場面は今でも存在します。

本記事では、アクセスキー・シークレットアクセスキーを用いる環境でMFAを有効化する方法について説明します。

## 前提

* CDK用ユーザーのアクセスキー、シークレットアクセスキーは受け取っているものとする
* MFA用のデバイスとして、QRコードを読み取れるカメラ付きのスマートフォン・タブレットを用意してある
* スマートフォン・タブレットには認証用のアプリケーションがインストールされているものとする
    * Google Atuhenticator
    * Microsoft Atuhenticator など
* CDK用のユーザーはAWSマネジメントコンソールを操作する許可は出されておらず、アクセスキー・シークレットアクセスキーを使ったAWS CLIによる操作が中心になるものとする。

## CLI環境でMFAを実行することについて

仮想MFAデバイス登録後のMFA認証は、AWS CLIだけでも可能ですが、一時認証情報の発行依頼の実施と、発行された一時認証情報の登録操作が面倒です。

参考: AWSの記事

https://aws.amazon.com/jp/premiumsupport/knowledge-center/authenticate-mfa-cli/

AWSが述べているMFAの実行方法の概要

1. `aws sts`コマンドを実行して、一時認証情報を取得する
    * JSON形式で一時認証情報が返ってくる 
    * 返ってきたJSONの中に`SessionToken`がある
1. 取得した一時認証情報を環境変数にセットする
    * アクセスキー
    * シークレットアクセスキー
    * 一時認証情報の`SessionToken`

「一時認証情報を取得して、環境変数をセットし直す」操作を実施するのは手間です。一時認証情報の有効期限は12時間でして、もし毎日CLIによる作業を実施するとしたら、毎日（その日の労働時間によっては1日に2回）この作業をする必要があります。

それで、なにか良いツールはないものかと探してみましたら、Pythonのツールで「一時認証情報を取得して、その一時認証情報を適切に設定してくれる」ツールがありました。`aws-mfa`というツールです。

aws-mfa

https://github.com/broamski/aws-mfa

このツールを使うと、以下の方法でMFAが実行できます。公式で紹介されている方法より簡単です。

1. 仮想MFAデバイスでMFAコードを確認する
1. `aws-mfa`コマンドを実行する
1. MFAコードを入力する

本記事では、仮想MFAデバイスの設定を終えたあと、CLIでMFAを実行する際はこの`aws-mfa`を使うことにします。


## 環境

今回のPCの環境は以下を想定しています。

* OSはWindows 10
* Python 3.xがインストール済み、もしくはインストール可能
    * Pythonのツールaws-mfaを使用するため

## 作業

### CLIのインストール

Windows版のCLIをインストールします。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

### CLIの認証情報を設定する

1. PowerShellを起動する
1. `aws configure`コマンドを実行する

アクセスキー、シークレットアクセスキーは必ず指定します。

リージョンは、よく使用するリージョンが決まっているのであれば、指定しておきます。もし指定しない場合、CLI実行時にコマンドラインオプション`--region <リージョン名>`を付ける必要があります。

デフォルトの出力形式については、任意です。

```:aws configure 実行例
> aws configure
AWS Access Key ID [None]: <アクセスキー>
AWS Sercret Access Key [None]: <シークレットアクセスキー>
Default region name [None]: ap-northeast-1
Default output format [None]:
```

### CLIでMFAを有効化する

CLIを使用するユーザーに対し、AWSマネジメントコンソールの操作が許可されていない場合、AWSマネジメントコンソールからMFAを有効化することはできません。

このような場合、CLIでMFAを有効化する必要があります。以下でその方法を説明します。

### 仮想MFAデバイス作成用のQRコードファイルを作成する

以下のコマンドを実行します。実際は1行で入力してください。

```
aws iam create-virtual-mfa-device
--virtual-mfa-device-name <ユーザー名>
--bootstrap-method QRCodePNG
--outfile $HOME/mfa_qr.png
```

コマンドの実行に成功すると、仮想MFAデバイスのARNが表示されます。

```json
{
    "VirtualMFADevice": {
        "SerialNumber": "arn:aws:iam::<AWSアカウントID>:mfa/<ユーザー名>"
    }
}
```

### 仮想MFAデバイス登録用の画像表示

先の操作で作成されたQRコードの画像を表示します。

使用中のPowerShellから開くことが可能です。`start`コマンドを使います。

    start $HOME/mfa_qr.png

または、エクスプローラーや使い慣れた画像ツールで開いてください。

### 仮想MFAデバイスを登録する

表示されたQRコードを仮想MFAデバイスの認証用アプリケーションで読み取り、仮想MFAデバイスの登録を行います。

使用する認証用アプリケーションごとに対応してください。

MFAコードが表示できるようになれば良いです。

### 仮想MFAデバイスを有効化する

以下のコマンドを実行します。実際は1行で入力してください。

```
aws iam enable-mfa-device
--user-name <ユーザー名>
--serial-number arn:aws:iam::<AWSアカウントID>:mfa/<ユーザー名>
--authentication-code1 <1つ目のMFAコード>
--authentication-code2 <2つ目のMFAコード>
```

エラーが返ってこなければ成功です。

### Python 3.xのインストール

Python 3.xがインストール済みの場合は、本節は飛ばしてください。

1. https://www.python.org/downloads/ を開く
1. [Download the latest version for Windows] の下に表示されている`Download Python 3.x.x` ボタンを押下する
1. ダウンロードされたファイル`python-3.x.x-amd64.exe`を実行する
1. インストール時のオプションのうち、`Add Python 3.x to PATH`をチェックする
1. `Install Now`を押下する
1. インストールに成功すると「Setup Successful」と表示される
1. `Close`を押下する

### aws-mfaのインストール

1. 起動中のPowerShellがあれば、そのまま使用する
    * もし起動中のPowerShellがなければ、PowerShellを起動する
1. `pip install aws-mfa`コマンドを実行する
1. 「Successfully installed aws-mfa-<インストール時のバージョン番号>」が表示されたら、インストールに成功している

```:実行例
PS C:\Users\[ユーザー名]> pip install aws-mfa
Collecting aws-mfa
  Using cached aws_mfa-0.0.12-py2.py3-none-any.whl (13 kB)

(中略)

Installing collected packages: aws-mfa
Successfully installed aws-mfa-0.0.12
```

### AWS CLIの認証情報ファイルを編集する

`$HOME/.aws/credentials`（通常は C:\Users\\[ユーザー名]\\.aws\credentials）を直接編集します。

1. [default]のセクション名を[default-long-term]に変更する
1. `aws_mfa_device`を追記する
    * 値は仮想MFAデバイスのARN

```
[default-long-term]
aws_access_key_id = <アクセスキー>
aws_sercret_access_key = <シークレットアクセスキー>
aws_mfa_device = arn:aws:iam::<AWSアカウントID>:mfa/<ユーザー名>
```

## aws-mfaを使ったMFA認証の方法

1. 仮想MFAデバイスでMFAコードを表示する
1. `aws-mfa`コマンドを実行する
1. MFAコードを入力して`Enter`キーを押下する

```
PS C:\Users\[ユーザー名]> aws-mfa
INFO - Validating credentials for profile: default
INFO - Short term credentials section default is missing, obtaining new credentials.
Enter AWS MFA code for device arn:aws:iam::<AWSアカウントID>:mfa/<ユーザー名> (renewing for 43200 seconds): ※MFAコードを入力してEnterキーを押下する※
INFO - Fetching Credentials - Profile: default, Duration: 43200
INFO - Success! Your credentials will expire in 43200 seconds at: xxxxxxxxx
```