AWSのMFA(多要素認証)バッチを作ってみた

本記事は「 [TTDC Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ttdc) 」 11日目の記事です。

# 概要 <!-- omit in toc -->
今回はWindows環境でMFAを行うためのバッチファイルについて紹介します。
- バッチファイルを起動した後、セッショントークンコード(6桁の数字)入力
- AWS CLIにてセッショントークンコード(=認証情報)を取得

※本記事では、AWS CLIのインストール手順を含みません

# はじめに

近年データをAWS等のクラウド上で管理する状況が増えていますが、データは機密性が高いものが多く、セキュアな管理が求められています。
またセキュリティ対策の一つとして、MFAを前提としたサービスへのアクセスが必要となるケースがあります。
今回は、AWSのIAMユーザーがAWS CLIコマンドを使用してAWSサービスにアクセスする場合に、事前にMFAを行い一時的な認証情報を取得する
バッチファイルの詳細と、実行手順について説明します。バッチファイルで入手した認証情報を環境変数に設定することで、AWS CLIコマンドによるAWSリソースへのアクセスが可能となります。

# 検証条件
- 環境
  Windows11

- 前提条件
  - AWSのIAMユーザー登録(MFA)
  - AWS CLIのダウンロードおよび設定

  :::note info
  上記2項目は事前に準備をしておいてください。
  :::
# MFAとは？
MFA(多要素認証) は、ユーザー名とパスワードに加えて保護を強化できる [AWS IAM](https://aws.amazon.com/jp/iam/features/mfa/) の機能です。
MFAが有効になっているときは、ユーザーが AWS マネジメントコンソールにサインインする際、ユーザー名とパスワード (第 1 の要素、つまりユーザーが知っているもの) の他に、
MFAデバイスからの認証コード (第 2 の要素、つまりユーザーが持っているもの) の入力が求められます。
このように複数の要素を組み合わせることによって、AWSアカウントのセキュリティが強化されます。

# 全体構成
全体の構成としては、同じディレクトリ配下に、`mfa.bat`と`setting.ini`の2種類のファイルを配置してください。
```
.
├── mfa.bat
├── setting.ini
```
  - `mfa.bat`は、MFAを通すためのバッチファイルです。セッショントークンコードに6桁の数字を入力すると、自動的にAWS CLIコマンドが実行され、一時的な認証情報を取得することができます。一時的な認証情報は、`temp.json`に出力されます
  - `setting.ini`は、バッチを実行するために必要な設定ファイルです。あらかじめ、下記2項目について設定が必要となります
    1. MFAが有効になっているIAMユーザーのARN情報
    2. セッショントークンを有効にする制限時間
# 事前準備
設定ファイル(`setting.ini`)の詳細を下記に示します。
```
(setting.ini)
; ARN
ARN=arn:aws:iam::123456789012:mfa/hogehoge

; Duration Seconds
DurationSeconds=43200
```
`mfa.bat`を実行する前に、下記項目について設定内容の書き換えが必要となります。
  1.  ARN
  MFAが有効になっているIAMユーザーのARN情報を書き換えます。リソースを所有し、ハイフンがない AWS アカウントのIDを入力します(※例は`123456789012`)
  `:mfa/hogehoge`の`hogehoge`にはIAMユーザー名を設定する必要があります。
  2. Duration Seconds
  セッショントークンを有効にする制限時間を秒単位で入力します。例は「43200(=12時間)」となっています。
  なお、制限時間の上限は「129600(=36時間)」となっています。

上記2項目の書き換えが完了したら、`setting.ini`ファイルを保存します。

# MFAバッチ
MFAを通すためのバッチファイル(`mfa.bat`)です。セッショントークンコードを入力し、認証に成功したときのみ、一時的な認証情報を取得することができます。一時的な認証情報は、`mfa.bat`,`setting.ini`と同じ階層に`temp.json`が出力されます。セッショントークンコードが誤って入力された場合は`temp.json`に何も書き込まれていないファイルが出力されるため、その場合はもう一度バッチを起動してバッチファイルを再度実行してください。

```
(mfa.bat)
@echo off

rem 設定情報の読み込み
setlocal enabledelayedexpansion

for /f "tokens=1,* delims==" %%a in (setting.ini) do (
    set %%a=%%b
)

rem 認証情報の取得
set /p mfa="ワンタイムパスワードを入力してください: "
aws sts get-session-token --duration-seconds %DurationSeconds% --serial-number %ARN% --token-code !mfa! --profile default --output json > temp.json

endlocal

```

<br>
上記バッチファイルのコードについて、詳細を説明します。

```
@echo off
```
バッチファイルにおいて、コマンドプロンプト上に実行中のコマンドを非表示にするコードです。
<br>

```
rem 設定情報の読込
setlocal enabledelayedexpansion

for /f "tokens=1,* delims==" %%a in (setting.ini) do (
    set %%a=%%b
)
```
カレントディレクトリに記載した設定ファイルを読み込むためのコードです。
`setlocal enabledelayedexpansion`は[遅延環境変数](https://qiita.com/tana_tomo_1025/items/7f824a154f004f610386)といい、変数の値を置き換えるタイミングを変えることができます。
実際にそのコードが実行されるべきタイミングで値を置き換えるために必要な宣言となっています。
<br>
```
aws sts get-session-token --duration-seconds %DurationSeconds% --serial-number %ARN% --token-code !mfa! --profile default --output json > temp.json
```
今回使用するAWS CLIコマンドは上記の`get-session-token`コマンドになります。<br>

- `aws sts get-session-token`は、AWSのCLIコマンドで、STS(Security Token Servise)を通じて一時的なセッショントークンを取得するために使用します。
  このトークンは、指定した時間内でAWSサービスにアクセスするために使用します
- `--duration-seconds %DurationSeconds%`は、取得したセッショントークンの有効期限を指定します。`setting.ini`ファイルで有効期限の設定を変更することができます
- `--serial-number %ARN%`は、MFAデバイスのARN(Amazon Resource Name)を指定します。`setting.ini`ファイルでARNの設定を変更することができます
- `--token-code !mfa!`は、MFAデバイスから取得した一時的なセッショントークンコードを指定します。!mfa!はバッチファイルを実行する際にMFAデバイスから入力されたセッショントークンコードを受け取ります。
- `--profile default`は、AWS CLIが使用するプロファイルを指定します。defaultは設定されているAWSのプロファイル(AWSのアクセスキー、シークレットキー、リージョン設定など)を使用することを指しています。
- `--output json > temp.json`は、AWS CLIコマンドの実行結果をjson形式で出力する設定になります。今回の場合は、`temp.json`に一時的な認証情報が出力されます。

# バッチ実行手順
今回の手順は、同じディレクトリ配下に`mfa.bat`と`setting.ini`が配置されている状態が前提条件となります。
1. MFAバッチ(`mfa.bat`)をダブルクリックします
1. コマンドプロンプトが立ち上がり、`ワンタイムパスワードを入力してください: "`と表示されるので、6桁のセッショントークンコードの数字を入力します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945032/38c8aac6-2786-f4db-296d-404e14b2745e.png)
1. コマンドプロンプトが自動で閉じられた後、`mfa.bat`と`setting.ini`と同じ階層に`temp.json`ファイルが出力されていることを確認します。出力例は下記参照。

```
<temp.jsonの出力例>
{
    "Credentials": {
        "SecretAccessKey": "secret-access-key",
        "SessionToken": "temporary-session-token",
        "Expiration": "expiration-date-time",
        "AccessKeyId": "access-key-id"
    }
}
```
上記手順で取得した一時的な認証情報(`temp.json`)を使用して[環境変数を設定](https://repost.aws/ja/knowledge-center/authenticate-mfa-cli)すると、AWSのリソースへのアクセスが可能となります。

### **注意事項**
:::note warn
誤ったセッショントークンコードを入力した場合
:::

誤ったセッショントークンコードを入力した場合は、`temp.json`が空のファイルで出力されるため、その場合はもう一度MFAバッチ(`mfa.bat`)を実行してください。

# あとがき
今回の記事が、Qiita初投稿になります。読みにくい部分があればご容赦ください。
ご一読ありがとうございました。<br>