4. 认证与密码策略

Redis 默认监听 6379 端口且不要求任何认证,只要网络可达,任何人都能执行 CONFIG SET、FLUSHALL 甚至 MODULE LOAD。认证与密码策略要解决的核心问题不是"加一个密码",而是把"谁能连、能连什么、能做什么、凭据怎么存、多久换一次"这五件事同时管住。本节围绕 requirepass、ACL 用户体系、密码轮换与凭据保护展开。

一、从 requirepass 到 ACL:认证能力的演进

Redis 6 之前只有单一密码:在 redis.conf 中设置 requirepass,客户端用 AUTH password 认证。它的问题很明显——所有客户端共享同一口令,权限无法区分,一旦泄露等于全库失守。Redis 6 引入 ACL(Access Control List),把"认证"和"授权"合并到用户维度:每个用户有自己的密码列表、可执行的命令、可访问的键模式。旧版 requirepass 在 ACL 体系下等价于给 default 用户设置密码。

因此现代部署应优先使用 ACL 多用户模型,而不是继续沿用单一 requirepass。下面这张图展示了从连接建立到命令放行的完整判定链,也是本节所有配置的落点。

Redis ACL 认证与授权判定链 客户端连接 AUTH user pass ① 认证 校验用户密码列表 SHA256 比对 ② 命令授权 命令白名单 / 黑名单 +@read -@dangerous ③ 键模式授权 ~app:cache:* ~session:* 命令放行并执行 返回结果给客户端 拒绝:NOPERM / WRONGPASS 记录日志,不执行 命令/键不匹配 密码在服务端的存储形态 ACL SETUSER app >明文密码 → 内部转为 SHA256 十六进制摘要保存 → ACL LIST / ACL GETUSER 只显示哈希 → 支持 #哈希 直接写入,避免明文落盘 → 明文只应出现在受控的配置注入环节 凭据泄露的常见入口 • 命令行 -a 参数进入 shell history / ps • 代码仓库硬编码 redis://:pass@host • redis.conf 权限过宽被其他用户读取 • 慢查询日志 / MONITOR 输出带出 AUTH • 备份 RDB/AOF 中包含 ACL 摘要

二、强密码的生成与判定标准

Redis 密码没有复杂度强制校验,服务端不会拒绝弱口令,所以强度必须由生成侧保证。可用的判定标准是:长度不低于 24 字符,包含大小写字母、数字与符号中的至少三类,且不来自字典词、项目名、主机名或键盘序列。更实际的做法是直接使用密码管理器或 openssl rand 生成高熵随机串:

# 生成 32 字节随机密码(base64 后约 44 字符)
openssl rand -base64 32
# 示例输出(每次不同):
# 7Kq2mZx9vLpR4tNw8sYbHc3fJd6gAe1uQo5iXr0nMk=

# 生成 SHA256 摘要,用于写入 ACL 而不落明文
echo -n '7Kq2mZx9vLpR4tNw8sYbHc3fJd6gAe1uQo5iXr0nMk=' | sha256sum
# 输出形如:a3f1...(64 位十六进制)

需要强调的是,ACL SETUSER 接受明文密码后会在内存中转为 SHA256 摘要,ACL LIST 与 ACL GETUSER 回显的都是哈希值,不会回显明文。因此把哈希写进配置文件是可行且更安全的:ACL SETUSER app #a3f1...c9。这样即使配置文件被读取,攻击者也无法直接还原口令,只能做离线爆破——而 32 字节随机串的爆破成本极高。

三、多用户 ACL 的落地配置

下面给出一份可直接参考的 ACL 配置示例,按"应用读写用户、只读报表用户、运维管理用户"三类角色划分。示例中的键前缀与命令集属于教学假设,实际使用时替换为业务真实命名空间。

# 关闭 default 用户的远程使用能力,仅保留本地管理
ACL SETUSER default off

# 应用读写用户:只能操作 app: 前缀的键,禁止危险命令
ACL SETUSER app_rw on #a3f1...c9 ~app:* &app:* +@read +@write +@keyspace -@dangerous -flushall -flushdb -config -shutdown

# 报表只读用户:只读,且限制在 report: 前缀
ACL SETUSER report_ro on #b7d2...4e ~report:* +@read -@write -@dangerous

# 运维管理用户:全权限,但仅允许从管理网段登录
ACL SETUSER ops_admin on #c9e4...1a ~* &* +@all

# 持久化到配置文件,重启后仍生效
ACL SAVE

配置完成后用 ACL LIST 核对,再用 ACL WHOAMI 确认当前连接身份。验证时不要只看"能连上",要主动测试越权:用 app_rw 执行 GET report:daily 应返回 NOPERM,用 report_ro 执行 SET app:x 1 也应被拒绝。只有拒绝路径被验证过,授权边界才算真正建立。

ACL 规则中的 ~ 是键模式,& 是 Pub/Sub 频道模式,+/- 是命令或命令类别的允许/禁止。命令类别如 @read、@write、@dangerous 由 Redis 内置,比逐条列举命令更易维护。

四、密码轮换:如何做到不断连

ACL 用户支持同时持有多个密码,这是实现平滑轮换的关键。轮换流程分四步:先给用户追加新密码,再让应用切换到新密码,确认旧密码无连接使用后删除旧密码,最后 ACL SAVE。整个过程不需要重启 Redis,也不会中断现有连接。

# 1. 追加新密码(旧密码仍有效)
ACL SETUSER app_rw >新密码明文

# 2. 应用侧灰度切换连接池,逐步使用新密码

# 3. 观察一段时间后,移除旧密码
ACL SETUSER app_rw <旧密码明文

# 4. 持久化
ACL SAVE

轮换周期建议按凭据敏感度设定:面向公网或跨团队共享的凭据 30~90 天轮换一次,内部服务间凭据可放宽到 180 天,但一旦发生人员离职、日志泄露或代码仓库误提交,必须立即轮换。轮换动作本身要纳入变更记录,否则"上次换密码是什么时候"会成为排障时的盲区。

五、凭据泄露的防护要点

密码策略再强,也挡不住凭据从侧面流出。工程上要同时收紧几条路径:其一,禁止在命令行使用 -a 传密码,改用 REDISCLI_AUTH 环境变量或 --askpass 交互输入,避免密码进入 ps 输出和 shell 历史;其二,应用配置中的连接串改用密钥管理服务注入,不写入代码仓库;其三,redis.conf 与 ACL 文件权限设为 600 且属主为 redis 运行用户;其四,限制 MONITOR、SLOWLOG 的访问权限,这些命令可能带出认证上下文;其五,RDB/AOF 备份文件按敏感数据对待,加密存储并限制下载权限。

如果发现凭据可能已泄露,处理顺序是:先追加新密码并切换应用,再删除泄露密码,然后审计 ACL LOG 与慢查询日志确认是否有异常命令执行,最后检查是否被写入持久化后门(如异常 ACL 用户、异常键)。不要只改密码就认为事件结束。

六、上线前的认证检查清单

检查项合格标准验证方式
default 用户状态远程不可用或已设强密码ACL LIST 查看 default 行
密码强度≥24 字符,高熵随机生成侧核对,非人工构造
密码存储配置中为 SHA256 哈希ACL GETUSER 回显为哈希
权限最小化按角色限定命令与键前缀越权命令返回 NOPERM
轮换机制支持多密码并存切换追加新密码后旧连接不受影响
凭据入口无命令行明文、无仓库硬编码检查启动脚本与代码配置
持久化ACL 规则已 SAVE 且文件权限 600重启后 ACL LIST 一致