当前位置:首页 > 文章列表 > 数据库 > Redis > Redis ACL 怎样限制客户端只能访问指定命令

Redis ACL 怎样限制客户端只能访问指定命令

来源:17golang原创 2026-11-03 16:01:57 0浏览 收藏

Redis ACL 的关键不是只给客户端设置一个密码,而是同时限制“能执行哪些命令”和“这些命令能作用于哪些键”。如果一个缓存客户端只需要读取 cache: 前缀下的数据,可以创建一个新用户,给它 +get +mget,再给它 ~cache:*;这样它既不能执行 SET,也不能读取其他业务前缀。

官方地址:https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/

最稳妥的做法是从新用户的零权限状态开始,先写清楚命令集合,再写键模式,最后用 ACL GETUSER 和一组允许/拒绝请求复查。命令权限正确但键模式过宽,仍然不是最小权限。

先把命令权限和键权限分开

Redis ACL 的规则按从左到右应用,但不同规则解决的是不同问题:

规则限制对象示例
+get允许一个命令只允许读取字符串值
+@read允许一个命令类别允许读类命令集合
~cache:*允许访问的键模式只匹配 cache: 前缀
resetchannels清空 Pub/Sub 通道模式不让账号默认访问频道

因此,+get 不等于“可以读取所有键”,~cache:* 也不等于“可以执行读写命令”。两者需要一起出现,才能表达“只能用 GET 读取某个范围”。

Redis 客户端经过 AUTH、用户规则、命令权限和键模式检查后得到允许或 NOPERM 结果的静态结构图
图1:Redis ACL 请求过滤说明图,展示命令权限与键模式是两道独立判断,不是运行截图。

从零创建一个只读缓存用户

新建用户默认是关闭状态、没有密码、没有可执行命令,也没有键模式。可以利用这个安全起点明确写入完整规则。下面的示例给业务账号开放 GET 与 MGET,只允许访问 cache: 前缀。

# 使用管理员身份创建最小权限用户;密码占位符要替换为密钥管理系统提供的值
redis-cli --user admin --pass 'admin-password' ACL SETUSER cache_reader reset on >ReplaceWithLongSecret resetchannels ~cache:* +get +mget

# 查看用户最终的 flags、commands、keys 和 channels
redis-cli --user admin --pass 'admin-password' ACL GETUSER cache_reader

reset 会清掉旧密码、键模式、通道和命令授权,并把用户恢复到关闭且无权限的初始状态;随后再用 on、密码、键模式和命令规则逐项打开能力。这里显式加入 resetchannels,是为了避免把 Pub/Sub 访问范围和键访问混在一起。

生产环境不要把真实密码写进脚本或文章。示例中的 ReplaceWithLongSecret 只是占位符;创建用户后应通过安全的凭据分发方式让客户端使用双参数认证:

# 以明确的用户名认证,而不是继续依赖权限过大的 default 用户
redis-cli --user cache_reader --pass 'ReplaceWithLongSecret' GET cache:1234

精确命令和命令类别怎么选

如果业务调用面很小,精确列出命令最容易审查。例如只读一个字符串缓存时用 +get,批量读取再加上 +mget。如果业务会使用一组稳定的读命令,可以用 +@read,但它的范围比两个命令更大,升级或模块变化时需要重新检查。

# 先查看当前 Redis 实例中的命令类别,避免凭记忆猜类别内容
redis-cli --user admin --pass 'admin-password' ACL CAT read

# 精确授权:只允许 GET 和 MGET,适合调用面固定的缓存读取器
redis-cli --user admin --pass 'admin-password' ACL SETUSER cache_reader +get +mget

# 类别授权:适合读命令集合明确、可以接受更宽命令面的服务
redis-cli --user admin --pass 'admin-password' ACL SETUSER report_reader reset on >ReplaceWithLongSecret ~report:* +@read

不建议把 +@all -@dangerous 当作默认的“只读”方案。官方文档明确指出,+@all 还会包含模块加载的命令,而命令类别本身通常不包含模块命令;用“先全部允许再排除少量危险命令”的写法,很容易遗漏未来出现的能力。要限制一个业务账号,优先用精确命令或小范围类别。

Redis ACL 精确命令、命令类别和排除危险命令三种策略以及 cache 键范围的静态对比图
图2:权限策略对比说明图,展示命令集合大小与维护成本的取舍,不是 Redis 控制台截图。

键模式决定“能读哪里”

命令授权通过后,Redis 还会检查命令参数里涉及的键是否匹配用户的键模式。~cache:* 允许匹配 cache: 开头的键,不能把它误写成 ~*,后者会覆盖整个键空间。

# 为同一个用户增加第二个业务前缀;每个模式都应有明确的业务用途
redis-cli --user admin --pass 'admin-password' ACL SETUSER cache_reader ~session:*

# 如果决定完全替换旧的键范围,先清理再写入新模式
redis-cli --user admin --pass 'admin-password' ACL SETUSER cache_reader resetkeys ~cache:*

Redis 7 及以后还提供只读和只写键模式,例如 %R~cache:* 与 %W~cache:*。如果应用只需要读,可以把命令集合和键权限都收窄;不过最终仍要以目标 Redis 版本的命令参考和实际客户端调用面为准。

用 ACL GETUSER 和 NOPERM 复查结果

ACL GETUSER 返回 flags、密码摘要、commands、keys、channels 和 selectors 等字段。检查时至少确认四点:用户是 on、命令列表没有意外的 +@all、键模式没有无意的 ~*、通道权限符合业务需要。

# 读取机器可解析的用户描述;重点关注 commands、keys 和 channels
redis-cli --user admin --pass 'admin-password' ACL GETUSER cache_reader

# 允许的命令和键应成功,未授权的命令或键应返回 NOPERM
redis-cli --user cache_reader --pass 'ReplaceWithLongSecret' GET cache:1234
redis-cli --user cache_reader --pass 'ReplaceWithLongSecret' SET cache:1234 changed
redis-cli --user cache_reader --pass 'ReplaceWithLongSecret' GET other:1234

预期是第一条读取请求可以执行,后两条分别因没有 set 命令权限、键不匹配 cache:* 而返回 NOPERM。这组复查不会证明所有业务路径都覆盖到了,但可以快速发现最常见的“命令放宽”或“键范围放宽”。

增量修改时最容易踩的坑

多次调用 ACL SETUSER 不会自动重置已有用户,而是把新规则增量应用到当前用户。比如先加 +set,再加 +get,最后会同时拥有两个命令。需要重做权限时显式使用 reset,需要扩展权限时则把变更记录成可审查的最小差异。

另外,命令类别可能重叠,一个命令可以属于多个类别;不要只看类别名称推断最终集合,应该用 ACL CAT 列出当前实例的实际内容。对管理账号、迁移脚本和运维工具,更应该单独建立用户,避免把 CONFIG、FLUSHALL、DEBUG 等管理能力交给普通业务连接。

结论:按业务调用面给权限

业务场景命令策略键策略
只读缓存+get +mget~cache:*
报表读取经审查的 +@read~report:*
读写单一业务前缀精确列出读写命令~order:* 或更细的读写模式
运维管理独立账号,单独审批不要复用业务账号的键模式

相关问题

只写键模式能阻止客户端执行 SET 吗?

不能。键模式只限定键范围,仍然需要用命令规则控制 SET 或其他写命令。

+@read 是不是等于只读?

它表示允许当前实例定义的读类命令,不等于只允许某一两个命令;还要结合键模式,并检查命令类别实际内容。

为什么 ACL SETUSER 之后旧连接权限没有立刻符合预期?

ACL 规则修改的是用户权限,已有连接的认证状态和客户端调用仍要单独观察。先用新连接按用户名认证复查,再检查连接池是否复用了旧连接。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go testing.T.Name 怎样在辅助函数中获取当前测试名称Go testing.T.Name 怎样在辅助函数中获取当前测试名称
上一篇
Go testing.T.Name 怎样在辅助函数中获取当前测试名称
Kubernetes 原生 Sidecar Containers 稳定后怎样理解生命周期
下一篇
Kubernetes 原生 Sidecar Containers 稳定后怎样理解生命周期
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    859次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    864次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    940次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    919次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    749次使用