今すぐローカル開発環境のアクセスキー/シークレットキーを削除してIAM Roles Anywhereを使いなさい！

タイトルは少し煽りましたが、簡単にできますので、一度検討してみてはいかがでしょうか！


2023/10/25更新：続きをブログに書きました。

https://moritalous.pages.dev/4b1453fbea03b6f3b258

## 環境

前半の手順はUbuntuで行いました。
最後の"証明書をWindowsに保存して管理する"の部分だけWindows 11を使用しました。


## 手順

### 証明書を生成する

AWS IAM Roles Anywhere Credential HelperのGitHubリポジトリに便利なスクリプト（generate-credential-process-data.sh）が用意されています。

https://github.com/aws/rolesanywhere-credential-helper

```console:shell
wget https://raw.githubusercontent.com/aws/rolesanywhere-credential-helper/main/generate-credential-process-data.sh
```

出力先のディレクトリを作成し実行します。

```console:shell
mkdir credential-process-data
bash generate-credential-process-data.sh
```

以下のファイルが生成されます。

```console:tree credential-process-data
credential-process-data
├── client-cert.pem
├── client.conf
├── client-csr.pem
├── client-key.pem
├── root-cert.pem
├── root.conf
└── root-key.pem

0 directories, 7 files
```

:::note
スクリプトの中で以下の処理が行われています。

1. root CAの設定ファイル（root.conf）の作成
1. root CAの証明書とRSAプライベートキーの生成
1. クライアント証明書の設定ファイル（client.conf）の作成
1. クライアント証明書とRSAプライベートキーの生成

証明書の有効期限は1年間です。
:::

### マネジメントコンソールでIAM Roles Anywhereを設定する

1. [IAM Roles Anywhere](https://ap-northeast-1.console.aws.amazon.com/rolesanywhere/home)の管理画面を表示し、`信頼アンカーを作成する`ボタンをクリックします。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/22433c56-0b55-6e86-2738-d8671eab76f9.png)

1. 認証機関 (CA) ソースで`外部証明書バンドル`を選択し、外部証明書バンドルに`root-cert.pem`の値を貼り付けます。`信頼アンカーを作成する`ボタンをクリックします。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/2286e805-7b5e-799f-c801-5ac034abb2ae.png)

1. [IAMロール]の管理画面に遷移し、`ロールを作成`ボタンをクリックします。
1. 信頼されたエンティティタイプを`AWSのサービス`とし、ユースケースは`Roles Anywhere`を選択します。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/34bf24c4-b52f-3b5a-af65-8aa6c8da64e0.png)

1. 任意のポリシーを追加します。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/246da6f3-5b26-8f60-3993-7aed2e88614a.png)

1. ロールに名前をつけ、`ロールを作成`ボタンをクリックします。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/5883e81d-d42c-621a-9829-a69c362566bf.png)

1. [IAM Roles Anywhere](https://ap-northeast-1.console.aws.amazon.com/rolesanywhere/home)の管理画面に戻り、`プロファイルを作成`ボタンをクリックします。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/4ed4ca0f-0b7e-0ee9-14bf-43dc007c9795.png)

1. プロファイルの名称を入力し、ロールに先程作成したIAMロールを選択し、`プロファイルを作成`ボタンをクリックします。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/41ce5bc1-8ddd-6c9c-5a7d-79be6607de28.png)

1. 以下のARNをメモします。
    * 信頼アンカーのARN
    * プロファイルのARN
    * IAMロールのARN

### クレデンシャルヘルパーツールをダウンロードする

[こちら](https://docs.aws.amazon.com/ja_jp/rolesanywhere/latest/userguide/credential-helper.html)にOSごとのヘルパーツールが用意されているので、OSに合わせてダウンロードします。

```console:shell
wget https://rolesanywhere.amazonaws.com/releases/1.1.1/X86_64/Linux/aws_signing_helper -O ~/.local/bin/aws_signing_helper
chmod +x ~/.local/bin/aws_signing_helper
```

ヘルプを表示して見ます。

```console:shell
aws_signing_helper -h
```
```text:shell（出力）
A tool that utilizes certificates and their associated private keys to 
sign requests to AWS IAM Roles Anywhere's CreateSession API and retrieve temporary 
AWS security credentials. This tool exposes multiple commands to make credential 
retrieval and rotation more convenient.

Usage:
  aws_signing_helper [command] [flags]
  aws_signing_helper [command]

Available Commands:
  completion            Generate the autocompletion script for the specified shell
  credential-process    Retrieve AWS credentials in the appropriate format for external credential processes
  help                  Help about any command
  read-certificate-data Diagnostic command to read certificate data
  serve                 Serve AWS credentials through a local endpoint
  sign-string           Signs a fixed string using the passed-in private key (or reference to private key)
  update                Updates a profile in the AWS credentials file with new AWS credentials
  version               Prints the version number of the credential helper

Flags:
  -h, --help   help for aws_signing_helper

Use "aws_signing_helper [command] --help" for more information about a command.
```


### 一時認証情報を生成する

ヘルパーツールの`credential-process`コマンドで一時認証情報が生成できます。

```console:shell
export TRUST_ANCHOR_ARN=arn:aws:rolesanywhere:ap-northeast-1:999999999999:trust-anchor/...
export PROFILE_ARN=arn:aws:rolesanywhere:ap-northeast-1:999999999999:profile/...
export ROLE_ARN=arn:aws:iam::999999999999:role/...

aws_signing_helper credential-process \
     --certificate credential-process-data/client-cert.pem \
     --private-key credential-process-data/client-key.pem \
     --trust-anchor-arn ${TRUST_ANCHOR_ARN} \
     --profile-arn ${PROFILE_ARN} \
     --role-arn ${ROLE_ARN}
```
```text:shell（出力）※整形してます
{
  "Version":1,
  "AccessKeyId":"",
  "SecretAccessKey":"",
  "SessionToken":"",
  "Expiration":"2023-10-14T13:52:35Z"
}
```

一時認証情報の取得ができました。AWS CLIやSDKで使用するためにはconfigファイルに以下のように設定を行います。

```text:~/.aws/config
[default]
credential_process = aws_signing_helper credential-process 
  --certificate <<client-cert.pemの絶対パス>>
  --private-key <<client-key.pemの絶対パス>>
  --trust-anchor-arn <<信頼アンカーのARN>>
  --profile-arn <<プロファイルのARN>>
  --role-arn <<ロールのARN>>
```

これで、IAM Roles Anywhereであることを意識しないで利用できます。

## IMDSv2の仕組みで認証情報を取得する

ヘルパーツールに用意されている`serve`コマンドを使用すると、IMDSv2の仕組みで認証情報を取得することが可能です。

`~/.aws/config`ファイルを削除します。

```console:shell
rm ~/.aws/config
```

この状態では認証情報がないことを確認

```console:shell
aws sts get-caller-identity
```
```text:shell（出力）
Unable to locate credentials. You can configure credentials by running "aws configure".
```

`serve`を実行

```console:shell1
aws_signing_helper serve \
     --certificate credential-process-data/client-cert.pem \
     --private-key credential-process-data/client-key.pem \
     --trust-anchor-arn ${TRUST_ANCHOR_ARN} \
     --profile-arn ${PROFILE_ARN} \
     --role-arn ${ROLE_ARN}
```

```console:shell1（出力）
2023/10/14 13:10:10 Local server started on port: 9911
2023/10/14 13:10:10 Make it available to the sdk by running:
2023/10/14 13:10:10 export AWS_EC2_METADATA_SERVICE_ENDPOINT=http://127.0.0.1:9911/
```

別のターミナルを立ち上げ、IMDSv2のエンドポイントURLを変更します。

```console:shell2
export AWS_EC2_METADATA_SERVICE_ENDPOINT=http://127.0.0.1:9911/
```

この状態で認証情報が取得できることを確認します。

```console:shell2
aws sts get-caller-identity
```
```text:shell2（出力）
{
    "UserId": "...",
    "Account": "999999999999",
    "Arn": "arn:aws:sts::999999999999:assumed-role/..."
}
```

:::note
`~/.aws/config`に記述する方法で困らない気もしますが、なんとなくおしゃれ（？）
:::

### 証明書をWindowsに保存して管理する（macもできるはず）

今回、一番やりたかったのがこれです。

証明書で認証情報を生成できるようになりましたが、**証明書の管理が超重要**です。

どこに置くか悩むぐらいなら、OSに管理を任せましょう！

1. PKCS #12形式のファイルを作成

    Windowsで取り込めるフォーマットのファイルを作成します。

    ```console:shell
    openssl pkcs12 -export -in credential-process-data/client-cert.pem -inkey credential-process-data/client-key.pem -out credential-process-data/client-pkcs12.pfx
    ```
    パスワードの指定も可能ですので、必要に応じて設定しましょう。
    ```console:shell（出力）
    Enter Export Password:
    Verifying - Enter Export Password:
    ```

1. 作成した`client-pkcs12.pfx`をWindowsにコピーし、ダブルクリックでインポートウィザードを起動します。

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/d0205eee-5d48-a635-f80f-7551bd78b5d0.png)
    
    ウィザードに従いインポートします。

1. `%USERPROFILE%`にWindows用のヘルパーツール（aws_signing_helper.exe）を配置します。
1. `.aws/config`を作成

    証明書はWindowsが管理する場所から自動で使用されるので`--certificate`と`--private-key`は指定不要です。

    ```text:.aws/config
    [default]
    credential_process = aws_signing_helper credential-process --trust-anchor-arn <<信頼アンカーのARN>> --profile-arn <<プロファイルのARN>> --role-arn <<ロールのARN>>
    ```

    :::note warn
    Windowsの場合は改行があるとうまくいきませんでした。
  :::

これで証明書を指定せずにIAM Roles Anywhereが使用できるようになりました。

## まとめ

やってみると難しくありませんでした。

アクセスキー/シークレットキーが手元になければ、そもそも流出の心配もありませんので、オススメです。

## 課題

証明書の失効が上手くいかない。。
これでは本番運用はムツカシイ