目次
はじめに
こんにちは、omkです。
Redis6からACLが利用できるようになり、ElastiCacheでも利用できるようになっていますのでこれを使ってみました。
ElastiCache for Redisでは送信中の暗号化を有効にするにあたってRedis Authかユーザーグループでのアクセスコントロール(ACL)を有効するしてアクセスコントロールすることが可能です。
なので暗号化通信を行うためにACLを勉強してみたという経緯になります。
やってみた
前提
PHP:8.0
phpredis:5.3.5
Redis:6.x
PHPが動作するEC2インスタンスを用意します。php-redisを入れておきます。
ElastiCache for Redisクラスター作成
コンパネからElastiCacheクラスターを作成していきますが、まずはユーザーとユーザーグループを作成します。
公式ドキュメントを置いておきます。
https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/red-ug/Clusters.RBAC.html
ナビペの「ユーザー管理」を選択して作成していきます。
アクセス文字列はRedisの操作権限を示す文字列です。今回はとりあえず全権を与えます。
次にユーザーグループを作成します。
「ユーザーグループの管理」から作成していきます。
先程作成したユーザーとデフォルトユーザーのグループを作りました(デフォルトは必須です)。
では最後にElastiCacheクラスターを起動します。
「送信中の暗号化」にチェックを入れ、アクセスコントロールオプションで「ユーザーグループのアクセスコントロール」を選択し、先程作成したグループを割り当てます。
これで作成したらElastiCacheはOKです。
クラスターが完成したらPHPから接続してみます。
redis-cliから接続
PHPサーバから接続するにあたってredis-cliをインストールします。
(AmazonLinux2を使用しているのでextrasからインストールしました)
$ sudo amazon-linux-extras install redis6
では接続します。
$ redis-cli -h {エンドポイント} --tls -p 6379
--tls オプションは必須です。
> ACL LIST
1) "user default on nopass sanitize-payload ~* &* +@all"
2) "user omk-user on #0000000000000000000000000000000000000000000000000000000000000000 #0000000000000000000000000000000000000000000000000000000000000000 ~* &* +@all"
グループに設定したユーザーが確認出来ます。
使用するユーザーとパスワードを指定して認証します。
> AUTH omk-user {パスワード}
OK
> ACL WHOAMI
"omk-user"
認証できました。
権限の確認をしてみます。
> keys *
(empty array)
> set test-key test-value
OK
> keys *
1) "test-key"
> get test-key
"test-value"
操作できます。
ちなみに、Redis上でユーザーは作れないようになっているようです(SETUSERがない)。
> ACL HELP
1) ACL <subcommand> [<arg> [value] [opt] ...]. Subcommands are:
2) LIST -- Show user details in config file format.
3) USERS -- List all the registered usernames.
4) GETUSER <username> -- Get the user details.
5) CAT -- List available categories.
6) CAT <category> -- List commands inside category.
7) GENPASS [<bits>] -- Generate a secure user password.
8) WHOAMI -- Return the current connection username.
9) LOG [<count> | RESET] -- Show the ACL log entries.
10) HELP
11) Prints this help.
phpredisから接続
では簡単なコードを作成しました。
<?php
# 接続情報取得
$redisend = getenv('redis_end');
$redishost = 'tls://' . $redisend;
$redisuser = getenv('redis_user');
$redispass = getenv('redis_user_pass');
# 接続
$redis = new Redis();
$redis->connect($redishost,6379,5,NULL, 0, 0, ['auth' => [$redisuser, $redispass]]);
$value = $redis->get('test-key');
print($value);
?>
環境変数に設定したElastiCacheクラスターのエンドポイント、ユーザー、パスワードを読み込んでphpredisで接続します。
実行してみます。
$ php redis.php
test-value
キーに設定した値が返ってきました。
では、試しにユーザーの設定を変更してget権限を奪います。
on ~* -@all +set
これでsetコマンドしか使えなくなりました。
もう一度実行します。
$ php redis.php
PHP Fatal error: Uncaught RedisException: NOPERM this user has no permissions to run the 'get' command or its subcommand in /home/ec2-user/redis.php:14
Stack trace:
#0 /home/ec2-user/redis.php(14): Redis->get('test-key')
#1 {main}
thrown in /home/ec2-user/redis.php on line 14
アクセスコントロールが正常に機能していることがわかりました。
おわりに
redisでTLS通信できるようになりました。
適切なアクセスコントロールでセキュアにキャッシュクラスターを操作していきましょう。
アーキテクト課のomkです。
AWSについて雑多に取り組んだ内容を発信しています!!