当前位置:首页 > 文章列表 > 数据库 > Redis > Redis ACL 怎样只允许消费者读取指定命令

Redis ACL 怎样只允许消费者读取指定命令

来源:17golang原创 2026-10-26 01:55:38 0浏览 收藏

消费者账号明明只需要读取几类数据,却经常因为一条宽泛的 ACL 规则拿到了不该拥有的命令权限。更稳妥的做法是把“能调用哪些命令”和“这些命令能碰哪些 key”分开收紧:命令逐条放行,key 用前缀限制,最后分别测试成功和拒绝结果。

官方资料:https://redis.io/docs/latest/operate/oss_and_stack/management/security/acl/

如果目标是“只允许消费者读取指定命令”,不要从 +@all 或宽泛的 +@read 开始。先清空旧规则,再只加入业务真正需要的读取命令,并配上允许访问的 key 模式。

先把消费者的读取动作列成白名单

我排查这类权限时,第一步不会先改 ACL,而是把消费者代码里实际发出的 Redis 命令列出来。假设这个消费者只读 consumer:orders: 前缀下的字符串、哈希和列表数据,那么最小集合可以是 GET、MGET、EXISTS、HGET、HGETALL、LRANGE,以及用于观察生命周期的 TTL、PTTL。

这里故意不使用 +@read。命令分类适合快速了解一组能力,但它会让白名单随 Redis 命令分类变化而扩大;如果业务要求“指定命令”,逐条列出更容易审计。还要单独决定是否允许 PING、SELECT 或事务命令,它们不是数据读取本身,不能因为客户端习惯就顺手放开。

创建用户时同时收紧命令和 key

下面的示例创建一个名为 order_consumer 的用户。reset 先清理已有权限,on 允许用户登录;后面的每个 +command 是精确的命令白名单,~consumer:orders:* 则把 key 范围限制在订单消费者数据前缀内。

# 创建只读消费者:先清掉旧规则,再逐条放行真实需要的读取命令
redis-cli ACL SETUSER order_consumer reset on \
  '>replace-with-a-strong-password' \
  '~consumer:orders:*' \
  '+PING' '+GET' '+MGET' '+EXISTS' \
  '+HGET' '+HGETALL' '+LRANGE' '+TTL' '+PTTL'

# 查看用户当前的完整规则,确认没有遗留的宽泛权限
redis-cli ACL GETUSER order_consumer

密码只是示例占位符,生产环境不要把真实密码写进脚本仓库或文章。需要注意,ACL 是累积规则,单独追加几条 +GET 并不能保证旧的 +@all 已被移除,所以示例把清理动作放在最前面。

Redis ACL 将消费者命令白名单与 consumer orders key 前缀连接起来的结构说明图
图1:结构说明图,展示消费者账号、逐条读取命令和 key 前缀之间的静态授权关系,不是终端截图或运行证据。

用 ACL CAT 辅助检查,但不要让分类替代白名单

当你不确定某个命令是否属于读取类别时,可以让 Redis 自己列出分类内容。这个动作用于查目录,不代表要把整个分类授予消费者。

# 查看 Redis 当前提供的 ACL 命令分类
redis-cli ACL CAT

# 查看 read 分类包含哪些命令,用来核对客户端真实调用
redis-cli ACL CAT read

# 查看某个用户的命令、key 模式和状态
redis-cli ACL GETUSER order_consumer

Redis 官方文档还特别提醒:模块命令不一定包含在普通命令分类中。如果消费者读取的是 RedisJSON、Search 等模块数据,不能因为 +@read 看起来合理就假设模块命令自动可用;应查清实际命令后显式加入,并继续限制它能接触的 key。

先验证允许的命令能读到正确数据

权限排查不能只看 ACL GETUSER 的文字结果,还要用消费者账号建立一次真实连接。下面把允许的读取动作集中测试,成功结果说明命令白名单和 key 前缀至少在正向路径上匹配。

# 用消费者身份读取允许范围内的 key,密码请替换成实际密钥
redis-cli --user order_consumer --pass 'replace-with-a-strong-password' GET consumer:orders:1001

# 验证哈希、列表和 TTL 读取动作仍然属于允许集合
redis-cli --user order_consumer --pass 'replace-with-a-strong-password' HGETALL consumer:orders:1001
redis-cli --user order_consumer --pass 'replace-with-a-strong-password' LRANGE consumer:orders:queue 0 9
redis-cli --user order_consumer --pass 'replace-with-a-strong-password' TTL consumer:orders:1001

如果这里返回的是业务数据或合法的空结果,说明请求没有被 ACL 拦截;空数据本身不等于权限失败。要把“key 不存在”和“权限不足”区分开,后面还必须测试明确不允许的命令。

再验证未列出的命令会被拒绝

消费者不应该拥有写入、删除、配置或权限管理能力。测试时可以挑一个明显不在白名单里的命令,例如 SET 或 DEL。预期结果是 Redis 返回权限错误,而不是客户端静默成功。

# SET 没有加入白名单,预期返回 command not allowed 类似的权限错误
redis-cli --user order_consumer --pass 'replace-with-a-strong-password' SET consumer:orders:test value

# DEL 同样没有加入白名单,预期被拒绝,不能因为 key 前缀匹配就放行
redis-cli --user order_consumer --pass 'replace-with-a-strong-password' DEL consumer:orders:1001

# CONFIG 和 ACL 属于管理能力,预期同样被拒绝
redis-cli --user order_consumer --pass 'replace-with-a-strong-password' CONFIG GET maxmemory

这三次测试能说明一个重要边界:key pattern 只决定命令能访问哪些 key,不能把一个原本没有命令权限的 SET、DEL 或 CONFIG 变成可用命令。

最后测试越界 key,区分两层拒绝原因

如果消费者拿着允许的 GET 去读取 admin:secret,命令本身是白名单内的,但 key 不匹配 consumer:orders:*,预期仍然被拒绝。这一步能防止排查时只验证“允许的命令”,却忘记验证“允许的对象”。

# GET 是允许命令,但 admin:secret 不符合 key 前缀,预期因 key 权限被拒绝
redis-cli --user order_consumer --pass 'replace-with-a-strong-password' GET admin:secret

# 同一个允许命令访问 consumer:orders 前缀,作为对照应能正常返回或返回空值
redis-cli --user order_consumer --pass 'replace-with-a-strong-password' GET consumer:orders:missing

可以把结果记成一张小表:

测试命令是否在白名单key 是否匹配预期
GET consumer:orders:1001是是返回数据或空值
SET consumer:orders:test否是命令权限错误
GET admin:secret是否key 权限错误
Redis ACL 允许命令、未授权命令和越界 key 三种结果边界对比图
图2:结果边界说明图,对比命令白名单和 key pattern 分别导致的成功、命令拒绝与 key 拒绝,不是实际运行输出截图。

规则变更时只改动必要的一条

消费者新增读取动作时,先在代码或调用日志中确认具体命令,再追加一条最小规则,例如需要读取集合长度时只增加 +SCARD,不要为了省事切换成 +@read。变更后重复三组测试:允许命令、未授权命令、越界 key。

如果使用 Redis 7 及以上的 key 权限能力,还可以根据业务需要使用读写权限模式;但本文的消费者示例用普通只读 key pattern 已经足够表达范围。对于没有 key 参数、作用于整个数据库的命令,key pattern 不能替代命令级禁止,因此更要避免把 FLUSHALL、FLUSHDB、SWAPDB 等管理或破坏性命令放进消费者权限。

总结:用两张清单判断 ACL 是否收紧

Redis ACL 的最小消费者权限可以归纳为两张清单:第一张是逐条列出的命令白名单,第二张是允许访问的 key pattern。ACL GETUSER 用来检查配置,ACL CAT 用来查命令分类,真实请求则要同时覆盖允许命令、未授权命令和越界 key。只要这三组结果与预期一致,才能说明“指定命令”和“指定 key”两层边界都生效。

相关问题:

  • 为什么 +@read 不能直接等同于业务需要的读取白名单?
  • Redis ACL 的 key pattern 能限制没有 key 参数的管理命令吗?
  • 消费者需要读取 Redis 模块命令时,为什么要显式添加命令?
  • 怎样用 ACL LIST 记录用户规则变更?
版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Redis Pub/Sub 与 Streams 怎样按是否持久化选择Redis Pub/Sub 与 Streams 怎样按是否持久化选择
上一篇
Redis Pub/Sub 与 Streams 怎样按是否持久化选择
VS Code 怎样为工作区设置默认终端配置文件
下一篇
VS Code 怎样为工作区设置默认终端配置文件
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之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模型性能。
    693次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    706次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    774次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    734次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    568次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码