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 密码没有复杂度强制校验,服务端不会拒绝弱口令,所以强度必须由生成侧保证。可用的判定标准是:长度不低于 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 也应被拒绝。只有拒绝路径被验证过,授权边界才算真正建立。
~ 是键模式,& 是 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 一致 |