Redis 6.0 ACL 权限控制:告别“一把钥匙开所有门”的安全隐患
旧版 Redis 仅靠一套密码通行全局,获取密码后即可执行FLUSHALL、KEYS *、DEBUG SEGFAULT,甚至随意订阅任意频道。这听似夸张,却曾是 Redis 安全管理的真实写照。简而言之:一个密码 = 全部命令 + 全部键 + 全部数据库。
多租户或微服务共享实例时,这种权限设计堪称灾难。项目 A 的缓存键 user:123 与项目 B 的支付流水 payment:txn_456 挤在同一实例中,却共用同一套凭证。一旦某个应用被攻破,相当于所有数据都暴露在“万能钥匙”之下。

Redis 6.0 引入 ACL 并非锦上添花的“功能增强”,而是直击旧版最大短板:将“谁可以运行哪些命令”与“谁可以读写哪些键”彻底拆解,精确到单个用户粒度。这才是 ACL 真正的核心价值所在。
用户正常运行需满足三要素,缺一不可
你以为给用户设置密码就能正常使用?其实远远不够。一个用户必须同时满足以下三项配置,否则即便认证通过,Redis 也会直接拒绝执行命令:
on:用户必须处于启用状态。若设置为off,密码再正确也无济于事。- 至少一个有效密码:使用
>password指定明文密码,或#hash指定SHA256摘要。除非你刻意允许免密登录(nopass),否则密码不可省略。 - 显式授予命令权限:默认新建用户为
-@all,即所有命令均被拒绝。必须通过+@read、+get、+@all等规则明确开放相应权限。
举一个常见误区:仅执行ACL SETUSER alice on >p1pp0,用户alice依然什么都做不了——因为未授予任何命令权限。必须补充类似+@read的规则,alice 才能真正开始工作。
键权限(~pattern)不只是通配符的简单补丁,背后有完整的匹配引擎
键模式使用~前缀,底层采用 glob 风格匹配(并非完整正则表达式,但常用通配符均可支持),具体规则如下:
~user:*→ 匹配user:1、user:profile:abc~order/202[4-6]/*→ 匹配order/2025/123,但不匹配order/2023/456~*→ 允许所有键(等价于旧版行为)~cache:img:* ~cache:json:*→ 多个模式需分开书写,以空格分隔
这里容易陷入一个认知误区:键权限仅管控“已知键的操作”,并不会自动放开元操作。例如KEYS *命令本身受命令权限控制——即使你授予了~*键权限,若未给予+keys,Redis 依然会拒绝执行。简单来说,命令权限与键权限是两把独立的锁,彼此无法替代。
ACL SAVE 并不等于“永久生效”,它高度依赖文件路径与写入权限
运行期执行的ACL SETUSER仅存在于内存中,重启即消失。要持久化保存,必须调用ACL SAVE。但此命令并非随意写入任意位置——它仅覆盖 redis.conf 中aclfile指定的路径(默认通常是users.acl,而非主配置文件本身)。
- 若 redis.conf 中未配置
aclfile /etc/redis/users.acl,ACL SAVE会静默失败——返回 OK 但实际未写入任何内容。 - 如果目录
/etc/redis/Redis 进程没有写入权限,则会报错:(error) ERR Error writing ACL file: Permission denied。 - 正确做法是:首先确保
aclfile路径在 redis.conf 中存在且可写,然后执行ACL SAVE,最后可再运行一次CONFIG REWRITE(可选)或直接重启验证。
最容易出问题的是容器部署场景:很多情况下 redis.conf 为只读挂载,ACL SAVE看似执行成功,实际落盘失败。等下次重启时,所有用户配置全部恢复初始状态——这个坑几乎每周都有人踩,务必提前检查文件权限与路径配置。
