AWS CLIからのMFA(多要素認証)を楽にするツール(aws-mfa)を使ってみた

# AWS CLIからのMFA(多要素認証)を楽にするツール(aws-mfa)を使ってみた

## はじめに
こんにちは、エンジニアの[ogady](https://twitter.com/gadyma)です。
うちの会社では、IAMユーザーのMFAをマストとしています。そうすると、AWS CLIからMFAする手順がめんどくさい。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">aws cliからMFA認証通す時って、クソめんどい。皆さんどうやってるんだろう。そもそもcli用ユーザー作ってmfa無効にするのが正解なのか？</p>&mdash; ogady@アニオタエンジニア (@gadyma) <a href="https://twitter.com/gadyma/status/1182635353372446720?ref_src=twsrc%5Etfw">October 11, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

公式の手順はこれ

- [AWS CLI 経由で MFA を使用してアクセスを認証する](https://aws.amazon.com/jp/premiumsupport/knowledge-center/authenticate-mfa-cli/)

自分で作ろうかとも思ったのですが、良さげなツールを見つけたので試してみました。
`aws-mfa` を使えば、簡単に期限付きのAWSアクセスキーを発行して、AWS CLIからリソースにアクセスできます。

## こんな人向け
- AWS CLIのMFAを毎回公式の方法でやっている
- MFA使うべきなのはわかってるけど運用がめんどくさそうでやっていない

## aws-mfaをインストールする
使うツールはこれ

- **[GitHub - broamski/aws-mfa](https://github.com/broamski/aws-mfa)**


### 1. pip でインストール
```shell-session:
$ pip3 install aws-mfa
```

### 2. 一応インストールされてるか確認

```shell-session:
$ aws-mfa -h
usage: aws-mfa [-h] [--device arn:aws:iam::123456788990:mfa/dudeman]
               [--duration DURATION] [--profile PROFILE]
               [--long-term-suffix LONG_TERM_SUFFIX]
               [--short-term-suffix SHORT_TERM_SUFFIX]
               [--assume-role arn:aws:iam::123456788990:role/RoleName]
               [--role-session-name ROLE_SESSION_NAME] [--force]
               [--log-level {CRITICAL,ERROR,WARNING,INFO,DEBUG,NOTSET}]
               [--setup]

optional arguments:
  -h, --help            show this help message and exit
  --device arn:aws:iam::123456788990:mfa/dudeman
                        The MFA Device ARN. This value can also be provided
                        via the environment variable 'MFA_DEVICE' or the
                        ~/.aws/credentials variable 'aws_mfa_device'.
  --duration DURATION   The duration, in seconds, that the temporary
                        credentials should remain valid. Minimum value: 900
                        (15 minutes). Maximum: 129600 (36 hours). Defaults to
                        43200 (12 hours), or 3600 (one hour) when using '--
                        assume-role'. This value can also be provided via the
                        environment variable 'MFA_STS_DURATION'.
  --profile PROFILE     If using profiles, specify the name here. The default
                        profile name is 'default'. The value can also be
                        provided via the environment variable 'AWS_PROFILE'.
  --long-term-suffix LONG_TERM_SUFFIX, --long-suffix LONG_TERM_SUFFIX
                        The suffix appended to the profile name toidentify the
                        long term credential section
  --short-term-suffix SHORT_TERM_SUFFIX, --short-suffix SHORT_TERM_SUFFIX
                        The suffix appended to the profile name toidentify the
                        short term credential section
  --assume-role arn:aws:iam::123456788990:role/RoleName, --assume arn:aws:iam::123456788990:role/RoleName
                        The ARN of the AWS IAM Role you would like to assume,
                        if specified. This value can also be provided via the
                        environment variable 'MFA_ASSUME_ROLE'
  --role-session-name ROLE_SESSION_NAME
                        Friendly session name required when using --assume-
                        role
  --force               Refresh credentials even if currently valid.
  --log-level {CRITICAL,ERROR,WARNING,INFO,DEBUG,NOTSET}
                        Set log level
  --setup               Setup a new log term credentials section

```

## 基本的な使い方

### 1. IAMの設定を行う
- MFAの有効化(手順は以下を参考)
[AWSでMFA(二段階認証)を有効にする方法を超丁寧に説明するよ - Qiita](https://qiita.com/viptakechan/items/6d19aee635b2ab189e47)

- アクセスキーを発行する

### 2. aws cliの設定を行う
発行したアクセスキーでaws cliの設定を行います。
`aws-mfa`ではプロファイルの命名は **`<プロファイル名>-long-term`の形式** にする必要があります。

```shell-session:
$ aws configure --profile sample-long-term
AWS Access Key ID [None]: XXXXXXXXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]: json
```


デフォルトのリージョンを指定する場合は、上記に加え`-long-term`を付けないプロファイルを作成します。
この時、アクセスキー、シークレットアクセスキーは不要です。

```shell-session:
$ aws configure --profile sample
AWS Access Key ID [None]: 
AWS Secret Access Key [None]: 
Default region name [None]: ap-northeast-1
Default output format [None]: json
```


### 3. aws-mfaを実行する
実行する時は **`-long-term`を付けないプロファイル を指定**します。
また、`--device`オプションを付けて、MFAデバイスのARNを設定します。 

```shell-session:
$ aws-mfa --profile sample --device arn:aws:iam::123456788990:mfa/IAMユーザー名 
INFO - Validating credentials for profile: sample
INFO - Short term credentials section sample is missing, obtaining new credentials.
# ↓MFAコードを入力
Enter AWS MFA code for device [arn:aws:iam::123456788990:mfa/IAMユーザー名] (renewing for 43200 seconds): MFAコード
INFO - Fetching Credentials - Profile: sample, Duration: 43200
INFO - Success! Your credentials will expire in 43200 seconds at: 2019-10-13 18:40:17+00:00
```


aws-mfaは、`-long-term`がついたプロファイルを使ってMFAを行います、期限つきアクセスキーとトークンで `-long-term`がついてないプロファイルを作成してくれます。(すでにある場合は、更新+追記)


```shell-session:~/.aws/credentialsをみてみる
$ cat ~/.aws/credentials
[sample-long-term]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXX

# ここから下は自動生成される。
[sample]
assumed_role = False
aws_access_key_id = XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXX
aws_session_token = XXXXXXXXXXXXXXXXXXXXXXXX
expiration = 2019-10-13 20:52:51
```


これで、今回は`sample`プロファイルを使って、AWS CLIからリソースにアクセスすることができます。
アクセスキーの**有効期限はデフォルト12時間**ですが、**`--duration` オプションで15分〜36時間の範囲で指定できます。**(秒指定:900〜129600)


```shell-session:試しにコマンド打ってみる
$ aws ec2 describe-instances --profile sample --region ap-northeast-1
{
  "Reservations": [
    {
      "Instances": [
        {
          "Monitoring": {
            "State": "disabled"
          },
          "PublicDnsName":""
...
...
```


## いちいち `--device` オプションを指定したくない


**毎回MFAデバイスのARNを指定するのは面倒**なので、credentialsファイルに追記します。

```shell-session:~/.aws/credentialsに追記
$vim ~/.aws/credentials
[sample-long-term]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXX
aws_mfa_device = arn:aws:iam::123456788990:mfa/IAMユーザー名 # ←追記
```

こうすると、実行時にMFAデバイスのARNを指定しなくてもよくなります。

```shell-session:MFAデバイスのARNの指定なしでOK
$ aws-mfa --profile sample
```


## 後書き
コマンド一発でできるので便利。
IAMユーザーの運用については自分の中でベストプラクティスがまだ不明確なのですが、これを使えば **「AWS CLIを使う時めんどくさい」というMFAのハードルを下げられる**ので、どんどん使っていきたいです。

## 参考にしたもの
- [AWS CLI 経由で MFA を使用してアクセスを認証する](https://aws.amazon.com/jp/premiumsupport/knowledge-center/authenticate-mfa-cli/)
- [aws-mfaを利用してawscli上でらくらくMFA(多要素認証)｜株式会社クインテット｜Pando](https://pando.life/qwintet/article/972)