ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Redis密码设置与验证:从requirepass到ACL的完整安全链路

Redis密码设置与验证:从requirepass到ACL的完整安全链路 “Redis 密码设置和验证技巧”在面试题里通常被归成基础题但我做了这么多年后端和中间件相关的技术面试发现十个候选人里至少有四五个会在这道题上翻车。不是他们不知道requirepass而是不知道密码配完以后会发生什么连主从复制都会断、配置文件一改就起不来服务、密码在命令行里一敲就进了 shell history。这篇内容主要面向准备 Redis 面试的开发者以及正在维护 Redis 实例的运维和架构师我把平时工作中真正踩过的坑、验证过的命令和面试追问思路都整理出来照着看能省不少试错时间。1. 面试现场Redis 密码这道“送分题”为什么频频翻车1.1 我遇到过的候选人回答先还原一个比较典型的面试现场。我一般会从最基础的问法开始“Redis 怎么配置密码”候选人最常见的第一句是“修改 redis.conf 里的 requirepass”。然后我继续追问“如果线上 Redis 不能重启怎么让它立即生效”这时候就有不少人犹豫了能说出CONFIG SET requirepass的不到一半。再追问“设置完密码之后从库要做什么调整”能立刻想到masterauth的就更少了。到这里你会发现很多人所谓的“会 Redis 密码”其实只停留在“配置项叫什么”的层面。真正到了生产环境Redis 不是单机玩具它背后还跟着主从、哨兵、集群、各种客户端和可视化管理工具密码设置涉及的是一个完整的认证链路而不只是改一行配置。我还会问一个有点坑的问题“如果 Redis 密码忘了怎么办”不少人答不上来或者只想到去配置文件里看。实际上有几种合法思路一是直接改配置重启二是如果有CONFIG SET权限但还没来得及持久化重启后密码又变回去了这也是一个隐藏考点。1.2 看似简单背后的四个隐藏考点我把这类题目背后真正想考察的点拆成四块动态配置能力生产环境不能随便重启能不能通过CONFIG SET在线改密码改完以后怎么持久化。客户端认证方式redis-cli -a的参数用法、AUTH命令、错误信息对应的处置方法。分布式拓扑联动主从复制、哨兵、集群里各自怎么配密码改主库密码会不会拖垮整个架构。新版权限模型Redis 6 以后引入的 ACL 是否了解是否知道requirepass和 ACL 之间的关系。这四块正好对应本篇的后续章节。如果你能把这四条都讲清楚面试官基本会认为你不仅知道一个配置项而是理解 Redis 安全的完整链路。接下来我按操作顺序从最基本的“设置密码”开始讲再逐步升级到验证和分布式场景。2. 动手配置requirepass 的完整设置与持久化陷阱2.1 三种设置方式与适用场景先说最传统的requirepass。它是 Redis 配置文件redis.conf里的一个项默认被注释掉# requirepass foobared把注释去掉改成自己的密码保存重启读写任何 key 之前就得先AUTH。这是最笨但最直接的设置方式。适合新装实例也适合你在本地开发环境里模仿生产配置。第二种方式是运行中动态修改不用重启服务redis-cli -a 旧密码 CONFIG SET requirepass 新密码如果没有设置密码-a可以省略直接redis-cli CONFIG SET requirepass 新密码这种方式非常适合线上临时改密。因为重启 Redis 会带来连接闪断、缓存穿透、慢查询堆积等一系列连锁问题能用动态命令解决的尽量不要重启。第三种方式是把密码通过环境变量注入一般在容器化部署里用。比如 Docker 启动 Redis 时在 command 里加docker run -d --name redis \ -p 6379:6379 \ redis:7-alpine \ redis-server --requirepass ${REDIS_PASSWORD} --appendonly yes其中REDIS_PASSWORD由编排平台注入避免把明文密码写进镜像或者 docker-compose 文件。这个思路在生产环境非常常见也是面试时可以和容器化话题结合的加分项。2.2 CONFIG REWRITE 为什么不是万能动态CONFIG SET改完密码后可能遇到一个大坑它只对当前运行的内存配置生效不会自动写回配置文件。如果 Redis 进程重启密码会恢复成配置文件里的旧值。这句话很多面试候选人会答但真正到操作时还是会忘记做持久化。持久化的标准做法是在执行完CONFIG SET后再敲一条redis-cli -a 新密码 CONFIG REWRITECONFIG REWRITE会把当前内存中那些和默认值不一致的配置项写回 redis.conf包括你刚改的requirepass。但要注意它只对通过CONFIG SET修改过的参数有效手工手动编辑过的内容如果和当前运行态不一致有可能被覆盖。所以稳妥的顺序是先改配置文件再重启或者直接用CONFIG SETCONFIG REWRITE不要一边手动改文件一边动态设参。另外一个容易踩的坑是权限问题。有些 Redis 实例的运行用户对 redis.conf 没有写权限CONFIG REWRITE会报错ERR CONFIG REWRITE failed: Permission denied这时候你需要确认 Redis 进程的运行用户以及 redis.conf 文件属主。我曾经遇到一个用 root 启动、配置文件却属于 redis 用户的实例CONFIG REWRITE一直失败排查了半天才发现是文件权限问题。2.3 密码里的特殊字符与配置文件坑密码不是随便写个字符串就完事里面如果带了特殊字符配置文件里的表现会和你想象的不太一样。比如密码是abc123如果你用命令行方式把它直接拼进 redis.confrequirepass abc123Redis 对配置值的解析规则不算特别复杂但双引号、空格、反斜杠都会导致意外问题。最稳妥的办法是密码尽量只用字母、数字、下划线避免在生产配置里出现$、、空格这类容易被 shell 或配置文件误处理的字符。如果密码里非要包含特殊字符比如Pssw0rd2025#用命令行设置时一定要用单引号包住防止 shell 把#当成注释、把$当变量redis-cli CONFIG SET requirepass Pssw0rd2025#而在 redis.conf 里同样的密码建议直接写成requirepass Pssw0rd2025#这里可能有人问为什么 redis.conf 里要用双引号因为 Redis 配置解析器支持将带空格或特殊字符的值用引号包裹。如果不加引号像requirepass Pssw0rd2025#这种写法#之后的内容会被认为是注释吗实际测试下来redis.conf 中#只有在行首才是注释在值中间不会被吃掉。但为了统一和防呆带特殊字符的值我还是建议加引号。再提醒一点不要在 shell 命令行里长时间保留含密码的历史记录。这个细节下一章详细展开。3. 客户端与运维工具里的密码验证细节3.1 redis-cli 常见用法与明文密码风险设置好密码之后怎么验证最直接的方式是使用AUTH命令redis-cli 127.0.0.1:6379 AUTH your_password OK 127.0.0.1:6379 PING PONG这里如果没认证就执行PING会看到(error) NOAUTH Authentication required.这是最常见也最直接的一条验证反馈。另一个常见操作是使用-a参数一条命令完成认证和操作redis-cli -a your_password PING注意Redis 6 之后在命令行使用-a会打印一条警告Warning: Using a password with -a or -u option on the command line interface may not be safe.这是因为-a后面的明文密码会被进程列表和 shell history 记录。如果你手滑在团队共用机器上这么干密码就相当于裸奔了。更安全的替代方案是设置环境变量后用--no-auth-warning抑制警告或者干脆交互式输入。比如用REDISCLI_AUTH环境变量export REDISCLI_AUTHyour_password redis-cli --no-auth-warning PING这样密码至少不会出现在命令行参数里只是会留在环境变量中比直接明文参数安全一些但仍然只能在信任环境中使用。如果你用redis-cli --user指定用户同时用--pass传密码可以显式指定 ACL 用户redis-cli --user alice --pass alice_pass PINGRedis 6 之后客户端可见的认证方式已经不再局限于requirepass对应的单用户模式--user和--pass是更完整的认证参数组合。这套东西在面试里展开讲会非常加分第五章我们再细说。3.2 可视化管理工具连接配置日常开发里很多人习惯用 Redis Desktop Manager 或 Another Redis Desktop Manager 连接 Redis。这些工具的配置界面都有一个“密码”字段直接把requirepass里的密码填进去就能连。但有几个细节需要注意。第一如果你用的是主从架构连接从节点的只读地址时也要提交正确的认证信息。从节点同样需要密码验证否则用不含密码的客户端连接会一直提示NOAUTH。第二很多可视化客户端默认保存密码到本地的密钥链或配置文件里如果你是在公共电脑上调试记得不要勾选“保存密码”。第三工具软件版本过老时对 Redis 6 默认用户名default的处理可能不完善需要用户名字段填default密码填你设置的requirepass值。换个最新版本一般都能解决。生产环境还有一个容易被忽略的点可视化管理工具建议只绑到内网或跳板机不要直接把 Redis 的 6379 端口映射到公网。因为即使设置了密码也挡不住暴力破解和 DDoS尤其是很多工具为了易用性默认禁用保护模式暴露公网基本等于开门揖盗。3.3 常见报错信息与排查对照表我把密码相关的高频报错和排查思路整理成一张表方便大家在实际操作时对照报错信息含义排查方向NOAUTH Authentication required.连接后未认证执行AUTH或在客户端配置密码WRONGPASS invalid username-password pair or user is disabled.用户名或密码错误确认requirepass值、ACL 用户状态ERR Client sent AUTH, but no password is set.服务端没配密码客户端却发了 AUTH检查目标实例是不是密码配错了实例ERR AUTH password called without any password configured for the default user. Are you sure your configuration is correct?给 default 用户发 AUTH但 default 用户无密码确认是否改了 ACL 而不是 requirepassCONFIG SET failed: Permission denied当前用户没权限改配置检查 ACL 中用户是否含 CONFIG SET 权限这里重点解释第二个WRONGPASS是 Redis 6 之后对认证失败的标准返回。以前老版本可能只显示ERR invalid password现在则明确提示“用户名-密码对无效或用户被禁用”。如果你看到这个报错第一反应是核对密码本身第二反应是看看是不是命中了 ACL 禁用。还有一个奇怪场景客户端输入密码连接时提示ERR Client sent AUTH, but no password is set。这说明你连的根本不是你认为的那个 Redis 实例可能是端口转发指错机器、Docker 端口映射绑到了错误的容器或者requirepass配置被注释了。这类问题通常不是密码维度而是网络拓扑层面的排查。4. 分布式场景下的密码联动主从、哨兵与集群4.1 主从复制必须配 masterauthRedis 密码设置最容踩的大坑往往不是认证本身而是设置完主库密码之后从库悄悄断开了。为什么会断因为从库要连主库同步数据它自己也得通过主库的认证。如果你只在主库设置了requirepass却没有在从库配置文件里告诉它“用这个密码去连主库”从库一启动就会反复尝试连接主库然后被NOAUTH挡住。解决办法是在从库的 redis.conf 中设置masterauth 你的主库密码这句话和主库的requirepass不是同一个配置项。很多人会搞混以为在主库配了masterauth就行。不是的requirepass是“本实例接受哪些客户端访问”masterauth是“本实例作为从库时如何认证主库”。两个配置方向不同经常要同时设置。假设我们有一个主节点和一个从节点主节点 redis.confbind 0.0.0.0 requirepass MasterPass masterauth MasterPass从节点 redis.confreplicaof 192.168.1.10 6379 masterauth MasterPass主节点也顺便配masterauth的好处是如果未来主从切换老主变成了新从它还能继续用这个密码认证新主减少切换时的配置断层。这算是我在生产环境总结出来的一个小技巧。4.2 Sentinel 的 auth-pass 配置如果你用了 Redis Sentinel 做高可用那么认证配置还要延伸到哨兵这边。Sentinel 本质上是一个特殊的 Redis 客户端它需要监控主从节点的状态也可能会在故障转移时执行SLAVEOF等命令。所以在哨兵的配置文件中需要给每个主节点指定对应的密码sentinel monitor mymaster 192.168.1.10 6379 2 sentinel auth-pass mymaster MasterPass这里的mymaster是主节点别名MasterPass是主从认证用的密码。如果主从节点密码不一致也会导致哨兵无法正常判断odown和sdown故障转移失败是必然的。实际上我见过一个典型案例哨兵本身没有配置auth-pass结果主库故障后哨兵自以为执行了切换但从库一直认证不上新主库业务侧时断时连。排查日志才发现哨兵压根没有拿到主库的认证权限整个故障转移流程卡在认证步骤。所以分布式环境下密码不只是“客户端连接时输入一下”的事它是每个协同节点都需要共享的认证密钥。4.3 集群多节点密码设置雷区Redis Cluster 场景下配置会更加麻烦一些。官方建议每个节点的requirepass和masterauth都保持一致而且所有节点的密码必须相同。为什么因为集群内部节点之间需要互相通信gossip 消息、槽迁移、主从选举都会涉及跨节点连接。如果 A 节点密码是pass1B 节点密码是pass2A 节点向 B 节点发内部请求时认证直接失败整个集群的稳定性会迅速崩溃。具体到操作如果你用redis-cli --cluster create创建集群建立连接时就要带上统一的-a参数比如redis-cli -a ClusterPass --cluster create \ 192.168.1.10:6379 192.168.1.11:6379 192.168.1.12:6379 \ 192.168.1.13:6379 192.168.1.14:6379 192.168.1.15:6379 \ --cluster-replicas 1每个节点在创建集群之前都应该先把requirepass和masterauth写好。否则集群创建时或扩容时会出现认证失败提示连接目标节点超时。这里还要提醒一个隐患即使所有节点密码一样如果中间改过一次密码必须把每个节点的配置都同步更新。我用CONFIG SET依次改完所有节点后要再执行CONFIG REWRITE全部持久化并且重启后观察集群状态是否 OK。不要只改主节点从节点和后续新加节点全都要同步。4.4 和分布式锁面试题结合的常见追问Redis 分布式锁是另一个高频面试点。有些面试官会把密码设置和安全问题串起来问“如果你的 Redis 没有设置密码部署在公网上用它做分布式锁安全吗”这不是在问锁的算法而是在问安全边界。没有认证就意味着任何人都能往你的 Redis 里写SET key value NX EX 10可以把你的锁直接覆盖掉也可以把缓存数据全部清空。所以分布式锁在生产环境成立的前提是Redis 本身是可信、可控、有认证的。我之前还遇到过候选人主动提到SET分布式锁命令在认证前后有区别吗答案是没有区别认证与否只决定“你能不能执行命令”不决定“命令本身会不会发生竞争”。锁的原子性和安全性靠的是SET NX EX和 Lua 脚本密码只是访问控制层两者是不同维度的事情。如果能把这个逻辑理清楚面试官一般会认为你对 Redis 安全体系的理解是连贯的而不是背了一堆孤立考点。5. 进阶安全认知ACL 权限模型与生产加固5.1 Redis 6 的 ACL 怎么理解从 Redis 6 开始密码体系不再只是requirepass一个开关而是引入了基于用户的 ACLAccess Control List。简单理解requirepass相当于把整个 Redis 的钥匙交给所有人拿到钥匙的人能执行所有命令ACL 则更像是公司门禁卡不同用户拿不同卡片有的只能进一层有的能进全部楼层。ACL 的常用命令大概就这些查看所有用户ACL LIST创建一个只读业务用户密码为readonly_pass只允许访问cache:*前缀的 keyACL SETUSER readonly_user on readonly_pass ~cache:* read给默认用户设置密码或禁用默认用户ACL SETUSER default on default_pass ACL SETUSER default off这里和面试强相关的点是CONFIG SET requirepass xxx本质上是在设置default这个用户的密码。如果你通过ACL SETUSER default on newpass修改了 default 用户密码那么原来CONFIG SET requirepass的效果会被覆盖或者同步变更。换个说法requirepass只是 ACL 模型里 default 用户的一个快捷配置入口。我记得实际踩过一个坑某次我用ACL SETUSER default off禁用了默认用户然后用另一个管理员用户连 Redis。结果哨兵和从库的masterauth还在用旧的 default 密码认证导致一夜间主从、哨兵全部脑裂。后来我统一把管理员用户和默认用户分开哨兵用独立的sentinel-user连接才彻底避免类似问题。5.2 实战建议不要再用超级用户跑业务如果你的 Redis 是企业里面向多个业务方使用的公共组件我强烈建议不要只设一个requirepass而是给不同业务创建不同用户和权限。比如订单服务只能用order:*前缀的 key不允许FLUSHALL搜索服务只能读search:*的缓存不允许修改配置。这样就算某个业务的密码泄露影响范围也被限制在它自己的业务下。ACL 创建用户后客户端连接方式从AUTH password变成用户名加密码redis-cli --user order_user --pass order_pass或者交互式AUTH order_user order_pass如果你还在用老式客户端不支持 Redis 6 的 ACL 认证那需要确认一下版本。Redis 7 已经出了好几年支持 ACL 的客户端早就普及了面试里谈到这块会显得你对新技术演进有跟进。5.3 我建议的生产密码策略从配置管理到最小权限最后把生产环境的密码管理经验汇总一下。不要指望一个requirepass能解决所有安全问题真正的安全体系应该是分层叠加的。第一层是网络隔离。Redis 监听端口一定要用防火墙或安全组限制来源只允许应用服务器、运维跳板机的 IP 访问。密码只是第二道防线不是第一道。第二层是密码本身。使用足够长的随机字符串至少 20 位以上并定期轮换。轮换时建议先改从库的masterauth再逐步切换主从角色最后更新业务连接串避免一次性改完导致大面积不可用。这部分细节在不同公司可能不太一样但大方向是“先让新密码在部分节点生效验证稳定后再全量推广”。第三层是配置管理。不要把明文密码直接提交到 Git。可以用配置中心、环境变量或密钥管理服务来动态注入 redis 配置密码只在运行态临时生成。容器的部署方式里redis 启动命令从环境变量读取密码就是很常见的做法。第四层是操作审计。生产 Redis 建议开启CONFIG SET notify-keyspace-events做 key 事件通知或者通过访问日志审计可疑操作。但事件通知不是安全审计替代品它更多是为了业务需要。真正严格的审计一般靠客户端层面的记录或者 Redis Enterprise 这类商业版功能。开源版做不了太细的审计这也是很多公司在生产环境选择托管版 Redis 的原因之一。如果你问我在实际项目里最值得记住的一条规则我会说Redis 的密码设置永远不是“加一行配置”就结束的它需要联动主从、哨兵、客户端、运维工具和权限模型一起设计。面试也好生产也好把这个链路捋顺了Redis 安全相关的题目基本不会再出错。另外我最后再分享一个排查技巧当你怀疑密码配置有问题时优先查看 Redis 日志日志里会直接打印AUTH username failed或NOAUTH之类的关键行通常能帮你迅速定位是哪一层认证出了问题比一台台机器试快得多。
返回列表