Elasticache Redisを構築する上での注意点

# はじめに
今回業務にてAWS Elasticache Redisを構築する機会があり、構築していく中でつまづいた点がいくつかあったのでみなさまのご参考までに備忘録として残していきます。
# 主な注意点
- クラスターモード
- パスワード認証

# クラスターモードとは
### クラスターモードの説明の前に前提知識

用語 | 説明
-- | --
Redisクラスター | 単一または複数のシャードで構成されるグループ。Redisにアクセスする際のエンドポイントを提供する。
シャード | 	プライマリノード(1個) + レプリカノード(0-5個)で構成されるノードグループ。Redisクラスター内に、最低1つ以上存在する。
プリライマリノード | 読み取り/書き込み両方可能なノード。シャード1つにつき、必ず1個作成される。
レプリカノード | 読み取りのみ可能なノード。シャード1つにつき、0-5個のいずれかで作成可能。マルチAZを有効化する場合、最低1個以上作成する必要がある。


ここでクラスターモードとは、複数のシャードを持てるという意味です。つまり複数のプライマリノードを持てることからスケールアウトを可能にするということです。次にクラスターモードの有無での違いについて確認します。

# クラスタモードの有無の違い
クラスタモードを無効化にするとシャードが一つしか持てません。つまりプライマリノードが一つしか持てないので、Redisへの書き込み/読み取り負荷が増大した場合にはスケールアップ（プライマリモードのインスタンスタイプを上げる）することしかできません。またAZ障害が原因でプライマリノードがダウンした場合に、代わりのプライマリノードが存在しないため同じシャード内のレプリカノードを昇格させることで復旧をします。しかしこの復旧作業中はプライマリノードが０の状態であるためその間は書き込みができません。

そこでクラスタモードを有効化にすると、AZ障害が原因でプライマリノードがダウンした場合に、別のシャード内のプライマリノードが生きているのでプライマリノードが1以上存在することを担保できます。これがクラスタモードのメリットだと言えます。

# パスワード認証
ここではパスワード認証を設定する上で注意点などを記述していきます。まずRedisの認証方法としてパスワード認証と認証トークンがありますが今回はパスワード認証に焦点を当てて説明したいと思います。

パスワード認証とは、自身で作成したユーザーでredisにログインできるものです。そのユーザーを作成するにあたってステップがあり、「ユーザー管理」でユーザーを作成する→「ユーザーグループの管理」で作成したユーザーでグループを作成する→redisとユーザーグループを関連づける。となります。ここから一つ一つ見ていきます。

### ユーザー管理
ユーザーを作成していくにあたって注意すべきポイントはユーザー名とアクセス文字列です。
まずユーザー名の注意点としては、後にユーザーグループを作成するにあたって複数のユーザーを選択するときにユーザー名が「default」であるユーザーを必ず一つ選ばなければなりません。この制約で注意しないといけないのが後述する認証によるセキュリティです。
またアクセス文字列とは、ユーザーが実行できるコマンドと、ユーザーが操作できるキーを定義できます。

### ユーザーグループ
ここでの注意点は先ほども書いた通り、ユーザー名が「default」であるユーザーを必ず一つ選ばないといけないということです。

# 認証によるセキュリティ
### ログイン方法
まずはログイン方法について記述したいと思います。経路としては私はパブリックサブネットに踏み台をおいてそこからRedisにログインをしています。コマンドとしては以下の通りです。

```
sudo -iu ec2-user
# ログインにはredis-cliが必要なためurlを参考にインストールしてください(https://penpen-dev.com/blog/ec2-redis/)
sudo amazon-linux-extras install epel -y
sudo yum install gcc jemalloc-devel openssl-devel tcl tcl-devel -y
sudo wget http://download.redis.io/redis-stable.tar.gz
sudo tar xvzf redis-stable.tar.gz
cd redis-stable
sudo make BUILD_TLS=yes

#ログイン
src/redis-cli -u "redis://ユーザー名:パスワード@redisエンドポイント:6379/0" --tls
```
### ユーザーを二つ作り、セキュリティー強化
ユーザーは二つ作成しています。「default」と「通常ユーザー」です。
「default」はパスワード認証なしで「通常ユーザー」はパスワード認証ありです。
理由としては、まずユーザーグループを作成するにあたってUserNameがdefaultであるユーザーが一つ必ず必要です。
またもう一つの理由として、踏み台で接続確認を行ったときに、接続にエンドポイント・ユーザー名・パスワードを使用した際にパスワードが間違っていた場合にエンドポイントがあっていれば、UserNameがdefaultであるユーザーでログイン出来てしまう仕様になっていました。そこでdefaultの権限を絞って作成することで万が一defaultユーザーでのログインが出来てもDB操作を防ぐようにしています。



```
[ec2-user@ip-10-0-xx-xx redis-stable]$ src/redis-cli -u "redis://ユーザー名:パスワード@redisエンドポイント:6379/0" --tls
Warning: Using a password with
'-u' option on the command line interface may not be safe
AUTH failed: WRONGPASS invalid username-password pair or user is disabled. 
redisエンドポイント:6379>ACLWHOAMI
(error) NOPERM this user has no permissions to run the 'aci|whoami' command
redisエンドポイント:6379>
```
↑パスワードが間違った場合にdefaultユーザーでログインできるがコマンドの権限がない状態

```
[ec2-user@ip-10-0-34-66 redis-stable]$ src/redis-cli -u "redis://ユーザー名:パスワード@redisエンドポイント:6379/0" --tls
Warning: Using a password with
'_a' or '-u' option on the command line interface may
clustercg.test-backend2-redisエンドポイント:6379>ACLWHOAMI
"ユーザー名"
```
↑パスワードがあっていればACLコマンドが使用でき、test-redis-userでログイン出来ている。

# まとめ
今回はRedisを構築する上での注意点について記述しました。また至らない部分が多々見受けられると思いますので、ご教授よろしくお願いいたします。