Redis 认证与授权:`requirepass` 与 ACL 权限管理 (Redis 6.0+)

好的,没问题,我们直接开始!

各位观众,晚上好!欢迎来到“Redis 安全夜总会”,我是今晚的特邀讲师,代号“数据守门员”。今天咱们聊点刺激的,聊聊 Redis 的认证与授权,特别是 Redis 6.0 以后推出的 ACL 权限管理。

别害怕,这不是什么高深的黑魔法,只要你跟着我的节奏,保证你也能成为 Redis 安全领域的老司机。

第一幕:密码,打开 Redis 大门的钥匙 (requirepass)

在 Redis 的早期,安全是个比较“简单”的概念,简单到什么程度呢?就好像你家的门锁是透明玻璃,谁都能看到里面有什么。那时候,只有一个全局密码 requirepass

  • 功能: 简单粗暴,开启 requirepass 后,客户端连接 Redis 必须提供密码才能执行任何操作。

  • 配置:redis.conf 文件中找到 requirepass 选项,设置一个强密码。

    requirepass your_super_secret_password
  • 如何使用:

    • 连接时: 在连接 Redis 的时候,提供密码。

      redis-cli -a your_super_secret_password

      或者,连接后使用 AUTH 命令认证:

      redis-cli
      127.0.0.1:6379> AUTH your_super_secret_password
      OK
  • 优点:

    • 简单易用,配置方便。
  • 缺点:

    • 全局密码,所有用户共享一个密码,权限无法细分。
    • 一旦密码泄露,所有数据都会暴露。
    • 无法针对不同用户进行权限控制,例如只允许读取某些 key,或者只允许执行某些命令。

场景模拟:

想象一下,你开了一家冰淇淋店,requirepass 就像你只给了一个员工一把总钥匙。他可以打开店门,卖冰淇淋,也可以偷偷吃掉你的配方,甚至把店里的钱卷走。

第二幕:ACL,让 Redis 安全更精细 (Redis 6.0+)

requirepass 在安全性方面的局限性显而易见。于是,Redis 6.0 引入了 Access Control List (ACL) 权限管理,让我们可以更精细地控制用户的访问权限。

  • ACL 是什么?

    ACL 就像一个权限清单,定义了用户可以执行哪些操作,访问哪些资源。 你可以为每个用户分配不同的 ACL 规则,实现更细粒度的权限控制。

  • ACL 的核心概念:

    • User (用户): 代表一个客户端连接 Redis 的身份。每个用户都有一个用户名和密码(可选)。
    • Category (类别): 代表一组 Redis 命令,例如 @read, @write, @admin, @slowlog, @pubsub, @keyspace, @bitmap, @list, @set, @sortedset, @hash, @string, @stream, @transactions, @connection, @geo, @scripting
    • Key Pattern (键模式): 允许用户访问特定的 key 或者 key 的集合,使用 glob 风格的模式匹配。
    • Command (命令): 允许用户执行特定的 Redis 命令。
    • Channel (频道): 允许用户订阅特定的频道(用于 Pub/Sub)。
  • ACL 规则语法:

    ACL 规则使用一种简单的文本语法来定义用户的权限。语法如下:

    user <username> [PASSWORD <password>|NOPASS] [RESET] [SETNAME <clientname>] [COMMAND +|-<command> ...] [CATEGORY +|-<category> ...] [KEYS +|-<keypattern> ...] [CHANNELS +|-<channelpattern> ...]
    • user <username>: 定义用户名。
    • PASSWORD <password>: 设置密码。 如果使用 NOPASS,则表示该用户不需要密码即可连接。
    • RESET: 重置用户的权限为默认值。
    • SETNAME <clientname>: 设置客户端名称。
    • COMMAND +|-<command> ...: 允许或禁止用户执行特定的命令。 + 表示允许,- 表示禁止。 可以使用 allcommands 表示所有命令。
    • CATEGORY +|-<category> ...: 允许或禁止用户执行某个类别的命令。 +@read 表示允许所有读取命令。
    • KEYS +|-<keypattern> ...: 允许或禁止用户访问匹配特定模式的 key。 +foo* 表示允许访问所有以 "foo" 开头的 key。
    • CHANNELS +|-<channelpattern> ...: 允许或禁止用户订阅匹配特定模式的频道。
  • ACL 命令:

    Redis 提供了一组命令来管理 ACL:

    • ACL SETUSER <username> <rules>: 创建或修改用户。
    • ACL GETUSER <username>: 获取用户的 ACL 规则。
    • ACL DELUSER <username> ...: 删除用户。
    • ACL LIST: 列出所有用户及其 ACL 规则。
    • ACL LOAD: 从配置文件重新加载 ACL 规则。
    • ACL CAT: 列出所有命令类别。
    • ACL WHOAMI: 返回当前连接的用户。
    • AUTH <username> <password>: 使用用户名和密码进行身份验证。

代码实战:

假设我们要创建一个用户 alice,密码是 alice_password,只允许读取以 user:* 开头的 key,并且只能执行 GET 命令。

redis-cli
127.0.0.1:6379> ACL SETUSER alice PASSWORD alice_password +GET KEYS user:*
OK

现在,我们创建一个用户 bob,不需要密码,可以执行所有读取命令,并且可以访问所有 key。

redis-cli
127.0.0.1:6379> ACL SETUSER bob NOPASS +@read +KEYS *
OK

查看 alice 的 ACL 规则:

redis-cli
127.0.0.1:6379> ACL GETUSER alice
1) "flags"
2) "on"
3) "passwords"
4) 1) "88a7f4881c1a59456433d1a877dc58c7a9053f66c4a0002c60020f8836688063"
5) "commands"
6) 1) "get"
7) "keys"
8) 1) "user:*"
9) "channels"
10) (empty array)

现在,我们用 alice 的身份连接 Redis:

redis-cli -u alice -p alice_password
127.0.0.1:6379> GET user:123
"Alice's data"
127.0.0.1:6379> SET user:123 "New data"
(error) NOPERM this user has no permissions to run the 'set' command or its subcommand
127.0.0.1:6379> GET other_key
(error) NOPERM this user has no permissions to access one of the keys required by the command

可以看到,alice 只能执行 GET 命令,并且只能访问以 user:* 开头的 key。 尝试执行 SET 命令或者访问其他 key 会报错。

现在,我们用 bob 的身份连接 Redis:

redis-cli -u bob
127.0.0.1:6379> GET user:123
"Alice's data"
127.0.0.1:6379> GET other_key
"Some other data"
127.0.0.1:6379> SET user:123 "Bob's data"
(error) NOPERM this user has no permissions to run the 'set' command or its subcommand

bob 可以执行所有读取命令,访问所有 key,但是不能执行 SET 命令。

ACL 规则详解:

规则 含义
+@all 允许执行所有命令。
-@all 禁止执行所有命令。
+@read 允许执行所有读取命令,例如 GET, STRLEN, HGET 等。
+@write 允许执行所有写入命令,例如 SET, HSET, DEL 等。
+@admin 允许执行管理命令,例如 CONFIG, SHUTDOWN 等。 谨慎使用!
+command 允许执行特定的命令,例如 +GET
-command 禁止执行特定的命令,例如 -SET
+KEYS pattern 允许访问匹配特定模式的 key,例如 +KEYS user:*。 可以使用 * 作为通配符。
-KEYS pattern 禁止访问匹配特定模式的 key,例如 -KEYS sensitive:*
+CHANNELS pattern 允许订阅匹配特定模式的频道,例如 +CHANNELS news:*
-CHANNELS pattern 禁止订阅匹配特定模式的频道,例如 -CHANNELS secret:*

场景模拟:

现在,你把冰淇淋店分成了不同的区域:前台、仓库、财务室。 ACL 就像你给不同的员工分配了不同的钥匙。 前台员工只能打开前台的门,卖冰淇淋;仓库员工只能打开仓库的门,管理库存;财务室员工可以打开财务室的门,处理账务。 这样,即使某个员工出了问题,也不会影响到其他区域的安全。

第三幕:ACL 最佳实践

  • 最小权限原则: 只授予用户完成任务所需的最小权限。 避免过度授权。

  • 使用密码: 尽量为每个用户设置密码。 不要使用空密码。

  • 定期审查: 定期审查 ACL 规则,确保权限设置仍然有效和安全。

  • 使用配置文件: 将 ACL 规则保存在配置文件中,方便管理和维护。 使用 ACL LOAD 命令加载配置文件。

  • 监控和审计: 监控 Redis 的访问日志,及时发现异常行为。

  • 禁用 FLUSHALLFLUSHDB: 除非绝对必要,否则应该禁用 FLUSHALLFLUSHDB 命令,因为它们会清空所有数据。 可以使用 ACL SETUSER 命令来禁止用户执行这些命令。

    ACL SETUSER the_user -FLUSHALL -FLUSHDB
  • 利用 Category: 善用 Redis 内置的 Category,简化权限配置。例如,如果用户只需要读取数据,可以直接赋予 +@read 权限,而不需要逐个添加 GETHGET 等命令的权限。

配置文件示例 (acl.conf):

user default on >some_very_complex_password allcommands allkeys allchannels

user alice on >alice_secret_password +GET +SET +INCR keys user:* channels news:*

user bob off # Disabled user.  Cannot authenticate

user monitor nopass +MONITOR +CLIENT keys * channels * # WARNING: powerful

然后,在 redis.conf 中添加:

aclfile /path/to/acl.conf

重启 Redis 服务,ACL 规则就会生效。

第四幕:高级技巧和注意事项

  • 用户名和密码的存储: Redis 内部存储密码的哈希值,而不是明文密码。
  • 客户端名称: 可以使用 CLIENT SETNAME 命令为客户端设置名称,方便监控和管理。 ACL 规则中也可以使用 SETNAME 选项为用户设置客户端名称。
  • 身份验证失败处理: 当客户端身份验证失败时,Redis 会返回 NOAUTH 错误。 客户端应该正确处理这个错误,并提示用户重新输入用户名和密码。
  • ACL 的持久化: ACL 规则会被持久化到 RDB 文件和 AOF 文件中,所以即使 Redis 重启,ACL 规则也不会丢失。
  • 与其他安全措施结合使用: ACL 只是 Redis 安全体系的一部分。 应该与其他安全措施结合使用,例如防火墙、SSL/TLS 加密等,才能构建更安全的 Redis 环境。

总结

requirepass 就像一把简单的门锁,适用于简单的场景,但安全性有限。 ACL 就像一套复杂的门禁系统,可以实现更精细的权限控制,适用于对安全性要求更高的场景。

选择哪种方案取决于你的实际需求。 如果你只需要简单的密码保护,requirepass 足够了。 如果你需要更细粒度的权限控制,ACL 是更好的选择。

记住,安全是一个持续的过程,需要不断地学习和改进。 希望今天的课程能帮助你更好地理解 Redis 的认证与授权,构建更安全的 Redis 应用。

好了,今天的“Redis 安全夜总会”就到这里。 感谢各位的参与,我们下次再见! 记住,数据安全,人人有责!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注