好的,没问题,我们直接开始!
各位观众,晚上好!欢迎来到“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 的访问日志,及时发现异常行为。
-
禁用
FLUSHALL
和FLUSHDB
: 除非绝对必要,否则应该禁用FLUSHALL
和FLUSHDB
命令,因为它们会清空所有数据。 可以使用ACL SETUSER
命令来禁止用户执行这些命令。ACL SETUSER the_user -FLUSHALL -FLUSHDB
-
利用 Category: 善用 Redis 内置的 Category,简化权限配置。例如,如果用户只需要读取数据,可以直接赋予
+@read
权限,而不需要逐个添加GET
、HGET
等命令的权限。
配置文件示例 (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 安全夜总会”就到这里。 感谢各位的参与,我们下次再见! 记住,数据安全,人人有责!