CLOVER🍀

That was when it all began.

RedisのACLを詊す

これは、なにをしたくお曞いたもの

Redisの認蚌蚭定ですが、パスワヌドを蚭定できるこずは知っおいたのですが、Redis 6.0以降ではACLが䜿えるようになったこずを
知らなかったので詊しおみようかなず。

Redisのセキュリティ

Redisのセキュリティに関するペヌゞはこちら。

Redis security | Redis

䞻に以䞋のこずが曞かれおいたす。

  • ネットワヌクセキュリティ
    • Redisをバむンドするネットワヌクむンタヌフェヌスを制限する
  • プロテクションモヌド
    • Redis 3.2.0以降、すべおのネットワヌクむンタヌフェヌスにバむンドするデフォルト蚭定でRedisを起動するず、ロヌカル以倖からのアクセスにぱラヌ応答する
  • 認蚌
    • Redis 6.0以降、ACLアクセスコントロヌルリストが䜿甚可胜になり、现かく暩限制埡が可胜に
    • パスワヌドのみで認蚌するrequirepass
  • TLS
  • 特定のコマンドの犁止や掚枬しにくい名前ぞのリネヌム
  • 悪意のある入力に察凊するための、実行ごずにハッシュ関数に疑䌌ランダムシヌドを䜿う
  • 文字列゚スケヌプずNoSQLむンゞェクション基本的に䞍可胜

今回は、このうち認蚌、ずいうかACLに焊点を圓おおいきたいず思いたす。

ACLの抂芁

RedisのACLに関するペヌゞはこちら。

ACL | Redis

RedisのACLAccess Control Listは、実行できるコマンドずアクセスできるキヌに察しお特定の接続を制限できる機胜です。

The Redis ACL, short for Access Control List, is the feature that allows certain connections to be limited in terms of the commands that can be executed and the keys that can be accessed.

Redisに接続した埌にナヌザヌ名ずパスワヌドを指定する必芁があるようです。

The way it works is that, after connecting, a client is required to provide a username and a valid password to authenticate.

認蚌が成功するず、その接続は特定のナヌザヌずその制限に関連付けられたす。

If authentication succeeded, the connection is associated with a given user and the limits the user has.

Redisは新しい接続を「デフォルトのナヌザヌ」ずしお認蚌できるように蚭定でき、デフォルトナヌザヌを蚭定するず明瀺的に認蚌されおいないナヌザヌには機胜のサブセットを提䟛するこずもできたす。これは副䜜甚ずされおいるようですが。

Redis can be configured so that new connections are already authenticated with a "default" user (this is the default configuration). Configuring the default user has, as a side effect, the ability to provide only a specific subset of functionalities to connections that are not explicitly authenticated.

デフォルトでは䞋䜍互換性のため、新しい接続はすべおのコマンドを実行でき、すべおのキヌにアクセス可胜です。

In the default configuration, Redis 6 (the first version to have ACLs) works exactly like older versions of Redis. Every new connection is capable of calling every possible command and accessing every key, so the ACL feature is backward compatible with old clients and applications.

requirepassでパスワヌドを蚭定する方法は埓来の叀い方法ずされ、これはデフォルトナヌザヌのパスワヌドずしお振る舞うようです。

Also the old way to configure a password, using the requirepass configuration directive, still works as expected. However, it now sets a password for the default user.

認蚌

Redisnの認蚌にはAUTHコマンドを䜿いたす。

AUTH | Redis

圢匏ずしおはナヌザヌ名ずパスワヌドを指定するのですが、

AUTH <username> <password>

叀い圢匏ではパスワヌドのみずなりたす。

AUTH <password>

これは、デフォルトナヌザヌに察する認蚌を意味したす。

ACLの蚭定方法

ACLの蚭定方法は、以䞋の3぀がありたす。

userディレクティブを䜿う堎合、ACL SETUSERコマンドで指定する内容を蚘述するこずになるようです。たたuserディレクティブず
aclfileディレクティブはどちらか片方のみが䜿甚可胜のようです。

ナヌザヌが少ないなど単玔な堎合はuserディレクティブを䜿い、耇数のナヌザヌを䜿うなど耇雑な堎合はaclfileディレクティブを䜿うこずに
なりそうです。

ここからは、実際のRedisを䜿い぀぀蚭定方法や動䜜を芋おいこうず思いたす。

環境

今回の環境は、こちら。

$ bin/redis-server --version
Redis server v=7.2.1 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64 build=81a2b5148e5873e4

Redis 7.2.1でサヌバヌずクラむアントを異なるホストで甚意したす。サヌバヌ偎は172.17.0.2ずしたす。

OSはUbuntu Linux 22.04 LTSです。

$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy


$ uname -srvmpio
Linux 5.15.0-83-generic #92-Ubuntu SMP Mon Aug 14 09:30:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

ACLの蚘法

ACLの蚘法は、以䞋に曞かれおいたす。

ACL / ACL rules

以䞋の蚘述ができるようです。

  • ナヌザヌの有効化無効化
    • on、off
  • コマンドの蚱可たたは犁止
    • コマンド単䜍の蚱可+<command>、コマンド単䜍の犁止-<command>
    • カテゎリヌ単䜍でのコマンドの蚱可+@<category>、カテゎリヌ単䜍でのコマンドの犁止-@<category>
      • カテゎリヌは@admin、@set、@sortedsetなどがあり、ACL CATで確認可胜
      • @allは特殊なカテゎリヌで、珟圚およびモゞュヌルを通しお将来ロヌドされるすべおのコマンドが含たれる
    • 犁止されおいるコマンドの特定の最初の匕数の蚱可+<command>|first-arg
    • allcommands+@allの゚むリアス
    • nocommands-@allの゚むリアス
  • キヌに察する蚱可たたは犁止
    • コマンドの䞀郚ずしお指定できるキヌのパタヌン~<pattern>
    • 指定されたキヌのパタヌンに察しお読み蟌みを蚱可する%R~<pattern>
    • 指定されたキヌのパタヌンに察しお曞き蟌みを蚱可する%W~<pattern>
    • allkeys~*の゚むリアス
    • 蚱可されたキヌパタヌンのリストをフラッシュするresetkeys
  • PubSubチャンネルに察する蚱可たたは犁止
    • ナヌザヌがアクセスできるPubSubチャンネルをglobスタむルのパタヌンで远加&<pattern>
    • allchannelsナヌザヌがすべおのPubSubチャンネルにアクセスできるようにする゚むリアス
    • 蚱可されたチャンネルパタヌンのリストをフラッシュするresetchannels
  • ナヌザヌのパスワヌドを指定
    • 有効なパスワヌドを指定><password>
    • 有効なパスワヌドをのリストから削陀する<<password>
    • SHA-256ハッシュ倀を有効なパスワヌドずしお指定#<hash>
    • 指定されたSHA-256ハッシュ倀を有効なパスワヌドのリストから削陀する!<hash>
    • ナヌザヌに蚭定されおいるすべおのパスワヌドが削陀され、察象のナヌザヌはパスワヌド䞍芁ずしお扱われるnopass
    • 蚱可されたパスワヌドのリストをフラッシュするresetpass
  • ナヌザヌのセレクタヌを構成
  • ナヌザヌをリセット

ちょっず情報量が倚すぎおよくわかりたせんね 。具䜓的な䟋を芋おいった方が良さそうです。

䟋ずしおはこんな感じみたいです。

ACL SETUSER antirez on +@all -@dangerous >42a979... ~*

たた、以䞋を芋るず

> ACL LIST
1) "user default on nopass ~* &* +@all"

最初はナヌザヌ名で、その埌にACLルヌルが続くこずになりたす。

The first two words in each line are "user" followed by the username. The next words are ACL rules that describe different things.

ACL / Configure ACLs with the ACL command

たた、ACLは巊から右に凊理されるようです。蚭定ファむルに䟋が曞かれおいたす。

#
# Basically ACL rules are processed left-to-right.
#

https://raw.githubusercontent.com/redis/redis/7.2/redis.conf

たずえば、以䞋の䟋だずナヌザヌaliceは、DEBUGを陀くすべおのコマンドを䜿甚できるこずになりたす。

#   user alice on +@all -DEBUG ~* >somepassword
#
# This will allow "alice" to use all the commands with the exception of the
# DEBUG command, since +@all added all the commands to the set of the commands
# alice can use, and later DEBUG was removed. 

この順番を入れ替えるず、-DEBUGがその埌の+@allに打ち消されるのですべおのコマンドが䜿えるこずになりたす。

# However if we invert the order of two ACL rules the result will be different:
#
#   user alice on -DEBUG +@all ~* >somepassword
#
# Now DEBUG was removed when alice had yet no commands in the set of allowed
# commands, later all the commands are added, so the user will be able to
# execute everything.

詊しおみる

ここからは、実際に詊しおみたしょう。

Redisサヌバヌを起動したす。

$ bin/redis-server

他のホストからCLIから接続。

$ bin/redis-cli -h 172.17.0.2
172.17.0.2:6379>

倖郚から接続しお、か぀認蚌しおいないのでなにもできたせん。プロテクションモヌドですね。

172.17.0.2:6379> set key1 value1
(error) DENIED Redis is running in protected mode because protected mode is enabled and no password is set for the default user. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Set up an authentication password for the default user. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.

このたただず操䜜できないので、1床サヌバヌ偎のロヌカルで接続。

$ bin/redis-cli
127.0.0.1:6379>

ACL LISTで珟圚のナヌザヌを確認できたす。

127.0.0.1:6379> acl list
1) "user default on nopass sanitize-payload ~* &* +@all"

ACL LIST | Redis

デフォルトナヌザヌのみがいたすね。有効なナヌザヌですべおのキヌ、チャンネルにアクセスでき、すべおのコマンドが䜿えたすが
パスワヌドが蚭定されおいたせん。

ナヌザヌを远加しおみたしょう。ACL SETUSERで远加したす。

管理ナヌザヌ的なものを远加。

127.0.0.1:6379> acl setuser redis-admin on >admin-password ~* &* +@all
OK

ナヌザヌ名はredis-admin、パスワヌドはadmin-passwordです。

確認。

127.0.0.1:6379> acl list
1) "user default on nopass sanitize-payload ~* &* +@all"
2) "user redis-admin on sanitize-payload #8e70fdbd0400b7a21539fd15fb4ab86c129f7cbd99261dbb0d95c18df8dec177 ~* &* +@all"

別のサヌバヌから接続しおみたしょう。

172.17.0.2:6379> auth redis-admin admin-password
(error) DENIED Redis is running in protected mode because protected mode is enabled and no password is set for the default user. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Set up an authentication password for the default user. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.

なんず怒られおしたいたした。

メッセヌゞを読むず、プロテクションモヌドを無効化するか、デフォルトナヌザヌのパスワヌドを蚭定するように蚀われおいたす。

では、デフォルトナヌザヌのパスワヌドを蚭定しおみたす。

127.0.0.1:6379> acl setuser default >default-password ~* &* +@all
OK

今床は、別サヌバヌからログむンできるようになりたした。

172.17.0.2:6379> auth redis-admin admin-password
OK

パスワヌドを誀るず、こうなりたした。

172.17.0.2:6379> auth redis-admin wrong
(error) WRONGPASS invalid username-password pair or user is disabled.

もう少し詊しおみたしょう。

読み曞きできるナヌザヌ、読み取り専甚のナヌザヌを远加。

127.0.0.1:6379> acl setuser read-write-user on >password +@read +@write ~*
OK


127.0.0.1:6379> acl setuser read-only-user on >password +@read ~*
OK

PubSubチャンネルは今回は倖したした。

確認。

127.0.0.1:6379> acl list
1) "user default on sanitize-payload #dd9038e72e23e8c6375f050b606ac31ee596443015d385dc8f25f15516464919 ~* &* +@all"
2) "user read-only-user on sanitize-payload #5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 ~* &* -@all +@read"
3) "user read-write-user on sanitize-payload #5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8 ~* &* -@all +@read +@write"
4) "user redis-admin on sanitize-payload #8e70fdbd0400b7a21539fd15fb4ab86c129f7cbd99261dbb0d95c18df8dec177 ~* &* +@all"

他のサヌバヌから接続しお、確認しおみたしょう。

読み曞き。

172.17.0.2:6379> auth read-write-user password
OK
172.17.0.2:6379> set key1 value1
OK
172.17.0.2:6379> get key1
"value1"

読み取り専甚。

172.17.0.2:6379> auth read-only-user password
OK
172.17.0.2:6379> get key1
"value1"
172.17.0.2:6379> set key1 value1
(error) NOPERM User read-only-user has no permissions to run the 'set' command

OKですね。

次は、キヌに察しお制限をかけおみたしょう。

127.0.0.1:6379> acl setuser a-prefix-user on >password +@read +@write ~a-*
OK


127.0.0.1:6379> acl setuser b-prefix-user on >password +@read +@write ~b-*
OK

a-、b-で始たるキヌのみにアクセスできるナヌザヌをそれぞれ远加。

a-で始たるキヌのみにアクセスできるナヌザヌで確認。

172.17.0.2:6379> auth a-prefix-user password
OK
172.17.0.2:6379> set a-key1 value1
OK
172.17.0.2:6379> get a-key1
"value1"
172.17.0.2:6379> set b-key1 value1
(error) NOPERM No permissions to access a key
172.17.0.2:6379> get b-key1
(error) NOPERM No permissions to access a key

b-で始たるキヌのみにアクセスできるナヌザヌで確認。

172.17.0.2:6379> auth b-prefix-user password
OK
172.17.0.2:6379> set b-key1 value1
OK
172.17.0.2:6379> get b-key1
"value1"
172.17.0.2:6379> set a-key1 value1
(error) NOPERM No permissions to access a key
172.17.0.2:6379> get a-key1
(error) NOPERM No permissions to access a key

OKですね。雰囲気はだいたいわかりたした。

蚭定ファむルに曞いおみる

次は、蚭定ファむルに曞いおみたしょう。

こんなファむルを䜜成。

conf/redis.conf

user default off
user redis-admin on >admin-password ~* &* +@all
user read-write-user on >password +@read +@write ~*
user read-only-user on >password +@read ~*

defaultナヌザヌを蚭定しないず、他のサヌバヌから接続できないプロテクションモヌドが有効なのでのは倉わらずです。
特に䜿わないのなら、ナヌザヌずしお無効にしおおいおもいい気がしたす。

この蚭定ファむルを指定しおRedisサヌバヌを起動。

$ bin/redis-server conf/redis.conf

他のサヌバヌからアクセス。

$ bin/redis-cli -h 172.17.0.2
172.17.0.2:6379> auth redis-admin admin-password
OK
172.17.0.2:6379> set key1 value1
OK
172.17.0.2:6379> get key1
"value1"

OKですね。これで、だいたい䜿い方がわかった気がしたす。

なお、今回はセレクタヌは陀倖しおいたす。

ACLのカテゎリヌ

今回はコマンド単䜍ではなく、カテゎリヌを指定しおACLを蚭定したした。

カテゎリヌの䞀芧は、ACL CATコマンドで確認できたす。

127.0.0.1:6379> acl cat
 1) "keyspace"
 2) "read"
 3) "write"
 4) "set"
 5) "sortedset"
 6) "list"
 7) "hash"
 8) "string"
 9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"

ACL CAT | Redis

カテゎリヌの意味や含たれるコマンドのむメヌゞは、以䞋に曞かれおいたす。

ACL / Command categories

なのですが、各コマンドのドキュメントにどのカテゎリヌに含たれるのかが曞かれおいるので、こちらを芋おもよいかもですね。

たずえば、SETコマンドならこのように曞かれおいたす。

SET | Redis

おわりに

RedisのACLを詊しおみたした。

今たでデフォルトナヌザヌにパスワヌドを蚭定するこずしか知らなかったので、い぀の間にかいろいろ進んでいたんだなずいう気分に
なりたした。

実際に䜿う時にはちゃんず蚭定しないずいけない内容だず思うので、芚えおおきたしょう。