ACL
Redis 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. 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 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.
Redis访问控制列表,简称ACL,是限定特定连接执行指定的命令和指定的键的功能。这个功能的工作方式是,连接后,客户端需要提供一个用户名和一个有效的密码来验证。如果验证成功,连接将被关联到一个验证通过的给定了权限限制的用户。Redis新连接默认授权给默认用户(默认配置)。配置默认用户权限会导致未明确身份的连接只能访问特定功能子集。
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. 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.
默认配置方面,Redis6(有ACLs功能的第一版)运行和旧版Redis一样。每个新连接都可以调用所有可能的命令和访问所有键,因此ACL功能与旧版客户端和应用程序是兼容的。旧的方式配置密码,使用requirepass配置指令,仍然可以工作。但是,现在只给默认用户设置密码。
The Redis AUTH
command was extended in Redis 6, so now it is possible to use it in the two-arguments form:
Redis
AUTH
命令在Redis6中扩展了,因此现在可以使用两个参数的形式:
AUTH <username> <password>
Here’s an example of the old form: > 这里是旧的格式:
AUTH <password>
What happens is that the username used to authenticate is “default”, so just specifying the password implies that we want to authenticate against the default user. This provides backward compatibility.
只提供密码的话我们默认使用”default” 这个默认用户进行鉴权。这提供了向后兼容性。
When ACLs are useful
Before using ACLs, you may want to ask yourself what’s the goal you want to accomplish by implementing this layer of protection. Normally there are two main goals that are well served by ACLs:
使用ACLs之前,你应该考虑你使用ACLs的目的是什么?通常有两个主要目的:
You want to improve security by restricting the access to commands and keys, so that untrusted clients have no access and trusted clients have just the minimum access level to the database in order to perform the work needed. For instance, certain clients may just be able to execute read only commands. > 想要提升安全性,限定连接的命令和键的访问,这样不可信客户端没有访问,只有可信客户端可以访问数据库的最小访问级别,以便执行需要的工作。例如,某些客户端只能执行只读命令。
You want to improve operational safety, so that processes or humans accessing Redis are not allowed to damage the data or the configuration due to software errors or manual mistakes. For instance, there is no reason for a worker that fetches delayed jobs from Redis to be able to call the
FLUSHALL
command. > 想要提升操作安全度,防止进程或人工访问或配置导致软件错误的或者人工错误操作。不能谁都能调用FLUSHALL
命令。
Another typical usage of ACLs is related to managed Redis instances. Redis is often provided as a managed service both by internal company teams that handle the Redis infrastructure for the other internal customers they have, or is provided in a software-as-a-service setup by cloud providers. In both setups, we want to be sure that configuration commands are excluded for the customers.
另一个常规ACLs应用场景是Redis服务器的管理。Redis通常由内部公司团队管理Redis的基础设施,或者是通过云服务提供商提供的服务。在这两种情况下,我们都希望确保配置命令不能被其他人调用到。
Configure ACLs with the ACL command
配置ACLs
ACLs are defined using a DSL (domain specific language) that describes what a given user is allowed to do. Such rules are always implemented from the first to the last, left-to-right, because sometimes the order of the rules is important to understand what the user is really able to do. > ACLs使用一种域特定的语言来描述了给定用户允许做的事情。这些规则总是由从第一个到最后一个,从左到右的方式来实现,因为有时候规则的顺序对于理解用户权限范围很重要。
By default there is a single user defined, called default. We can use the ACL LIST
command in order to check the currently active ACLs and verify what the configuration of a freshly started, defaults-configured Redis instance is:
默认用户为*default*,我们可以使用
ACL LIST
命令查看当前活跃的ACLs,并可以验证新启动的Redis实例的默认配置。
> ACL LIST
1) "user default on nopass ~* &* +@all"
The command above reports the list of users in the same format that is used in the Redis configuration files, by translating the current ACLs set for the users back into their description.
上面的命令报告了当前的ACLs设置,通过将其转换为用户的描述来报告。
The first two words in each line are “user” followed by the username. The next words are ACL rules that describe different things. We’ll show how the rules work in detail, but for now it is enough to say that the default user is configured to be active (on), to require no password (nopass), to access every possible key (~*
) and Pub/Sub channel (&*
), and be able to call every possible command (+@all
).
返回结果的前两个单词为
user
和用户名。后面的单出是 ACL规则。可以看出配置的默认用户是活跃状态(on
),不需要密码 (nopass
),可以访问所有的键(~*
)和Pub/Sub通道(&*
),并且可以调用所有的命令(+@all
)。
Also, in the special case of the default user, having the nopass rule means that new connections are automatically authenticated with the default user without any explicit AUTH
call needed.
同时,默认用户的*nopass*规则意味着新的连接自动被默认用户认证,不需要显式的
AUTH
调用。
ACL rules
ACL规则
The following is the list of valid ACL rules. Certain rules are just single words that are used in order to activate or remove a flag, or to perform a given change to the user ACL. Other rules are char prefixes that are concatenated with command or category names, key patterns, and so forth.
下面是有效的ACL规则列表。某些规则只是单个单词,用于激活或移除标记,或者执行给定的改变用户ACL。其他规则是命令或类别名称或key规则等等的字符串前缀的组合连接。
Enable and disallow users:
on
: Enable the user: it is possible to authenticate as this user.off
: Disallow the user: it’s no longer possible to authenticate with this user; however, previously authenticated connections will still work. Note that if the default user is flagged as off, new connections will start as not authenticated and will require the user to sendAUTH
orHELLO
with the AUTH option in order to authenticate in some way, regardless of the default user configuration.
Allow and disallow commands: > 允许和禁止命令:
+<command>
: Add the command to the list of commands the user can call. Can be used with|
for allowing subcommands (e.g “+config|get”). >+<command>
:将命令添加到用户可以调用的命令列表中。可以使用|
来允许子命令(例如+config|get
)。-<command>
: Remove the command to the list of commands the user can call. Starting Redis 7.0, it can be used with|
for blocking subcommands (e.g “-config|set”). >-<command>
:从用户可以调用的命令列表中移除命令。Redis 7.0以上,可以使用|
来阻止子命令(例如-config|set
)。+@<category>
: Add all the commands in such category to be called by the user, with valid categories being like @admin, @set, @sortedset, … and so forth, see the full list by calling theACL CAT
command. The special category @all means all the commands, both the ones currently present in the server, and the ones that will be loaded in the future via modules. >+@<category>
:将一整类的命令添加到用户调用的命令列表中,有效的类别是@admin,@set,@sortedset,…和这样的,可以通过调用ACL CAT
命令来查看完整的列表。特殊的类别@all意味着所有的命令,包括当前在服务器中的和将来通过模块加载的命令。-@<category>
: Like+@<category>
but removes the commands from the list of commands the client can call. >-@<category>
:从用户可以调用的命令列表中移除命令。+<command>|first-arg
: Allow a specific first argument of an otherwise disabled command. It is only supported on commands with no sub-commands, and is not allowed as negative form like -SELECT|1, only additive starting with “+”. This feature is deprecated and may be removed in the future. >+<command>|first-arg
: 允许指定第一个参数的命令,如果参数是其他值则禁用。只适用于没有子命令的命令,不支持如-SELECT|1
这种格式的-
禁用模式,只支持+
增加模式。这个特性已经被废弃,可能在未来被移除。allcommands
: Alias for +@all. Note that it implies the ability to execute all the future commands loaded via the modules system. >allcommands
:+@all
的别名。能够执行通过模块系统加载的所有命令。nocommands
: Alias for -@all。 >nocommands
:-@all
的别名。
Allow and disallow certain keys and key permissions: > 允许和禁用指定key和key权限:
~<pattern>
: Add a pattern of keys that can be mentioned as part of commands. For instance~*
allows all the keys. The pattern is a glob-style pattern like the one ofKEYS
. It is possible to specify multiple patterns.
>~<pattern>
:增加命令可以使用的key的规则,如~*
是允许所有key,这个规则和KEYS
命令的规则一样,而且可以指定多个规则。%R~<pattern>
: (Available in Redis 7.0 and later) Add the specified read key pattern. This behaves similar to the regular key pattern but only grants permission to read from keys that match the given pattern. See key permissions for more information. >%R~<pattern>
: (Redis7.0后可用)增加指定的key规则读权限。这个行为类似于正常的key规则,但只允许读取给定规则的key。参见key权限%W~<pattern>
: (Available in Redis 7.0 and later) Add the specified write key pattern. This behaves similar to the regular key pattern but only grants permission to write to keys that match the given pattern. See key permissions for more information. >%W~<pattern>
: (Redis7.0后可用)增加指定key规则的写权限。这个行为类似于正常的key规则,但只允许写入给定规则的key。参见key权限%RW~<pattern>
: (Available in Redis 7.0 and later) Alias for~<pattern>
. >%RW~<pattern>
: (Redis7.0后可用)~<pattern>
的别名。allkeys
: Alias for~*
. >allkeys
:~*
的别名。resetkeys
: Flush the list of allowed keys patterns. For instance the ACL~foo:* ~bar:* resetkeys ~objects:*
, will only allow the client to access keys that match the patternobjects:*
. >resetkeys
:清除允许的key规则。如~foo:* ~bar:* resetkeys ~objects:*
为只允许客户端访问object:*
规则的key。
Allow and disallow Pub/Sub channels: > 允许和禁用 Pub/Sub channels:
&<pattern>
: (Available in Redis 6.2 and later) Add a glob style pattern of Pub/Sub channels that can be accessed by the user. It is possible to specify multiple channel patterns. Note that pattern matching is done only for channels mentioned byPUBLISH
andSUBSCRIBE
, whereasPSUBSCRIBE
requires a literal match between its channel patterns and those allowed for user. >&<pattern>
: (Redis 6.2以后可用),设置用户可访问的Pub/Sub频道的全局规则。可以指定多个频道规则。需要注意的是,模式匹配仅针对发布PUBLISH
和订阅SUBSCRIBE
提到的频道进行,而PSUBSCRIBE
则需要在其频道模式和允许用户的频道模式之间进行字面匹配。allchannels
: Alias for&*
that allows the user to access all Pub/Sub channels. >allchannels
:&*
的别名,允许用户访问所有的Pub/Sub频道。resetchannels
: Flush the list of allowed channel patterns and disconnect the user’s Pub/Sub clients if these are no longer able to access their respective channels and/or channel patterns. >resetchannels
: 清空用户所有的频道允许列表并断开用户 Pub/Sub客户端链接,如果它们不再能够访问其各自的频道和/或频道规则。
Configure valid passwords for the user: > 为用户设置密码
><password>
: Add this password to the list of valid passwords for the user. For example>mypass
will add “mypass” to the list of valid passwords. This directive clears the nopass flag (see later). Every user can have any number of passwords. >><password>
: 将这个密码添加到用户有效密码列表中。如>mypass
将把”mypass”添加到有效密码列表中。这个指令会清除 *nopass*标记。每个用户可以设置任意数量的密码。<<password>
: Remove this password from the list of valid passwords. Emits an error in case the password you are trying to remove is actually not set. ><<password>
: 从有效密码列表中一出这个密码。如果没设置给定密码时会报错。#<hash>
: Add this SHA-256 hash value to the list of valid passwords for the user. This hash value will be compared to the hash of a password entered for an ACL user. This allows users to store hashes in theacl.conf
file rather than storing cleartext passwords. Only SHA-256 hash values are accepted as the password hash must be 64 characters and only contain lowercase hexadecimal characters. >#<hash>
:将这个 SHA-256的哈希值添加到用户有效密码列表中。这个哈希值将会与用户输入的密码的hash值进行比较。用户可以将hash值存储在acl.conf
文件中,而不是存储明文密码。因为密码的hash为64个字符,并且只能包含小写的16进制字符,所以只支持 SHA-256的hash值。!<hash>
: Remove this hash value from the list of valid passwords. This is useful when you do not know the password specified by the hash value but would like to remove the password from the user. > 从有效密码列表中删除这个hash值。当你不知道指定的hash值对应的密码,但是想要删除这个密码时可以使用这个指令。nopass
: All the set passwords of the user are removed, and the user is flagged as requiring no password: it means that every password will work against this user. If this directive is used for the default user, every new connection will be immediately authenticated with the default user without any explicit AUTH command required. Note that the resetpass directive will clear this condition. >nopass
:所有设置的密码都会被删除,并且用户会被标记为需要无密码:这意味着每个密码都可以用于这个用户。如果这个指令用于默认用户,每次连接都会自动认证为默认用户,不需要显式的AUTH命令。注意,*resetpass*指令会清除这个条件。resetpass
: Flushes the list of allowed passwords and removes the nopass status. After resetpass, the user has no associated passwords and there is no way to authenticate without adding some password (or setting it as nopass later). >resetpass
: 清空密码列表,并清除*nopass*状态,用户没有关联密码,且必须添加密码才能进行认证(除非设置为nopass)。
Note: if a user is not flagged with nopass and has no list of valid passwords, that user is effectively impossible to use because there will be no way to log in as that user.
注意:如果用户没有标记为nopass
并且没有有效密码列表,那么用户将无法使用,因为没有方法登录为这个用户。
Configure selectors for the user: > 为用户设置选择器:
(<rule list>)
: (Available in Redis 7.0 and later) Create a new selector to match rules against. Selectors are evaluated after the user permissions, and are evaluated according to the order they are defined. If a command matches either the user permissions or any selector, it is allowed. See selectors for more information.
(<rule list>)
: (Redis7.0及以后可用) 创建一个新的规则匹配选择器。选择器根据用户的权限和权限的顺序进行运算。如果一个命令匹配了用户的权限或者任何选择器,那么它就是允许的。详细信息请参见选择器。
clearselectors
: (Available in Redis 7.0 and later) Delete all of the selectors attached to the user. >clearselectors
: (Redis7.0及以后可用) 删除所有附加到用户的选择器。
Reset the user: > 重置用户:
reset
Performs the following actions: resetpass, resetkeys, resetchannels, off, -@all. The user returns to the same state it had immediately after its creation. >reset
执行以下操作:resetpass
,resetkeys
,resetchannels
,off
,-@all
。用户会返回到它创建后的状态。
Create and edit user ACLs with the ACL SETUSER command
使用ACL SETUSER命令创建和编辑用户ACLs。
Users can be created and modified in two main ways: > 通过两种方式创建和编辑用户:
Using the ACL command and its
ACL SETUSER
subcommand. > 使用ACL命令和其ACL SETUSER
子命令。Modifying the server configuration, where users can be defined, and restarting the server. With an external ACL file, just call
ACL LOAD
. > 修改缓存服务中定义用户的配置并重启缓存服务。使用*外部ACL文件*,只需调用ACL LOAD
。
In this section we’ll learn how to define users using the ACL
command. With such knowledge, it will be trivial to do the same things via the configuration files. Defining users in the configuration deserves its own section and will be discussed later separately.
> 在这一节我们来学习如何使用ACL
命令来定义用户。懂了这个,通过配置文件来做同样的事情就很好弄了。在配置文件中定义用户在其他章节单独讨论。
To start, try the simplest ACL SETUSER
command call:
> 开始,试试最简单的ACL SETUSER
命令调用:
> ACL SETUSER alice
OK
The ACL SETUSER
command takes the username and a list of ACL rules to apply to the user. However the above example did not specify any rule at all. This will just create the user if it did not exist, using the defaults for new users. If the user already exists, the command above will do nothing at all.
> ACL SETUSER
命令会给用户赋予用户名和一套ACL鬼节列表。然而上面的例子并没有定义任何规则。执行后如果用户不存在会使用默认规则创建新用户。如果用户已经存在了,那命令不会做任何操作。
Check the default user status: > 检查默认用户状态:
> ACL LIST
1) "user alice off &* -@all"
2) "user default on nopass ~* ~& +@all"
The new user “alice” is: > 新用户”alice”:
- In the off status, so
AUTH
will not work for the user “alice”. > 是关闭状态,所以用户”alice”不能使用AUTH
命令。 - The user also has no passwords set. > 没设置密码。
- Cannot access any command. Note that the user is created by default without the ability to access any command, so the
-@all
in the output above could be omitted; however,ACL LIST
attempts to be explicit rather than implicit. > 不能访问任何命令。注意,默认创建的用户是不能访问任何命令的,所以输出中的-@all
可以省略;但是ACL LIST
会尽量都展示而不是给省略掉。 - There are no key patterns that the user can access. > 没有用户可以访问的key规则。
- The user can access all Pub/Sub channels. > 用户可以访问所有Pub/Sub频道。
New users are created with restrictive permissions by default. Starting with Redis 6.2, ACL provides Pub/Sub channels access management as well. To ensure backward compatibility with version 6.0 when upgrading to Redis 6.2, new users are granted the ‘allchannels’ permission by default. The default can be set to resetchannels
via the acl-pubsub-default
configuration directive.
默认情况下新建的用户有限定的权限。Redis 6.2以后,ACL提供了Pub/Sub频道访问管理。为了确保6.0版本和6.2版本之间的兼容性,新建用户默认被赋予’allchannels’权限。可以通过配置
acl-pubsub-default
来设置默认值为resetchannels
。
From 7.0, The acl-pubsub-default
value is set to resetchannels
to restrict the channels access by default to provide better security. The default can be set to allchannels
via the acl-pubsub-default
configuration directive to be compatible with previous versions.
从7.0版本开始,
acl-pubsub-default
值默认设置为resetchannels
,以提供更好的安全性。可以通过配置acl-pubsub-default
来设置默认值为allchannels
,以兼容6.0版本。
Such user is completely useless. Let’s try to define the user so that it is active, has a password, and can access with only the GET
command to key names starting with the string “cached:“.
这样的用户是完全无用的。让我们来激活用户,给用户设置密码,并让用户只能使用
GET
命令访问以”cached:“开头的key。
> ACL SETUSER alice on >p1pp0 ~cached:* +get
OK
Now the user can do something, but will refuse to do other things:
> AUTH alice p1pp0
OK
> GET foo
(error) NOPERM this user has no permissions to access one of the keys used as arguments
> GET cached:1234
(nil)
> SET cached:1234 zap
(error) NOPERM this user has no permissions to run the 'set' command
Things are working as expected. In order to inspect the configuration of the user alice (remember that user names are case sensitive), it is possible to use an alternative to ACL LIST
which is designed to be more suitable for computers to read, while ACL LIST
is more human readable.
可以使用
ACL GETUSER
来查看用户alice的配置(记住,用户名是大小写敏感的)。
> ACL GETUSER alice
1) "flags"
2) 1) "on"
2) "allchannels"
3) "passwords"
4) 1) "2d9c75..."
5) "commands"
6) "-@all +get"
7) "keys"
8) "~cached:*"
9) "channels"
10) "&*"
11) "selectors"
12) 1) 1) "commands"
2) "-@all +set"
3) "keys"
4) "~*"
5) "channels"
6) "&*"
The ACL GETUSER
returns a field-value array that describes the user in more parsable terms. The output includes the set of flags, a list of key patterns, passwords, and so forth. The output is probably more readable if we use RESP3, so that it is returned as a map reply:
ACL GETUSER
命令返回分拆的用户字段数组。输出包含flags
集合、key
规则列表、密码等等信息。输出以RESP3协议来说可读性更好,它返回的是一个map:
> ACL GETUSER alice
1# "flags" => 1~ "on"
2~ "allchannels"
2# "passwords" => 1) "2d9c75273d72b32df726fb545c8a4edc719f0a95a6fd993950b10c474ad9c927"
3# "commands" => "-@all +get"
4# "keys" => "~cached:*"
5# "channels" => "&*"
6# "selectors" => 1) 1# "commands" => "-@all +set"
2# "keys" => "~*"
3# "channels" => "&*"
Note: from now on, we’ll continue using the Redis default protocol, version 2
Using another ACL SETUSER
command (from a different user, because alice cannot run the ACL
command), we can add multiple patterns to the user:
用其他的用户使用
ACL SETUSER
命令,可以给alice
用户配置其他key规则。
> ACL SETUSER alice ~objects:* ~items:* ~public:*
OK
> ACL LIST
1) "user alice on >2d9c75... ~cached:* ~objects:* ~items:* ~public:* &* -@all +get"
2) "user default on nopass ~* &* +@all"
The user representation in memory is now as we expect it to be. > 效果和我们预期的一样。
Multiple calls to ACL SETUSER
It is very important to understand what happens when ACL SETUSER
is called multiple times. What is critical to know is that every ACL SETUSER
call will NOT reset the user, but will just apply the ACL rules to the existing user. The user is reset only if it was not known before. In that case, a brand new user is created with zeroed-ACLs. The user cannot do anything, is disallowed, has no passwords, and so forth. This is the best default for safety.
> 理解ACL SETUSER
命令被调用多次的运作原理很重要。尤其要知道,每次执行ACL SETUSER
命令并不会重置用户,只会将ACL规则应用到已有用户上。只有用户不存在才会被重置。那种情况,会创建一类无ACL权限用户。用户不能做任何事情,没有密码,禁用等等。是最安全的默认模式。
However later calls will just modify the user incrementally. For instance, the following sequence: > 后续的调用只会增量的修改用户信息。例如如下调用顺序:
> ACL SETUSER myuser +set
OK
> ACL SETUSER myuser +get
OK
Will result in myuser being able to call both GET
and SET
:
> myuser
用户可以同时调用GET
和SET
命令。
> ACL LIST
1) "user default on nopass ~* &* +@all"
2) "user myuser off &* -@all +set +get"
Command categories
命令分类
Setting user ACLs by specifying all the commands one after the other is really annoying, so instead we do things like this: > 给用户的ACL权限
> ACL SETUSER antirez on +@all -@dangerous >42a979... ~*
By saying +@all and -@dangerous, we included all the commands and later removed all the commands that are tagged as dangerous inside the Redis command table. Note that command categories never include modules commands with the exception of +@all. If you say +@all, all the commands can be executed by the user, even future commands loaded via the modules system. However if you use the ACL rule +@read or any other, the modules commands are always excluded. This is very important because you should just trust the Redis internal command table. Modules may expose dangerous things and in the case of an ACL that is just additive, that is, in the form of +@all -...
You should be absolutely sure that you’ll never include what you did not mean to.
> 通过提供+@all
和-@dangerous
信息,我们加入了所有命令的权限,然后移除了Redis命令列表中带有dangerours
标签的所有命令。需要注意命令分类是不包含模块命令的,除非使用+@all
。如果你给了 +@all
信息,用户就能执行所有命令,包括未来通过模块系统新加载的命令。然而,如果你使用 ACL规则 +@read
或其他类似规则,那么模块系统命令通常是排除掉的。这非常重要,因为你应该只相信Redis的内部命令表。模块系统可能暴露危险的事情,尤其在通过使用 +@all
的情况附加到ACL权限的情况。你应该绝对确保你没有引用你不需要的东西。
The following is a list of command categories and their meanings: > 下面是命令分类列表和他们的含义:
admin - Administrative commands. Normal applications will never need to use these. Includes
REPLICAOF
,CONFIG
,DEBUG
,SAVE
,MONITOR
,ACL
,SHUTDOWN
, etc. > admin - 管理员命令。通常应用不会用这些命令。包含REPLICAOF
,CONFIG
,DEBUG
,SAVE
,MONITOR
,ACL
,SHUTDOWN
,等。bitmap - Data type: bitmaps related. > bitmap - bitmaps数据类型相关命令
blocking - Potentially blocking the connection until released by another command. > blocking - 可能会阻塞连接直到另一个命令释放连接。
connection - Commands affecting the connection or other connections. This includes
AUTH
,SELECT
,COMMAND
,CLIENT
,ECHO
,PING
, etc. > connection - 影响当前连接和其他连接的命令。包含AUTH
,SELECT
,COMMAND
,CLIENT
,ECHO
,PING
,等等。dangerous - Potentially dangerous commands (each should be considered with care for various reasons). This includes
FLUSHALL
,MIGRATE
,RESTORE
,SORT
,KEYS
,CLIENT
,DEBUG
,INFO
,CONFIG
,SAVE
,REPLICAOF
, etc. > dangerous - 可能危险的命令(每个应该谨慎考虑使用)。包含FLUSHALL
,MIGRATE
,RESTORE
,SORT
,KEYS
,CLIENT
,DEBUG
,INFO
,CONFIG
,SAVE
,REPLICAOF
,等等。geo - Data type: geospatial indexes related. > geo数据类型相关命令
hash - Data type: hashes related. > hash - 哈希数据类型相关命令
hyperloglog - Data type: hyperloglog related. > hyperloglog - hyperloglog数据类型相关命令
fast - Fast O(1) commands. May loop on the number of arguments, but not the number of elements in the key. > fast - 快速O(1)命令。可能会遍历参数数量,但不会遍历键中的元素数量。
keyspace - Writing or reading from keys, databases, or their metadata in a type agnostic way. Includes
DEL
,RESTORE
,DUMP
,RENAME
,EXISTS
,DBSIZE
,KEYS
,EXPIRE
,TTL
,FLUSHALL
, etc. Commands that may modify the keyspace, key, or metadata will also have thewrite
category. Commands that only read the keyspace, key, or metadata will have theread
category. > 以类型无关的方式读写键,数据库,或其元数据的命令类型。包含DEL
,RESTORE
,DUMP
,RENAME
,EXISTS
,DBSIZE
,KEYS
,EXPIRE
,TTL
,FLUSHALL
,等等。命令可能会修改键空间,键,或元数据的命令将有write
类别。命令只能读取键空间,键,或元数据将有read
类别。list - Data type: lists related. > list - list数据类型相关命令
pubsub - PubSub-related commands. > pubsub - pubsub相关命令
read - Reading from keys (values or metadata). Note that commands that don’t interact with keys, will not have either
read
orwrite
. > read - 读取键(值或元数据)。请注意,不会交互的命令将不会有read
或write
类别。scripting - Scripting related. > scripting - 脚本相关命令
set - Data type: sets related. > set - set数据类型相关命令
sortedset - Data type: sorted sets related. > sortedset - sortedset数据类型相关命令
slow - All commands that are not
fast
. > slow - 非fast
命令stream - Data type: streams related. > stream - stream数据类型相关命令
string - Data type: strings related. > string - string数据类型相关命令
transaction -
WATCH
/MULTI
/EXEC
related commands. > transaction -WATCH
/MULTI
/EXEC
相关命令write - Writing to keys (values or metadata). > write - 写入键(值或元数据)的命令。
Redis can also show you a list of all categories and the exact commands each category includes using the Redis ACL
command’s CAT
subcommand. It can be used in two forms:
Redis可以查看分类列表及分类包含的命令列表,使用Redis
ACL
命令的CAT
子命令。它有两种用法:
ACL CAT -- Will just list all the categories available
## 可以查看所有的可用分类
ACL CAT <category-name> -- Will list all the commands inside the category
## 可以查看分类包含的所有的命令
Examples:
> 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"
As you can see, so far there are 21 distinct categories. Now let’s check what command is part of the geo category: > 可以看到有21个不同分类,还可以看到*geo*分类下的命令:
> ACL CAT geo
1) "geohash"
2) "georadius_ro"
3) "georadiusbymember"
4) "geopos"
5) "geoadd"
6) "georadiusbymember_ro"
7) "geodist"
8) "georadius"
Note that commands may be part of multiple categories. For example, an ACL rule like +@geo -@read
will result in certain geo commands to be excluded because they are read-only commands.
> 需要注意:一个命令可能同时属于多个分类。如:+@geo -@read
将导致geo命令被排除,因为它们是只读命令。
Allow/block subcommands
允许/拒绝子命令
Starting from Redis 7.0, subcommands can be allowed/blocked just like other commands (by using the separator |
between the command and subcommand, for example: +config|get
or -config|set
)
Redis7.0之后,子命令可以被允许/拒绝,可以用|
分隔命令和子命令,例如:+config|get
或-config|set
That is true for all commands except DEBUG. In order to allow/block specific DEBUG subcommands, see the next section.
> 除了DEBUG
命令其他命令都适用。
本节使用删除线因为主要介绍Redis6.0特性。
Allow the first-arg of a blocked command
Note: This feature is deprecated since Redis 7.0 and may be removed in the future. > ** 注意:该特性已经被Redis7.0取消了,可能在未来会被删除。那我就不翻了**
Sometimes the ability to exclude or include a command or a subcommand as a whole is not enough. Many deployments may not be happy providing the ability to execute a SELECT
for any DB, but may still want to be able to run SELECT 0
.
In such case we could alter the ACL of a user in the following way:
ACL SETUSER myuser -select +select|0
First, remove the SELECT
command and then add the allowed first-arg. Note that it is not possible to do the reverse since first-args can be only added, not excluded. It is safer to specify all the first-args that are valid for some user since it is possible that new first-args may be added in the future.
Another example:
ACL SETUSER myuser -debug +debug|digest
Note that first-arg matching may add some performance penalty; however, it is hard to measure even with synthetic benchmarks. The additional CPU cost is only paid when such commands are called, and not when other commands are called.
It is possible to use this mechanism in order to allow subcommands in Redis versions prior to 7.0 (see above section).
+@all VS -@all
+@all
VS-@all
In the previous section, it was observed how it is possible to define command ACLs based on adding/removing single commands.
在上一节中,我们可以通过添加/删除单个命令来定义命令ACL。
Selectors
选择器
Starting with Redis 7.0, Redis supports adding multiple sets of rules that are evaluated independently of each other. These secondary sets of permissions are called selectors and added by wrapping a set of rules within parentheses. In order to execute a command, either the root permissions (rules defined outside of parenthesis) or any of the selectors (rules defined inside parenthesis) must match the given command. Internally, the root permissions are checked first followed by selectors in the order they were added.
Redis7.0之后,Redis支持添加多个独立的规则集,这些规则集可以被包裹在括号中,以便添加到命令ACL中。为了执行命令,括号外定义的规则的顶级权限或括号内定义的规则的选择器必须匹配给定命令。在内部,顶级权限会先检查,然后按照添加顺序依次检查选择器。
For example, consider a user with the ACL rules +GET ~key1 (+SET ~key2)
. This user is able to execute GET key1
and SET key2 hello
, but not GET key2
or SET key1 world
.
例如,一个用户ACL规则为
+GET ~key1 (+SET ~key2)
。该用户可以执行GET key1
和SET key2 hello
,但不能执行GET key2
或SET key1 world
。
Unlike the user’s root permissions, selectors cannot be modified after they are added. Instead, selectors can be removed with the clearselectors
keyword, which removes all of the added selectors. Note that clearselectors
does not remove the root permissions.
与用户的顶级权限不同,选择器在添加后无法改变。可以使用
clearselectors
关键字来删除所有添加的选择器,但不会删除顶级权限。
Key permissions
Key权限
Starting with Redis 7.0, key patterns can also be used to define how a command is able to touch a key. This is achieved through rules that define key permissions. The key permission rules take the form of %(<permission>)~<pattern>
. Permissions are defined as individual characters that map to the following key permissions:
从Redis7.0版本开始,key规则也可以被用于定义命令能否访问一个Key。这是通过定义key权限的规则来实现的。key权限规则的格式为
%(<permission>)~<pattern>
。权限是定义为单个字符的,映射到以下key权限:
- W (Write): The data stored within the key may be updated or deleted. > 写(W):key中存储的数据可以被更新或删除。
- R (Read): User supplied data from the key is processed, copied or returned. Note that this does not include metadata such as size information (example
STRLEN
), type information (exampleTYPE
) or information about whether a value exists within a collection (exampleSISMEMBER
). > 读(R):用户提供的数据从key中被处理,复制或返回。注意,这不包括元数据,例如size信息(例如STRLEN
),类型信息(例如TYPE
))或是否存在于集合中(例如SISMEMBER
))。
Permissions can be composed together by specifying multiple characters. Specifying the permission as ‘RW’ is considered full access and is analogous to just passing in ~<pattern>
.
权限可以通过指定多个字符组合来组合。指定权限为“RW”被认为是完全访问,并且类似于只传入
~<pattern>
。
For a concrete example, consider a user with ACL rules +@all ~app1:* (+@readonly ~app2:*)
. This user has full access on app1:*
and readonly access on app2:*
. However, some commands support reading data from one key, doing some transformation, and storing it into another key. One such command is the COPY
command, which copies the data from the source key into the destination key. The example set of ACL rules is unable to handle a request copying data from app2:user
into app1:user
, since neither the root permission or the selector fully matches the command. However, using key selectors you can define a set of ACL rules that can handle this request +@all ~app1:* %R~app2:*
. The first pattern is able to match app1:user
and the second pattern is able to match app2:user
.
举一个具体的例子,假设一个用户ACL规则为
+@all ~app1:* (+@readonly ~app2:*)
。该用户具有完全访问app1:*
和只读访问app2:*
。然而,有些命令支持从一个key中读取数据,进行一些转换,并将其存储到另一个key中。例如COPY
命令,它可以复制数据从源key到目标key。该例子的ACL规则无法处理一个请求从app2:user
复制数据到app1:user
,因为顶级权限或选择器不能完全匹配命令。但是,使用key选择器,你可以定义一组ACL规则,以处理这个请求+@all ~app1:* %R~app2:*
。第一个规则可以匹配app1:user
,第二个规则可以匹配app2:user
。
Which type of permission is required for a command is documented through key specifications. The type of permission is based off the keys logical operation flags. The insert, update, and delete flags map to the write key permission. The access flag maps to the read key permission. If the key has no logical operation flags, such as EXISTS
, the user still needs either key read or key write permissions to execute the command.
命令必备哪种类型的权限归档在key说明。权限的类型取决于key的逻辑操作标志。插入,更新,删除标志映射到写入key权限。访问标志映射到读取key权限。如果key没有逻辑操作标志,例如
EXISTS
,用户仍然需要key读或key写权限才能执行命令。
Note: Side channels to accessing user data are ignored when it comes to evaluating whether read permissions are required to execute a command. This means that some write commands that return metadata about the modified key only require write permission on the key to execute: For example, consider the following two commands:
注意:当评估执行命令是否需要读权限时,侧信道访问用户数据被忽略。这意味着一些会返回被修改键的元信息的修改命令只需要key的写权限去执行:作为案例,我们看看一下两个命令:
LPUSH key1 data
: modifies “key1” but only returns metadata about it, the size of the list after the push, so the command only requires write permission on “key1” to execute. >LPUSH key1 data
:修改“key1”,但只返回元信息,列表push元素以后集合的大小,所以命令只需要”key1”的写权限去执行。LPOP key2
: modifies “key2” but also returns data from it, the left most item in the list, so the command requires both read and write permission on “key2” to execute. >LPOP key2
:修改“key2”,同时返回数据,列表最左边的项,所以命令需要读取和写入”key2”权限去执行。
If an application needs to make sure no data is accessed from a key, including side channels, it’s recommended to not provide any access to the key.
如果一个应用需要确保通过key不能访问数据,包括侧信道,那么建议不要提供任何访问key的权限。
How passwords are stored internally
密码的内部存储方式
Redis internally stores passwords hashed with SHA256. If you set a password and check the output of ACL LIST
or ACL GETUSER
, you’ll see a long hex string that looks pseudo random. Here is an example, because in the previous examples, for the sake of brevity, the long hex string was trimmed:
密码的内部存储方式是SHA256哈希。如果设置密码,并且检查
ACL LIST
或ACL GETUSER
的输出,你会看到一个长的十六进制字符串,它看起来像是伪随机的。现在举一个例子,因为在上一个例子中了简化展示我们只显示了长哈希前面的部分。
> ACL GETUSER default
1) "flags"
2) 1) "on"
2) "allkeys"
3) "allcommands"
4) "allchannels"
3) "passwords"
4) 1) "2d9c75273d72b32df726fb545c8a4edc719f0a95a6fd993950b10c474ad9c927"
5) "commands"
6) "+@all"
7) "keys"
8) "~*"
9) "channels"
10) "&*"
11) "selectors"
12) (empty array)
Also, starting with Redis 6, the old command CONFIG GET requirepass
will no longer return the clear text password, but instead the hashed password.
同时,从Redis 6开始,旧的命令
CONFIG GET requirepass
将不再返回明文密码,而是返回哈希密码。
Using SHA256 provides the ability to avoid storing the password in clear text while still allowing for a very fast AUTH
command, which is a very important feature of Redis and is coherent with what clients expect from Redis.
使用SHA256可以避免明文存储密码,同时还允许快速的
AUTH
命令,这是Redis的一个重要特性,并且与客户端的期望一致。
However ACL passwords are not really passwords. They are shared secrets between the server and the client, because the password is not an authentication token used by a human being. For instance:
但ACL *密码*不是真正的密码。它们是服务器和客户端之间的共享密钥,因为密码不是一个人类可以使用的认证令牌。例如:
- There are no length limits, the password will just be memorized in some client software. There is no human that needs to recall a password in this context. > 没有长度限制,密码将只被记忆在某些客户端软件中。在这种情况下不需要人工调用密码。
- The ACL password does not protect any other thing. For example, it will never be the password for some email account. > ACL密码不用于保障其他东西。例如,它不会是某个邮箱账户的密码。
- Often when you are able to access the hashed password itself, by having full access to the Redis commands of a given server, or corrupting the system itself, you already have access to what the password is protecting: the Redis instance stability and the data it contains. > 当你已经可以有访问指定服务器命令的全部权限时,可以有权限访问哈希密码,或者破坏系统本身,则你已经有权限访问密码所保护的东西了:Redis实例的稳定性和它包含的数据。
For this reason, slowing down the password authentication, in order to use an algorithm that uses time and space to make password cracking hard, is a very poor choice. What we suggest instead is to generate strong passwords, so that nobody will be able to crack it using a dictionary or a brute force attack even if they have the hash. To do so, there is a special ACL command ACL GENPASS
that generates passwords using the system cryptographic pseudorandom generator:
因此,为了使用算法和空间来是密码破解更困难而降低密码认证的速度,不是很好的选择。我们建议生成强密码,这样就不会有人能够使用字典或者爆破攻击,即使他们有哈希的认证令牌。为此,有一个特殊的ACL命令
ACL GENPASS
,可以使用系统加密随机数生成器生成密码:
> ACL GENPASS
"dd721260bfe1b3d9601e7fbab36de6d04e2e67b0ef1c53de59d45950db0dd3cc"
The command outputs a 32-byte (256-bit) pseudorandom string converted to a 64-byte alphanumerical string. This is long enough to avoid attacks and short enough to be easy to manage, cut & paste, store, and so forth. This is what you should use in order to generate Redis passwords.
这个命令输出一个32字节(256位)的随机字符串转换为64字节的字母数字字符串。这是长到足够防止攻击且短到能够管理、剪切、粘贴、等等。这是你应该使用的生成Redis密码的方式。
Use an external ACL file
使用外部ACL文件
There are two ways to store users inside the Redis configuration: > Redis配置存储用户信息有两种方式
- Users can be specified directly inside the
redis.conf
file. > 可以直接定义到redis.conf
文件中 - It is possible to specify an external ACL file. > 可以指定一个外部ACL文件
The two methods are mutually incompatible, so Redis will ask you to use one or the other. Specifying users inside redis.conf
is good for simple use cases. When there are multiple users to define, in a complex environment, we recommend you use the ACL file instead.
两种方式是*互不兼容*的,因此Redis会让你二选一。对于简单的使用场景,可以把用户定义到
redis.conf
配置中。当需要定义多个用户时,在复杂的环境中,我们推荐使用外部ACL文件。
The format used inside redis.conf
and in the external ACL file is exactly the same, so it is trivial to switch from one to the other, and is the following:
redis.conf
和外部ACL文件的格式是相同的,因此可以互相切换,格式如下:
user <username> ... acl rules ...
For instance:
user worker +@list +@connection ~jobs:* on >ffa9203c493aa99
When you want to use an external ACL file, you are required to specify the configuration directive called aclfile
, like this:
当你使用外部ACL文件时,你必须指定配置参数
aclfile
,格式如下:
aclfile /etc/redis/users.acl
When you are just specifying a few users directly inside the redis.conf
file, you can use CONFIG REWRITE
in order to store the new user configuration inside the file by rewriting it.
如果只是在
redis.conf
文件中定义几个用户,可以使用CONFIG REWRITE
命令来将新的用户配置重写存储到文件中。
The external ACL file however is more powerful. You can do the following: > 外部ACL文件的功能更强大。你可以做到以下事情:
Use
ACL LOAD
if you modified the ACL file manually and you want Redis to reload the new configuration. Note that this command is able to load the file only if all the users are correctly specified. Otherwise, an error is reported to the user, and the old configuration will remain valid. > 如果你手动修改了ACL配置文件,可以使用ACL LOAD
命令让Redis重新加载新配置。注意,这个命令只能加载正确的配置文件,*只有所有用户都正确定义了*。否则会报错,然后恢复旧配置。Use
ACL SAVE
to save the current ACL configuration to the ACL file. > 如果你想要保存当前ACL配置到ACL文件,可以使用ACL SAVE
命令。
Note that CONFIG REWRITE
does not also trigger ACL SAVE
. When you use an ACL file, the configuration and the ACLs are handled separately.
注意,
CONFIG REWRITE
命令不会触发ACL SAVE
命令。当你使用一个ACL文件时,配置和ACL都是分开处理的。
ACL rules for Sentinel and Replicas
Sentinel 和 Replica 的ACL规则
In case you don’t want to provide Redis replicas and Redis Sentinel instances full access to your Redis instances, the following is the set of commands that must be allowed in order for everything to work correctly.
如果你不想让Redis Replica和Redis Sentinel实例具有完全的访问权限,为了让功能正常运行,下面的命令集合就必须给予权限。
For Sentinel, allow the user to access the following commands both in the master and replica instances:
对于Sentinel , 允许用户在主实例和从实例中访问以下命令:
- AUTH, CLIENT, SUBSCRIBE, SCRIPT, PUBLISH, PING, INFO, MULTI, SLAVEOF, CONFIG, CLIENT, EXEC.
Sentinel does not need to access any key in the database but does use Pub/Sub, so the ACL rule would be the following (note: AUTH
is not needed since it is always allowed):
Sentinel 不需要访问任何键,但是需要访问Pub/Sub,因此ACL规则是(注意:
AUTH
不需要,因为它总是允许的):
ACL SETUSER sentinel-user on >somepassword allchannels +multi +slaveof +ping +exec +subscribe +config|rewrite +role +publish +info +client|setname +client|kill +script|kill
Redis replicas require the following commands to be allowed on the master instance:
Redis副本需要在主实例上允许以下命令:
- PSYNC, REPLCONF, PING
No keys need to be accessed, so this translates to the following rules:
没有键需要访问,因此这个规则转换为:
ACL setuser replica-user on >somepassword +psync +replconf +ping
Note that you don’t need to configure the replicas to allow the master to be able to execute any set of commands. The master is always authenticated as the root user from the point of view of replicas.
注意,你不需要配置副本来允许主实例执行任何命令。主实例总是从实例认证为的根用户。