ACL

Redis 访问控制列表

Redis 开源版

Redis ACL,即访问控制列表的简称,是允许限制特定连接可执行的命令和可访问的键的功能。其工作方式是,客户端连接后,需要提供用户名和有效密码进行身份验证。如果身份验证成功,该连接将与给定用户及其权限限制关联。Redis 可以配置为新连接默认使用“default”用户进行身份验证(这是默认配置)。配置默认用户的副作用是,可以仅向未明确进行身份验证的连接提供特定功能的子集。

在默认配置中,Redis 6(首个包含 ACL 功能的版本)的工作方式与旧版本完全相同。每个新连接都可以调用所有可能的命令并访问所有键,因此 ACL 功能与旧客户端和应用程序向后兼容。此外,使用 requirepass 配置指令配置密码的旧方法仍然按预期工作。但是,它现在是为默认用户设置密码。

Redis AUTH 命令在 Redis 6 中得到扩展,现在可以使用双参数形式。

AUTH <username> <password>

以下是旧形式的示例:

AUTH <password>

发生的情况是用于身份验证的用户名是“default”,因此仅指定密码意味着我们要针对默认用户进行身份验证。这提供了向后兼容性。

ACL 何时有用

在使用 ACL 之前,您可能想问问自己,通过实施这一层保护,您想要实现什么目标。通常有两个主要目标可以很好地通过 ACL 实现:

  1. 您希望通过限制对命令和键的访问来提高安全性,从而使不受信任的客户端无法访问,而受信任的客户端只需具备完成所需工作的最低数据库访问级别。例如,某些客户端可能只能执行只读命令。
  2. 您希望提高操作安全性,以便访问 Redis 的进程或人员不会因软件错误或手动失误而损坏数据或配置。例如,从 Redis 获取延迟作业的工作进程没有理由能够调用 FLUSHALL 命令。

ACL 的另一个典型用法与托管 Redis 实例有关。Redis 通常作为托管服务提供,既由内部公司团队为其他内部客户处理 Redis 基础设施,也由云提供商以软件即服务 (SaaS) 的形式提供。在这两种设置中,我们都希望确保为客户排除配置命令。

使用 ACL 命令配置 ACL

ACL 使用 DSL(领域特定语言)定义,该语言描述了给定用户允许执行的操作。这些规则始终从第一个到最后一个,从左到右实现,因为有时规则的顺序对于理解用户真正能够做什么很重要。

默认情况下,定义了一个名为 default 的用户。我们可以使用 ACL LIST 命令来检查当前活动的 ACL,并验证新启动的、默认配置的 Redis 实例的配置是什么。

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

上述命令以与 Redis 配置文件中相同的格式报告用户列表,通过将为用户设置的当前 ACL 转换回其描述。

每行的前两个词是“user”,后跟用户名。接下来的词是描述不同内容的 ACL 规则。我们将详细展示规则如何工作,但现在只需要知道,默认用户被配置为活动状态 (on),无需密码 (nopass),可以访问所有可能的键 (~*) 和 Pub/Sub 频道 (&*),并且可以调用所有可能的命令 (+@all)。

此外,在默认用户的特殊情况下,拥有 nopass 规则意味着新连接会自动使用默认用户进行身份验证,无需任何显式的 AUTH 调用。

ACL 规则

以下是有效 ACL 规则的列表。某些规则只是用于激活或移除标志,或对用户 ACL 执行给定更改的单个词。其他规则是与命令或类别名称、键模式等连接的字符前缀。

启用和禁用用户

  • on: 启用用户:可以以此用户身份进行身份验证。
  • off: 禁用用户:不再可能以此用户进行身份验证;但是,先前已认证的连接仍然有效。请注意,如果默认用户被标记为 off,新连接将以未认证状态开始,并且需要用户发送 AUTH 或使用 AUTH 选项发送 HELLO 以某种方式进行身份验证,而不管默认用户配置如何。

允许和禁用命令

  • +<command>: 将命令添加到用户可以调用的命令列表中。可与 | 一起使用以允许子命令(例如 "+config|get")。
  • -<command>: 从用户可以调用的命令列表中移除该命令。从 Redis 7.0 开始,可与 | 一起使用以阻止子命令(例如 "-config|set")。
  • +@<category>: 将该类别中的所有命令添加到用户可调用的命令列表中,有效类别如 @admin、@set、@sortedset 等等,调用 ACL CAT 命令查看完整列表。特殊类别 @all 表示所有命令,包括服务器中当前存在的命令以及将来通过模块加载的命令。
  • -@<category>: 与 +@<category> 类似,但从客户端可调用的命令列表中移除这些命令。
  • +<command>|first-arg: 允许对原本被禁用的命令使用特定的第一个参数。仅支持没有子命令的命令,不允许使用负形式(例如 -SELECT|1),只能使用以 "+" 开头的添加形式。此功能已弃用,将来可能被移除。
  • allcommands: +@all 的别名。请注意,这意味着能够执行将来通过模块系统加载的所有命令。
  • nocommands: -@all 的别名。

允许和禁用特定键以及键权限

  • ~<pattern>: 添加可在命令中引用的键模式。例如,~* 允许所有键。该模式是 glob 风格的模式,类似于 KEYS 命令使用的模式。可以指定多个模式。
  • %R~<pattern>: (Redis 7.0 及更高版本可用) 添加指定的读取键模式。这与常规键模式类似,但仅授予读取与给定模式匹配的键的权限。有关更多信息,请参阅键权限
  • %W~<pattern>: (Redis 7.0 及更高版本可用) 添加指定的写入键模式。这与常规键模式类似,但仅授予写入与给定模式匹配的键的权限。有关更多信息,请参阅键权限
  • %RW~<pattern>: (Redis 7.0 及更高版本可用) ~<pattern> 的别名。
  • allkeys: ~* 的别名。
  • resetkeys: 清空允许的键模式列表。例如,ACL ~foo:* ~bar:* resetkeys ~objects:* 只允许客户端访问匹配模式 objects:* 的键。

允许和禁用 Pub/Sub 频道

  • &<pattern>: (Redis 6.2 及更高版本可用) 添加用户可以访问的 Pub/Sub 频道 glob 风格模式。可以指定多个频道模式。请注意,模式匹配仅针对 PUBLISHSUBSCRIBE 提及的频道进行,而 PSUBSCRIBE 要求其频道模式与用户允许的模式之间进行字面匹配。
  • allchannels: &* 的别名,允许用户访问所有 Pub/Sub 频道。
  • resetchannels: 清空允许的频道模式列表,如果用户的 Pub/Sub 客户端无法再访问其相应的频道和/或频道模式,则断开连接。

配置用户的有效密码

  • ><password>: 将此密码添加到用户的有效密码列表。例如,>mypass 将“mypass”添加到有效密码列表。此指令清除 nopass 标志(见后)。每个用户可以拥有任意数量的密码。
  • <<password>: 从有效密码列表中移除此密码。如果您尝试移除的密码实际上未设置,则会发出错误。
  • #<hash>: 将此 SHA-256 哈希值添加到用户的有效密码列表。此哈希值将与为 ACL 用户输入的密码的哈希值进行比较。这允许用户将哈希值存储在 acl.conf 文件中,而不是存储明文密码。仅接受 SHA-256 哈希值,因为密码哈希必须为 64 个字符,并且只能包含小写十六进制字符。
  • !<hash>: 从有效密码列表中移除此哈希值。当您不知道哈希值指定的密码但想从用户中移除该密码时,这很有用。
  • nopass: 用户的所有已设置密码被移除,并且用户被标记为无需密码:这意味着任何密码都将对该用户生效。如果此指令用于默认用户,则每个新连接将立即使用默认用户进行身份验证,无需任何显式 AUTH 命令。请注意,resetpass 指令将清除此状态。
  • resetpass: 清空允许的密码列表并移除 nopass 状态。在 resetpass 之后,用户没有关联的密码,并且在添加密码(或稍后将其设置为 nopass)之前无法进行身份验证。

注意:如果用户未标记为 nopass 且没有有效密码列表,则该用户实际上无法使用,因为没有办法以此用户身份登录。

配置用户的选择器

  • (<rule list>): (Redis 7.0 及更高版本可用) 创建一个新的选择器来匹配规则。选择器在用户权限之后进行评估,并根据其定义的顺序进行评估。如果命令匹配用户权限或任何选择器,则允许执行。有关更多信息,请参阅选择器
  • clearselectors: (Redis 7.0 及更高版本可用) 删除附加到用户的所有选择器。

重置用户

  • reset 执行以下操作:resetpass, resetkeys, resetchannels, allchannels(如果 acl-pubsub-default 已设置), off, clearselectors, -@all。用户返回到创建后立即处于的状态。

使用 ACL SETUSER 命令创建和编辑用户 ACL

用户可以通过两种主要方式创建和修改:

  1. 使用 ACL 命令及其 ACL SETUSER 子命令。
  2. 修改服务器配置(可在其中定义用户)并重启服务器。对于外部 ACL 文件,只需调用 ACL LOAD

在本节中,我们将学习如何使用 ACL 命令定义用户。有了这些知识,通过配置文件执行相同的操作将是微不足道的。在配置中定义用户值得单独讨论,将在稍后单独讨论。

首先,尝试最简单的 ACL SETUSER 命令调用:

> ACL SETUSER alice
OK

ACL SETUSER 命令接受用户名和要应用于用户的 ACL 规则列表。但是,上述示例没有指定任何规则。如果用户不存在,它只会使用新用户的默认设置创建用户。如果用户已存在,上述命令将不做任何事情。

检查默认用户状态

> ACL LIST
1) "user alice off resetchannels -@all"
2) "user default on nopass ~* &* +@all"

新用户“alice”是:

  • 处于 off 状态,因此 AUTH 对用户“alice”不起作用。
  • 用户也没有设置密码。
  • 无法访问任何命令。请注意,默认创建的用户无法访问任何命令,因此上述输出中的 -@all 可以省略;但是,ACL LIST 试图明确而不是隐晦。
  • 用户无法访问任何键模式。
  • 用户无法访问任何 Pub/Sub 频道。

默认情况下,新用户创建时具有严格的权限。从 Redis 6.2 开始,ACL 也提供 Pub/Sub 频道访问管理。为了确保与 Redis 6.0 的向后兼容性,在升级到 Redis 6.2 时,默认授予新用户 'allchannels' 权限。可以通过 acl-pubsub-default 配置指令将默认设置为 resetchannels

从 7.0 开始,acl-pubsub-default 的值设置为 resetchannels,以默认限制频道访问,提供更好的安全性。可以通过 acl-pubsub-default 配置指令将默认设置为 allchannels,以兼容以前的版本。

这样的用户完全没用。让我们尝试定义用户,使其处于活动状态,设置密码,并且只能使用 GET 命令访问以字符串“cached:”开头的键名。

> ACL SETUSER alice on >p1pp0 ~cached:* +get
OK

现在用户可以做一些事情,但会拒绝做其他事情:

> 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

一切都按预期工作。为了检查用户 alice 的配置(请记住用户名区分大小写),可以使用 ACL LIST 的替代方法,它更适合计算机读取,而 ACL GETUSER 更具可读性。

> ACL GETUSER alice
1) "flags"
2) 1) "on"
3) "passwords"
4) 1) "2d9c75..."
5) "commands"
6) "-@all +get"
7) "keys"
8) "~cached:*"
9) "channels"
10) ""
11) "selectors"
12) (empty array)

ACL GETUSER 返回一个描述用户属性的字段-值数组,更易于解析。输出包括标志集、键模式列表、密码等等。如果我们使用 RESP3,输出可能更具可读性,因为它会作为映射回复返回。

> ACL GETUSER alice
1# "flags" => 1~ "on"
2# "passwords" => 1) "2d9c75273d72b32df726fb545c8a4edc719f0a95a6fd993950b10c474ad9c927"
3# "commands" => "-@all +get"
4# "keys" => "~cached:*"
5# "channels" => ""
6# "selectors" => (empty array)

注意:从现在开始,我们将继续使用 Redis 默认协议版本 2。

使用另一个 ACL SETUSER 命令(从另一个用户执行,因为 alice 不能运行 ACL 命令),我们可以为用户添加多个模式。

> ACL SETUSER alice ~objects:* ~items:* ~public:*
OK
> ACL LIST
1) "user alice on #2d9c75... ~cached:* ~objects:* ~items:* ~public:* resetchannels -@all +get"
2) "user default on nopass ~* &* +@all"

用户在内存中的表示现在正如我们所期望的那样。

多次调用 ACL SETUSER

理解多次调用 ACL SETUSER 会发生什么非常重要。关键是要知道,每一次 ACL SETUSER 调用都不会重置用户,而只会将 ACL 规则应用于现有用户。用户仅在之前未知的情况下才会被重置。在这种情况下,将创建一个全新的用户,其 ACL 为零。用户不能执行任何操作,被禁用,没有密码等等。这是出于安全考虑的最佳默认设置。

然而,后续调用只会递增地修改用户。例如,以下序列:

> ACL SETUSER myuser +set
OK
> ACL SETUSER myuser +get
OK

将导致 myuser 能够同时调用 GETSET

> ACL LIST
1) "user default on nopass ~* &* +@all"
2) "user myuser off resetchannels -@all +get +set"

命令类别

一个接一个地指定所有命令来设置用户 ACL 确实很麻烦,因此我们这样做:

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

上述命令包含所有命令 (+@all),然后移除 Redis 命令表中标记为危险的所有命令 (-@dangerous)。请注意,命令类别,除了 +@all,永远不包含模块命令。

如果您为特定用户使用 +@all,则该用户可以使用所有命令,包括通过模块系统加载的命令。但是,如果您使用 +@read 或其他任何类别,则模块命令将被排除。这个概念是基础,因为您应该只信任 Redis 内部命令表。模块可能会暴露危险的东西,在仅为添加性 ACL 的情况下,即以 +@all -... 的形式,您应绝对确保不会包含您不想包含的内容。

以下是命令类别及其含义的列表:

  • admin - 管理命令。正常应用程序绝不需要使用这些命令。包括 REPLICAOF, CONFIG, DEBUG, SAVE, MONITOR, ACL, SHUTDOWN 等。
  • bitmap - 数据类型:所有位图相关命令。
  • blocking - 可能会阻塞连接,直到被其他命令释放。
  • bloom - 数据类型:所有布隆过滤器相关命令。
  • cms - 数据类型:Count-Min Sketch 相关命令。
  • connection - 影响连接或其他连接的命令。包括 AUTH, SELECT, COMMAND, CLIENT, ECHO, PING 等。
  • cuckoo - 数据类型:所有 Cuckoo 过滤器相关命令。
  • dangerous - 潜在危险命令(出于各种原因应谨慎对待每个命令)。包括 FLUSHALL, MIGRATE, RESTORE, SORT, KEYS, CLIENT, DEBUG, INFO, CONFIG, SAVE, REPLICAOF 等。
  • fast - 快速 O(1) 命令。可能会循环处理参数数量,但不会循环处理键中的元素数量。
  • geo - 数据类型:所有地理空间索引相关命令。
  • hash - 数据类型:所有哈希相关命令。
  • hyperloglog - 数据类型:所有 HyperLogLog 相关命令。
  • json - 数据类型:所有 JSON 相关命令。
  • keyspace - 以类型无关的方式写入或读取键、数据库或其元数据。包括 DEL, RESTORE, DUMP, RENAME, EXISTS, DBSIZE, KEYS, EXPIRE, TTL, FLUSHALL 等。可能修改键空间、键或元数据的命令也将属于 write 类别。仅读取键空间、键或元数据的命令将属于 read 类别。
  • list - 数据类型:所有列表相关命令。
  • pubsub - 所有 Pub/Sub 相关命令。
  • read - 读取键(值或元数据)。请注意,不与键交互的命令既不属于 read 也不属于 write
  • scripting - 脚本相关。
  • search - 所有搜索相关命令。请注意,只有当索引的键前缀是用户有权访问的键的超集时,才能创建/修改索引。例如,具有键 ACL 模式 h:* 的用户可以创建前缀为 h:*h:p* 的索引,但不能创建前缀为 h*, k:*, 或 k* 的索引,因为这些前缀可能包含用户有权访问的键。
  • set - 数据类型:所有集合相关命令。
  • sortedset - 数据类型:所有有序集合相关命令。
  • slow - 所有不属于 fast 类别的命令。
  • stream - 数据类型:所有流相关命令。
  • string - 数据类型:所有字符串相关命令。
  • tdigest - 数据类型:所有 T-Digest 相关命令。
  • timeseries - 数据类型:所有时间序列相关命令。
  • topk - 数据类型:所有 Top-K 相关命令。
  • transaction - WATCH / MULTI / EXEC 相关命令。
  • write - 写入键(值或元数据)。请注意,不与键交互的命令既不属于 read 也不属于 write

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

示例

> 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"
22) "json"
23) "search"
24) "tdigest"
25) "cms"
26) "bloom"
27) "cuckoo"
28) "topk"
29) "timeseries"

如您所见,目前共有 29 个不同的类别。现在让我们检查一下哪些命令属于 geo 类别。

> ACL CAT geo
1) "geohash"
2) "georadius_ro"
3) "georadiusbymember"
4) "geopos"
5) "geoadd"
6) "georadiusbymember_ro"
7) "geodist"
8) "georadius"
9) "geosearch"
10) "geosearchstore"

请注意,命令可能属于多个类别。例如,ACL 规则 +@geo -@read 将导致某些地理空间命令被排除,因为它们是只读命令。

允许/阻止子命令

从 Redis 7.0 开始,可以像其他命令一样允许/阻止子命令(通过在命令和子命令之间使用分隔符 |,例如:+config|get-config|set)。

这适用于除 DEBUG 之外的所有命令。要允许/阻止特定的 DEBUG 子命令,请参阅下一节。

允许被阻止命令的第一个参数

注意:此功能已在 Redis 7.0 中弃用,将来可能被移除。

有时,仅仅排除或包含整个命令或子命令是不够的。许多部署可能不乐意提供对任何 DB 执行 SELECT 的能力,但可能仍然希望能够运行 SELECT 0

在这种情况下,我们可以按以下方式修改用户的 ACL:

ACL SETUSER myuser -select +select|0

首先,移除 SELECT 命令,然后添加允许的 first-arg。请注意,反过来操作是不可能的,因为 first-args 只能添加,不能排除。为某个用户指定所有有效的 first-args 会更安全,因为将来可能会添加新的 first-args。

另一个示例

ACL SETUSER myuser -debug +debug|digest

请注意,first-arg 匹配可能会带来一些性能开销;然而,即使使用合成基准测试也很难衡量。额外的 CPU 成本只在这种命令被调用时产生,而不是在调用其他命令时产生。

可以使用这种机制来允许在 Redis 7.0 版本之前使用子命令(参见上面章节)。

+@all 对比 -@all

在上一节中,我们看到了如何基于添加/移除单个命令来定义命令 ACL。

选择器

从 Redis 7.0 开始,Redis 支持添加多组规则,这些规则相互独立评估。这些次要的权限集合称为选择器,通过将一组规则包含在括号内来添加。要执行命令,根权限(括号外定义的规则)或任何选择器(括号内定义的规则)必须与给定命令匹配。在内部,首先检查根权限,然后按添加顺序检查选择器。

例如,考虑一个 ACL 规则为 +GET ~key1 (+SET ~key2) 的用户。该用户能够执行 GET key1SET key2 hello,但不能执行 GET key2SET key1 world

与用户的根权限不同,选择器一旦添加就无法修改。相反,可以使用 clearselectors 关键字移除选择器,该关键字将移除所有已添加的选择器。请注意,clearselectors 不会移除根权限。

键权限

从 Redis 7.0 开始,键模式也可以用来定义命令如何操作键。这通过定义键权限的规则来实现。键权限规则的形式为 %(<permission>)~<pattern>。权限被定义为单个字符,这些字符映射到以下键权限:

  • W (写): 键中存储的数据可能被更新或删除。
  • R (读): 处理、复制或返回键中用户提供的数据。请注意,这不包括元数据,例如大小信息(例如 STRLEN)、类型信息(例如 TYPE)或关于某个值是否存在于集合中的信息(例如 SISMEMBER)。

权限可以通过指定多个字符来组合。将权限指定为 'RW' 被视为完全访问,类似于只传入 ~<pattern>

举个具体例子,考虑一个 ACL 规则为 +@all ~app1:* (+@read ~app2:*) 的用户。该用户对 app1:* 拥有完全访问权限,对 app2:* 拥有只读访问权限。然而,有些命令支持从一个键读取数据,进行一些转换,然后存储到另一个键。其中一个命令是 COPY 命令,它将数据从源键复制到目标键。示例中的 ACL 规则集无法处理将数据从 app2:user 复制到 app1:user 的请求,因为根权限和选择器都不能完全匹配该命令。但是,使用键选择器,您可以定义一组可以处理此请求的 ACL 规则: +@all ~app1:* %R~app2:*。第一个模式能够匹配 app1:user,第二个模式能够匹配 app2:user

命令需要哪种类型的权限,这通过键规范文档记录。权限类型基于键的逻辑操作标志。插入、更新和删除标志映射到写键权限。访问标志映射到读键权限。如果键没有逻辑操作标志,例如 EXISTS,用户仍然需要键的读权限或写权限才能执行该命令。

注意:在评估执行命令是否需要读权限时,访问用户数据的侧信道会被忽略。这意味着某些返回关于修改键的元数据的写命令,只需要对该键有写权限即可执行。例如,考虑以下两个命令:

  • LPUSH key1 data: 修改 "key1",但只返回关于它的元数据(push 后列表的大小),因此该命令只需对 "key1" 有写权限即可执行。
  • LPOP key2: 修改 "key2",但也返回其中的数据(列表中最左边的项),因此该命令需要对 "key2" 同时具有读权限和写权限才能执行。

如果应用程序需要确保不会从键中访问任何数据,包括侧信道,建议不提供对该键的任何访问权限。

密码在内部如何存储

Redis 在内部使用 SHA256 散列存储密码。如果您设置了密码并检查 ACL LISTACL GETUSER 的输出,您会看到一个看起来像伪随机的长十六进制字符串。这是一个示例,因为在之前的示例中,为了简洁起见,长十六进制字符串被截断了:

> ACL GETUSER default
1) "flags"
2) 1) "on"
3) "passwords"
4) 1) "2d9c75273d72b32df726fb545c8a4edc719f0a95a6fd993950b10c474ad9c927"
5) "commands"
6) "+@all"
7) "keys"
8) "~*"
9) "channels"
10) "&*"
11) "selectors"
12) (empty array)

使用 SHA256 可以在避免以明文存储密码的同时,仍然允许非常快速地执行 AUTH 命令,这是 Redis 的一个非常重要的特性,并且与客户端对 Redis 的期望一致。

然而,ACL 的密码并非真正的密码。它们是服务器和客户端之间的共享秘密,因为密码不是人类使用的身份验证令牌。例如:

  • 没有长度限制,密码只会存储在某些客户端软件中。在这种情况下,不需要人类记住密码。
  • ACL 密码不保护任何其他东西。例如,它永远不会是某个电子邮件账户的密码。
  • 通常,当您能够访问散列密码本身时(通过完全访问给定服务器的 Redis 命令,或者破坏系统本身),您实际上已经能够访问该密码所保护的内容:Redis 实例的稳定性和其中包含的数据。

因此,为了使用消耗时间和空间的算法来增加密码破解难度而降低密码认证速度,这是一个非常糟糕的选择。我们建议改为生成强密码,这样即使拥有散列值,也没有人能够使用字典或暴力攻击来破解它。为此,有一个特殊的 ACL 命令 ACL GENPASS,它使用系统的加密伪随机生成器生成密码:

> ACL GENPASS
"dd721260bfe1b3d9601e7fbab36de6d04e2e67b0ef1c53de59d45950db0dd3cc"

该命令输出一个 32 字节(256 位)的伪随机字符串,转换为 64 字节的字母数字字符串。这足够长以避免攻击,又足够短以便于管理、复制粘贴、存储等等。这就是您应该用来生成 Redis 密码的方法。

使用外部 ACL 文件

在 Redis 配置中有两种存储用户的方法:

  1. 用户可以直接在 redis.conf 文件中指定。
  2. 可以指定一个外部 ACL 文件。

这两种方法是互不兼容的,所以 Redis 会要求您使用其中一种。在 redis.conf 中直接指定用户适用于简单用例。当需要定义多个用户时,在复杂的环境中,我们建议您使用 ACL 文件。

redis.conf 和外部 ACL 文件中使用的格式完全相同,因此从一种切换到另一种非常容易,格式如下:

user <username> ... acl rules ...

例如:

user worker +@list +@connection ~jobs:* on >ffa9203c493aa99

当您想使用外部 ACL 文件时,需要指定名为 aclfile 的配置指令,如下所示:

aclfile /etc/redis/users.acl

如果您只是在 redis.conf 文件中直接指定少量用户,可以使用 CONFIG REWRITE 命令通过重写文件来存储新的用户配置。

然而,外部 ACL 文件功能更强大。您可以执行以下操作:

  • 如果您手动修改了 ACL 文件并希望 Redis 重新加载新配置,请使用 ACL LOAD。请注意,此命令仅在所有用户都正确指定时才能加载文件。否则,将向用户报告错误,并且旧配置将保持有效。
  • 使用 ACL SAVE 将当前的 ACL 配置保存到 ACL 文件。

请注意,CONFIG REWRITE 不会触发 ACL SAVE。当您使用 ACL 文件时,配置和 ACL 是分开处理的。

Sentinel 和 Replicas 的 ACL 规则

如果您不想为 Redis 副本和 Redis Sentinel 实例提供对其 Redis 实例的完全访问权限,则必须允许以下命令集才能使一切正常工作。

对于 Sentinel,允许用户在主实例和副本实例中访问以下命令:

  • AUTH, CLIENT, SUBSCRIBE, SCRIPT, PUBLISH, PING, INFO, MULTI, SLAVEOF, CONFIG, CLIENT, EXEC.

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 副本需要在主实例上允许以下命令:

  • PSYNC, REPLCONF, PING

不需要访问任何键,因此这转化为以下规则:

ACL setuser replica-user on >somepassword +psync +replconf +ping

请注意,您不需要配置副本以允许主实例执行任何命令集。从副本的角度来看,主实例始终以 root 用户身份进行身份验证。

评价此页
返回顶部 ↑