【Amazon ElastiCache for Redis】3種の方法でログインしてみた

# サマリ
## この記事で得られること
* Amazon ElastiCache for Redis(以下、ElastiCache）のログイン方法を理解できる
* 特にIAM認証のログイン方法がわかる（本記事公開時点でほかの記事があまりない）

## 読むのにかかる時間
10分

# ElastiCacheのログイン方法
※本章は[ElastiCacheの認証と認可ページ](https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/red-ug/auth-redis.html)のサマリ

## ログイン方法1：Redis AUTHによる認証
ユーザという概念なしに、パスワードのみでElastiCacheへログインする方法。
詳細は[Redis AUTH コマンドによる認証](https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/red-ug/auth.html)、[redis AUTH](https://redis.io/commands/auth/)を参照。
Redis自体が以前はアクセス制御を提供していなく、ユーザという概念がなかった。
現在は、ユーザの概念があるため、RBACが主流になっていくと考えられる。

## ログイン方法2-1：RBAC＋パスワード認証
Redis6.0以降では、Redis AUTH認証の代わりにロールベースのアクセス制御 (RBAC) を利用可能。
AUTH認証との違いは以下の通り。
* フルアクセスだけでなく、細かな権限制御も可能
* ユーザの概念により、ユーザに対して権限付与が可能

RBACの利用に加えて、パスワードでの認証がこの項目でのログイン方式。

## ログイン方法2-2：RBAC＋IAM認証
認証方法2-1で説明したRBACの利用に加えて、IAM認証での認証である。
Redis7以上の場合、IAM認証を利用可能。
認証をパスワードではなく、IAM（有効期間が短いIAM認証トークン）に任せることにより、セキュリティの向上が見込まれる。
また、パスワードがないため、パスワードのローテーションも不要となる。

# 実際にログインしてみた
## 事前準備
* EC2サーバ
    * redis-cliのインストールは[クラメソさんのブログ](https://dev.classmethod.jp/articles/install-redis-cli/)参照
        * OS：Amazon Linux 2023
        * redis-cliのバージョン： 7.2.4
* ElastiCache（Redis AUTH有効なもの）
* ElastiCache（RBAC有効なもの）
※VPCなどは事前に用意


## Redis AUTH コマンドによる認証
ElastiCacheの設定は以下。
![RedisAUTH設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759531/d918a73b-7d29-6beb-1551-73732bb57fe9.png)


以下の通りログイン実施。
```bash:command1（対話型でのログイン）
$ redis-cli -h master.auth-redis.3mpbix.apne1.cache.amazonaws.com --tls -p 6379
master.auth-redis.3mpbix.apne1.cache.amazonaws.com:6379> keys *
(error) NOAUTH Authentication required.
master.auth-redis.3mpbix.apne1.cache.amazonaws.com:6379> auth <AUTHトークン>
OK
master.auth-redis.3mpbix.apne1.cache.amazonaws.com:6379> keys *
(empty array)
master.auth-redis.3mpbix.apne1.cache.amazonaws.com:6379> acl whoami
"default"
```

```bash:command2（環境変数でのログイン）
$ export REDISCLI_AUTH=<AUTHトークン>
$ printenv REDISCLI_AUTH
<AUTHトークン>
$ redis-cli -h master.auth-redis.3mpbix.apne1.cache.amazonaws.com --tls -p 6379
master.auth-redis.3mpbix.apne1.cache.amazonaws.com:6379> keys *
(empty array)
master.auth-redis.3mpbix.apne1.cache.amazonaws.com:6379> acl whoami
"default"
```

## RBAC＋パスワード認証
ElastiCacheの設定は以下。
![RedisRBAC設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759531/87c0dc4e-e4de-3bb4-660e-f08963006031.png)
![RBACユーザ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759531/8430b541-4cb7-669a-3314-f9b5f5a0bab5.png)


以下の通りログイン実施。
```bash:command1（対話型でのログイン）
$ redis-cli -h master.rbac-redis.3mpbix.apne1.cache.amazonaws.com --tls -p 6379
AUTH failed: WRONGPASS invalid username-password pair or user is disabled.
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> auth pass-user <パスワード>
OK
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> keys *
(empty array)
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> acl whoami
"pass-user"
```

```bash:command2（環境変数でのログイン）
$ export REDISCLI_AUTH=<パスワード>
$ printenv REDISCLI_AUTH
<パスワード>
$ redis-cli -h master.rbac-redis.3mpbix.apne1.cache.amazonaws.com --tls -p 6379 --user pass-user
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> keys *
(empty array)
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> acl whoami
"pass-user"
```

## RBAC＋IAM認証
ElastiCacheの設定は「RBAC＋パスワード認証」と同等。
追加で以下のIAMポリシーをEC2のIAMロールへ付与。

```json:IAMポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "elasticache:Connect"
            ],
            "Resource": [
                "<レプリケーショングループのARN>",
                "<ユーザのARN>"
            ]
        }
    ]
}
```

また、追加で以下のページの通り、デモアプリをインストール。
[デモアプリのレポジトリ](https://github.com/aws-samples/elasticache-iam-auth-demo-app)

以下の通りログイン実施。
```bash:command1（対話型でのログイン）
$ java -cp target/ElastiCacheIAMAuthDemoApp-1.0-SNAPSHOT.jar \
        com.amazon.elasticache.IAMAuthTokenGeneratorApp \
        --region ap-northeast-1 \
        --replication-group-id rbac-redis \
        --user-id iam-user
<IAM認証トークン>
$ redis-cli -h master.rbac-redis.3mpbix.apne1.cache.amazonaws.com --tls -p 6379
AUTH failed: WRONGPASS invalid username-password pair or user is disabled.
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> auth iam-user <IAM認証トークン>
OK
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> keys *
(empty array)
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> acl whoami
"iam-user"
```

```bash:command2（環境変数でのログイン）
$ java -cp target/ElastiCacheIAMAuthDemoApp-1.0-SNAPSHOT.jar \
        com.amazon.elasticache.IAMAuthTokenGeneratorApp \
        --region ap-northeast-1 \
        --replication-group-id rbac-redis \
        --user-id iam-user
<IAM認証トークン>
$ export REDISCLI_AUTH="<IAM認証トークン>"
$ printenv REDISCLI_AUTH
<IAM認証トークン>
$ redis-cli -h master.rbac-redis.3mpbix.apne1.cache.amazonaws.com --tls -p 6379 --user iam-user
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> keys *
(empty array)
master.rbac-redis.3mpbix.apne1.cache.amazonaws.com:6379> acl whoami
"iam-user"
```

# まとめ
ElastiCache for Redisの3種のログイン方法にてredis-cliによるログインを実施した。
それぞれ対話型のログインと認証情報を環境変数に保持したログインができることを確認した。
AuroraのIAM認証は、AWS CLIで認証情報を取得できるが、ElastiCacheは現時点では非対応だと思われる。
代わりに、「署名バージョン 4 の署名プロセス」を用いたコード例やデモアプリが提供されているため、今回はデモアプリを利用してIAM認証トークンを取得した。
調べた限りでは、Javaと[Go](https://github.com/build-on-aws/aws-redis-iam-auth-golang)のサンプルコードがあるが、それ以外の言語では開発が必要となる。

以上を踏まえて、各認証方法のユースケースは以下の通りと考える。

| ログイン方法 | メリデメ・ユースケース |
|:-:|:-:|
| Redis AUTHによる認証 | パスワードのみでログインできるが、フルアクセスとなり権限制御不可。旧来の運用を行う場合に採用可能性あり。原則、RBACに移行したほうがよい。 |
| RBAC＋パスワード認証 | ユーザごとに権限制御が可能だが、Redis AUTHと同様にパスワードの管理が必要。第一選択肢はこの認証となることが多いと考える。 |
| RBAC＋IAM認証 | ユーザごとに権限制御が可能、かつパスワード管理が不要。ただし、ライブラリが対応していない場合がある。署名プロセスの仕様やサンプルコードを読んでIAM認証トークンの取得を自前で開発できる場合は採用可。 |